Skip to content

Add log export for audit logs and SCIM events#922

Open
gearnode wants to merge 2 commits intomainfrom
gearnode/scm-log-export-job
Open

Add log export for audit logs and SCIM events#922
gearnode wants to merge 2 commits intomainfrom
gearnode/scm-log-export-job

Conversation

@gearnode
Copy link
Copy Markdown
Contributor

@gearnode gearnode commented Mar 25, 2026

Summary

  • Add async log export system for audit log entries and SCIM events, processed by a background worker and delivered via email as JSONL files
  • Expose the feature across all three API surfaces: GraphQL (console + connect), MCP tools, and CLI commands (probod audit-log export, probod scim-event export)
  • Add cursor-based streaming (ForEach* with DECLARE CURSOR) for memory-efficient iteration over large datasets
  • Add export button with date range dialog to the audit log settings page in the console UI
  • Include IAM authorization policies, database migration, email template, and end-to-end tests

Test plan

  • Run make test-e2e to validate audit log and SCIM event export e2e tests
  • Verify the export button appears on the audit log settings page for authorized users
  • Trigger an export and confirm the background worker processes it and sends the email

Summary by cubic

Adds async export for audit logs and SCIM events, processed by a background worker and emailed as a JSONL download link. Exposed in Console, GraphQL, MCP tools, and CLI.

  • New Features

    • Background worker streams large exports with database cursors and recovers stale jobs; emails a 24h download link.
    • Console: Export button and date range dialog on Audit Log settings (shown only if authorized).
    • API: GraphQL mutations in console/connect to request exports; MCP tools added; CLI commands prb audit-log export and prb scim-event export.
    • Email: New "Your log export is ready" templates and presenter.
    • RBAC: New actions iam:audit-log:export and iam:scim-event:export; owners/admins allowed, viewers blocked; e2e tests added.
    • Fixes: Close pipe reader after S3 upload to avoid deadlock; add partial index on pending exports for faster worker polling; export dialog uses UTC timestamps, includes the full “To” day, and blocks invalid ranges.
  • Migration

    • Apply DB migration creating the log_exports table and partial index on pending rows.
    • Deploy with the IAM log export worker (auto-starts); ensure file storage bucket and base URL are configured.

Written for commit 6143986. Summary will update on new commits.

Introduce a background worker-based log export system that allows
users to export audit log entries and SCIM events as JSONL files.
Exports are processed asynchronously and delivered via email with
a download link.

The feature spans all three API surfaces (GraphQL, MCP, CLI),
includes cursor-based streaming for memory-efficient large exports,
and adds IAM policies, e2e tests, and email templates.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 issues found across 30 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="pkg/coredata/migrations/20260325T120000Z.sql">

<violation number="1" location="pkg/coredata/migrations/20260325T120000Z.sql:16">
P2: Add an index for the pending-job lookup path (`status` + `created_at`) to avoid repeated full scans in `FOR UPDATE SKIP LOCKED` polling.</violation>
</file>

<file name="pkg/iam/log_export_worker.go">

<violation number="1" location="pkg/iam/log_export_worker.go:212">
P1: Deadlock if S3 upload fails: `pr` is never closed after `PutFile` returns, so `streamJSONL` blocks forever on the next write to `pw`. Close `pr` with the upload error so the writer side gets unblocked.</violation>
</file>

<file name="apps/console/src/pages/iam/organizations/settings/AuditLogSettingsPage.tsx">

<violation number="1" location="apps/console/src/pages/iam/organizations/settings/AuditLogSettingsPage.tsx:201">
P2: The selected “To” date is converted to midnight and sent as an exclusive upper bound, which drops all log entries from that day.</violation>

<violation number="2" location="apps/console/src/pages/iam/organizations/settings/AuditLogSettingsPage.tsx:271">
P2: The dialog allows submitting a date range where From is after To, which the backend always rejects.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Close the pipe reader after S3 upload completes to prevent a
deadlock when PutFile fails. Add a partial index on pending log
exports to avoid full table scans during worker polling. Fix the
export dialog to use explicit UTC timestamps and include the full
"To" day, and disable submit when From is after To.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
Copy link
Copy Markdown
Contributor Author

@gearnode gearnode left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review complete — 1 issue found.

);

CREATE INDEX idx_log_exports_pending ON log_exports (status, created_at)
WHERE status = 'PENDING';
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Speculative index on a new table

This partial index is added on a brand-new table with no observed production query latency to justify it. Per contrib/claude/coredata.md:

No indexes by default. Only add indexes when justified by observed query latency in production environments. Do not speculatively create indexes on new tables or columns. This rule does not apply to indexes that enforce constraints, such as unique indexes.

This is a non-unique partial index for worker polling, so the constraint exception does not apply. Consider removing it and adding it later if query latency warrants it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant