b8217dce8a
docker / test (pull_request) Successful in 24s
lint / lint (pull_request) Successful in 37s
lint / lint (push) Successful in 1m26s
test / test (push) Successful in 1m40s
test / test (pull_request) Successful in 34s
docker / lint (pull_request) Successful in 1m59s
docker / docker-test (pull_request) Successful in 14s
docker / docker-publish (pull_request) Has been skipped
- Enforce 32-char minimum on OAUTH_STATE_SECRET at startup (config.py) - Write DCR client registry with owner-only (0o600) permissions before atomic replace - Flip policy.yaml default write action from allow → deny - Add CLAUDE.md with architecture, commands, and AGENTS.md contract summary - Add .pre-commit-config.yaml mirroring `make lint` checks - Update .gitignore: add .venv, .claude, .mypy_cache, .ruff_cache, .coverage.* - Extend docs: audit log rotation guidance, OAUTH_STATE_SECRET and DCR_STORAGE_PATH notes - Tests: short-secret rejection, 32-char acceptance, POSIX permission check for DCR store Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
54 lines
1.2 KiB
Markdown
54 lines
1.2 KiB
Markdown
# Audit Logging
|
|
|
|
## Design
|
|
|
|
Audit logs are append-only JSON lines with hash chaining:
|
|
- `prev_hash`: previous entry hash.
|
|
- `entry_hash`: hash of current entry payload + previous hash.
|
|
|
|
This makes tampering detectable.
|
|
|
|
## Event Types
|
|
|
|
- `tool_invocation`
|
|
- `access_denied`
|
|
- `security_event`
|
|
|
|
Each event includes timestamps and correlation context.
|
|
|
|
## Integrity Validation
|
|
|
|
Use:
|
|
|
|
```bash
|
|
python3 scripts/validate_audit_log.py --path /var/log/aegis-mcp/audit.log
|
|
```
|
|
|
|
Exit code `0` indicates valid chain, non-zero indicates tamper/corruption.
|
|
|
|
## Operational Expectations
|
|
|
|
- Persist audit logs to durable storage.
|
|
- Protect write permissions (service account only).
|
|
- Validate integrity during incident response and release checks.
|
|
|
|
## Rotation
|
|
|
|
The server appends to a single audit file and does not rotate it in process — rotating
|
|
mid-stream would break the `prev_hash`/`entry_hash` chain. Manage growth externally with
|
|
`logrotate` using `copytruncate` so the open file handle keeps appending:
|
|
|
|
```
|
|
/var/log/aegis-mcp/audit.log {
|
|
weekly
|
|
rotate 12
|
|
compress
|
|
missingok
|
|
notifempty
|
|
copytruncate
|
|
}
|
|
```
|
|
|
|
Run `scripts/validate_audit_log.py` against each rotated segment to confirm the chain
|
|
remains intact across rotations before archiving.
|