Skip to content

[Feat] Tenant-scoped audit trail for security-relevant events #782

Description

@haofeif

Part of #777. After 3.0.

Builds on tenant/resource classification (#778), stable identity and actor/owner context (#774), and membership/administrative actions (#779). Later sharing (#780) and service accounts (#783) add event types and actors; they must not require inventing a second audit identity model.

In plain terms

When several people share one CAO, "who did that?" stops being a rhetorical question. Who removed that member? Who shared that workflow with the whole organisation? Who deleted that session?

CAO does have an audit log today, and it's a careful piece of work — append-only, permission-checked, protected against log injection. But it was built for one purpose and doesn't stretch to this one.

Why today's audit log isn't enough

Three specific problems, none of which are criticisms of what it does well:

It covers the memory/learning subsystem, not the whole application. It lives at logs/memory/YYYY-MM-DD.md; alongside memory events, successful instruction promotion calls the audit writer with a profile-change event (services/promotion_service.py:177-205, :243-255), subject to that writer's feature gate and best-effort behavior. Sign-in, membership administration and session deletion do not thereby acquire a general audit trail.

It switches itself off. If memory.enabled is false, the whole thing short-circuits at the top. The code describes this honestly as a "documented forensic gap". That's a reasonable trade for a local tool. It isn't for a shared one, where the audit trail shouldn't depend on an unrelated feature being turned on.

It has no tenant-scoped access model. Events for all users share the daily files, so those files cannot simply be exposed to an administrator who should see only their own tenant. If stored on a pod's temporary volume, they are lost when that pod is removed.

What this delivers

A tenant-scoped audit trail covering delivered security-relevant operations — sign-in and failure, role changes, member add and remove, deletions, and administrative intervention in another person's work. Sharing and service-account features must emit through the same audit interface when they land; the audit foundation does not wait for those later features to exist.

Attribution must describe who acted, not merely who owns the affected resource. Preserve the stable acting principal, delegated execution context where relevant, target resource/owner, operation and actual outcome. A tenant administrator stopping another person's agent is not an action performed by that owner; later service-account actions are not automatically actions by their human creator.

Some failures have no authenticated actor or established tenant. Record known facts and explicitly unknown identity where appropriate. Use trusted server context for an established tenant; do not turn a claimed tenant, email address or invalid token into authoritative attribution. Unattributed/platform events remain operator-scoped and are not exposed through every tenant's audit reader.

Readable by a tenant's administrator, for their own tenant only. The audit trail is itself tenant-isolated data.

Store the new audit trail in the central database on durable storage, with tenant-scoped reads. Durability comes from the storage and retention policy, not from choosing SQL over files: a SQLite database on a disposable volume is lost too, and a file on a persistent volume can survive pod replacement.

Preserve the memory audit log's purpose and format. This sits alongside it rather than replacing it, but does not exempt those files from #774/#778's ownership and access rules. "Unchanged" must not mean exposing an installation-wide file to a tenant or member who may read only their own data.

Define retention, bounded event fields and append-failure behavior explicitly. Exclude secrets and raw authentication material; distinguish an attempted operation from a committed outcome, and make recording failures observable rather than treating a best-effort write as a durable audit guarantee.

A note on sources

AWS's detective-controls page says there are no security practices unique to SaaS. That does not mean AWS offers no relevant guidance: its tenant-aware operations guidance calls for insight into individual tenants' activity. Use that alongside the OWASP Logging Cheat Sheet, which distinguishes known identity, affected objects and outcomes and warns against logging secrets.

Acceptance criteria

  • Security-relevant events record the known actor, operation, affected resource/owner, time and outcome, with trusted tenant attribution when available.
  • Pre-authentication failures and platform events with no established tenant are retained under operator-only access, without fabricated identity or cross-tenant disclosure.
  • Recording does not depend on whether the memory feature is enabled.
  • An administrator can read their own tenant's trail and cannot read another's.
  • Records survive a restart.
  • Entries cannot be silently altered or removed through the application.
  • Memory/learning audit behavior is preserved while respecting the ownership/access boundary; a tenant audit reader cannot expose another tenant's memory log.
  • Administrator intervention records the actor separately from the owner, and existing system/delegated-runtime actors retain their identities. The interface supports later service-account actors without requiring [Feat] Service accounts and an explicit API version #783 to land first; [Feat] Service accounts and an explicit API version #783 owns their integration coverage.
  • Identity/resource deletion does not silently rewrite historical attribution.
  • Retention, field bounds/redaction and recording-failure behavior are documented and exercised; raw credentials are never required as audit evidence.

Evidence

Claim Where
Audit log serves memory/learning and is file-based services/audit_log.py:1-30; promotion calls the writer at services/promotion_service.py:205, :243-255
Disabling memory disables auditing services/audit_log.py"documented forensic gap"
Tenant-aware operations and application audit guidance AWS SaaS Lens tenant-aware operations; OWASP Logging Cheat Sheet

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions