Reliable multi-tenant auto setup audit capability
AUDIT-WP-0004-T04, closing the workplan. Decision (Bernd): default to redaction, allow rejection per sender. Losing an audit record over one field is worse than storing it masked, but a higher-assurance channel must be able to refuse rather than mask. secret_policy is set per sender identity in AUDIT_CORE_SENDERS and defaults to redact. Detection now covers the whole payload at any depth, including lists, rather than only the top level of data. Under redaction the value is masked and the key is preserved: dropping the key would hide that the sender transmitted the field at all, which is exactly what an operator needs in order to stop it. The stored record carries details.redaction with policy and affected paths, so a reader never has to infer whether what they see is what was sent. Idempotency is unaffected - the payload hash is taken over the original request body, so redaction is deterministic and a resubmission still reconciles as a duplicate. Both outcomes are counted durably by sender, source, action and field path, exposed at GET /v1/secret-findings. Per-path aggregation is the point: the actionable unit is "stop emitting data.auth.token on membership.added", not "there were 47 redactions". Counters survive restart because the fix they drive lives in another service. Contract doc updated to match. Tests 46 -> 50. WP-0004 is finished. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|---|---|---|
| .claude/rules | ||
| .forgejo/workflows | ||
| audit_core | ||
| docs | ||
| registry | ||
| spec | ||
| tests | ||
| workplans | ||
| .custodian-brief.md | ||
| .gitignore | ||
| .repo-classification.yaml | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| Containerfile | ||
| INTENT.md | ||
| LICENSE | ||
| Makefile | ||
| pyproject.toml | ||
| README.md | ||
| SCOPE.md | ||
| WORK-RECORDS.md | ||
Reliable multi-tenant auto setup audit capability
Backend contract
The pluggable backend interface, event schema (audit-core.event.v1alpha1),
retention policy, and migration path from the mock file backend are documented
in docs/audit-backend-contract.md.
Development Mock Backend
The first implementation is intentionally tiny: a replaceable audit interface with a mock file backend.
By default it writes JSONL audit events to:
/tmp/audit-core/audit-YYYYMMDDTHH.jsonl
Files older than 7 days are removed when the backend writes or when cleanup is run explicitly. This backend is for local integration and bootstrap wiring. It is not durable audit custody.
Example:
python3 -m audit_core emit \
--source openbao \
--action openbao.authenticated_readiness_proof \
--resource openbao/openbao-0 \
--outcome success \
--detail file_audit_visible=true \
--detail backend=mock-file
Cleanup:
python3 -m audit_core cleanup
Make targets:
make test
make mock-audit-smoke
make mock-audit-cleanup
Environment:
AUDIT_CORE_MOCK_DIR: override the output directory.AUDIT_CORE_MOCK_RETENTION_DAYS: override the default 7-day cleanup window.