Skip to content

feat(server): append-only integration audit log #1218

@FelixTJDietrich

Description

@FelixTJDietrich

Part of #1197.

What ships

An integration_audit_log Postgres table that records install / uninstall / config-change / credential-rotation events on every workspace integration. Append-only; no updates, no deletes outside the privacy + retention epic's purge. Each row carries the operator id, the workspace id, the integration kind, the action, a structured details_jsonb, and the timestamp. Writes happen in the same transaction as the originating action.

Why

A workspace admin asking "who rotated my GitHub credential last week?" needs an answer; a TUM DPO asking "show me every credential change in this workspace for the past 90 days" needs an answer. Without an explicit audit log, the answers live in application logs that rotate out, and the privacy + retention epic's purge has no anchor.

Acceptance criteria

  • Liquibase changeset creates integration_audit_log with columns: id, workspace_id, integration_kind, action, operator_user_id, details_jsonb, occurred_at; indexed on (workspace_id, occurred_at) and (integration_kind, occurred_at)
  • Every install / uninstall / config-change / credential-rotation action writes one row in the same transaction; an integration test verifies transaction rollback discards the audit row
  • An admin UI surface (in the privacy admin UI section) renders a paginated audit log for the workspace
  • A purge contributor registered by #1211 removes rows for the workspace on workspace deletion; per-action retention is governed by the per-integration retention window from #1211
  • An ArchUnit rule rejects writes to integration_audit_log outside the dedicated audit-log writer service (no direct repository writes from feature code)

Tests to write

  • Per-action test: install, uninstall, config-change, credential-rotation each produce exactly one row with the right shape.
  • Transaction rollback test.
  • Admin UI render test (component test against seeded data).
  • ArchUnit positive fixture for the write-restriction rule.

Implementation notes

  • The action set is a fixed enum (INSTALL, UNINSTALL, CONFIG_CHANGE, CREDENTIAL_ROTATION); extension requires schema work (intentional friction).
  • details_jsonb carries action-specific context (rotated credential's new last-N-bytes hash, config diff summary, etc.); the shape is documented per action in docs/contributor/integrations/audit-log.md.
  • operator_user_id is the authenticated user who triggered the action; system-initiated rotations record a sentinel system-user id.
  • Reads are unauthenticated within the application but role-gated by the controller surface (workspace admin only).

Dependencies

Depends on #1216. Cooperates with #1213.

Metadata

Metadata

Assignees

No one assigned

    Labels

    application-serverSpring Boot server: APIs, business logic, databasefeatureNew feature or enhancementpriority:highAddress this sprint - Significant impactsecurityAuthentication, authorization, vulnerability fixes

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions