SCIM events store user_name, not identity_id; profile GIDs
in /Users/{id} paths drive LoadExistingByIDs and identity
email lookup instead of batching by user_name.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
Email comes from identity when a profile matches; empty
email only when the event has no profile row to join.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
Wrap encoding/csv with formula-safe cell sanitization and
use it from log export streaming.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
Load SCIM profile emails via Identities in the export
layer, drop the cross-table join, sanitize formula-leading
cells, and fall back to validated userName when profile email
is missing. Drop redundant gid array casts in LoadByIDs.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
Audit exports no longer emit a metadata JSON column. SCIM full
names come only from membership profiles, not request bodies.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
JSONL was awkward in spreadsheets and SIEM imports. Write
tab-separated-friendly CSV with organization name on every row,
resolve audit actors to email or API key name, and enrich SCIM rows
with profile email and display name when available.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>