Skip to content

fix(audit): scope enterprise audit logs by org#1291

Open
Nav-Prak wants to merge 3 commits into
BlazeUp-AI:mainfrom
Nav-Prak:pr/audit2-audit-org-scope
Open

fix(audit): scope enterprise audit logs by org#1291
Nav-Prak wants to merge 3 commits into
BlazeUp-AI:mainfrom
Nav-Prak:pr/audit2-audit-org-scope

Conversation

@Nav-Prak
Copy link
Copy Markdown
Contributor

Purpose / Description

Scope enterprise audit-log reads to the caller's organization so a tenant admin cannot list or export another organization's audit trail.

This is part of the AUDIT2 tenant-scoping work and is split out from the closed broader tenant-scope PR #1184 to keep the audit change independently reviewable.

Fixes

Approach

This change stamps audit rows with an org_id and filters audit-log list/export queries by the current admin's org.

  • Adds org_id to audit event flow where needed.
  • Resolves the actor's organization when buffering audit rows.
  • Adds org filtering to enterprise audit-log list and export routes.
  • Preserves org-less/local-mode admin behavior by omitting the org filter when the caller has no org.
  • Handles SCIM user deletion specially by capturing org_id before deleting the user, since the row cannot be resolved after deletion.

How Has This Been Tested?

Targeted audit tenant-scope tests:

cd observal-server && uv run --with pytest --with pytest-asyncio --with pyyaml \
  --with typer --with rich --with hypothesis --with pyarrow \
  pytest ../tests/test_tenant_scope_audit.py ../tests/test_audit_logging.py -q

Result: audit tenant-scope tests passed, including the SCIM user-deletion org preservation case.

Lint/format:

uv run --with ruff==0.15.10 ruff check \
  ee/observal_server/routes/audit.py \
  ee/observal_server/routes/scim.py \
  ee/observal_server/services/audit.py \
  observal-server/services/events.py \
  tests/test_tenant_scope_audit.py \
  tests/test_audit_logging.py

uv run --with ruff==0.15.10 ruff format --check \
  ee/observal_server/routes/audit.py \
  ee/observal_server/routes/scim.py \
  ee/observal_server/services/audit.py \
  observal-server/services/events.py \
  tests/test_tenant_scope_audit.py \
  tests/test_audit_logging.py

Also re-ran adjacent audit/events/HIPAA/SCIM suites as part of split verification; no regressions were found.

Checklist

  • You have a descriptive commit message with a short title (first line, max 50 chars).
  • You have commented your code, particularly in hard-to-understand areas
  • You have performed a self-review of your own code
  • UI changes: not applicable; no UI changes in this PR

Nav-Prak added 2 commits May 30, 2026 12:54
Stamp every audit row with the actor's organization (resolved from the
database and cached per actor) and constrain the audit-log list and export
queries to the caller's org, so a tenant admin cannot read another
organization's audit trail.

- Add org_id to the AuditableAction event and thread it through _make_row;
  resolve it from the actor in _buffer_row when unset, so all handlers get
  attributed without per-call-site changes.
- Add an org_id filter to list_audit_logs and export_audit_logs.
- Set org_id=None on mocked users in existing audit-log tests so they keep
  exercising the unscoped path unchanged.
- Add tenant-scope regression tests for list/export scoping, row
  attribution, and resolver caching.

Part of AUDIT2 tenant-scoping, split out of BlazeUp-AI#1184.
SCIM delete_user emits UserDeleted after the user row is deleted, so the
_buffer_row fallback that resolves org_id from the actor finds nothing and
the audit row lands with org_id="" -- hidden from the tenant's admins by the
org-scoped query.

Carry org_id on the UserDeleted event, captured in delete_user before the
delete, and stamp it on the audit row (the handler now passes
org_id=event.org_id, which short-circuits the actor lookup).

Adds a regression test driving UserDeleted through the event bus and
asserting the row keeps the event's org_id without a database lookup.

Part of AUDIT2 tenant-scoping, split out of BlazeUp-AI#1184.
@github-actions github-actions Bot added enterprise Enterprise-grade readiness server Pull request touches server code tests Pull request adds or modifies tests new contributor Pull request from a first-time contributor labels May 30, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 30, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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

Labels

enterprise Enterprise-grade readiness new contributor Pull request from a first-time contributor server Pull request touches server code tests Pull request adds or modifies tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant