audit trail system — SEC-001 phases 2b/3/4/5 (#20)#371
Conversation
78ef669 to
105868a
Compare
Reflects that Phases 1/2a/2b/3/4/5 all shipped via PR #371. Expands the Delivery sections to cover Phase 2b (auth, sharing, credentials, settings, rename, request-ID middleware), Phase 3 (MCP tool call audit via transparent wrapper), Phase 4 (hash chain + verify + export), and Phase 5 (remaining spec-declared actions: execution, authorization, configuration, mcp_operation key ops, git_operation, system, credentials.oauth_complete). Also annotates which spec actions are intentionally not wired because no endpoint exists (recreate, logout, token_refresh, credentials.create/delete/ reload, git.commit). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reflects that Phases 1/2a/2b/3/4/5 all shipped via PR #371. Expands the Delivery sections to cover Phase 2b (auth, sharing, credentials, settings, rename, request-ID middleware), Phase 3 (MCP tool call audit via transparent wrapper), Phase 4 (hash chain + verify + export), and Phase 5 (remaining spec-declared actions: execution, authorization, configuration, mcp_operation key ops, git_operation, system, credentials.oauth_complete). Also annotates which spec actions are intentionally not wired because no endpoint exists (recreate, logout, token_refresh, credentials.create/delete/ reload, git.commit). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
a3388ab to
8ebb8c7
Compare
|
Post-rebase status (2026-04-20):
Remaining gaps (per PR body):
Propose: merge as-is, open follow-up for UI check + natural-trigger verification. |
Reflects that Phases 1/2a/2b/3/4/5 all shipped via PR #371. Expands the Delivery sections to cover Phase 2b (auth, sharing, credentials, settings, rename, request-ID middleware), Phase 3 (MCP tool call audit via transparent wrapper), Phase 4 (hash chain + verify + export), and Phase 5 (remaining spec-declared actions: execution, authorization, configuration, mcp_operation key ops, git_operation, system, credentials.oauth_complete). Also annotates which spec actions are intentionally not wired because no endpoint exists (recreate, logout, token_refresh, credentials.create/delete/ reload, git.commit). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
8ebb8c7 to
603b74d
Compare
PR Validation Report —
|
| Category | Status | Notes |
|---|---|---|
| Commit Messages | ✅ | Conventional (feat/docs/wip), detailed bodies. Phase 5 uses wip: deliberately. |
| GitHub Issue | ✅ | #20 referenced; labels intact (priority-p1, type-feature). |
| Requirements | ✅ | docs/memory/requirements.md — SEC-001 expanded across all 5 phases. |
| Architecture | docs/memory/architecture.md endpoint table lists only Phase 1 endpoints — missing /export, /verify, /hash-chain/enable, /api/internal/audit. |
|
| Feature Flow | ✅ | feature-flows/audit-trail.md updated (+168 / −19). |
| Security Check | ✅ | No secrets, keys, real emails, IPs, env files, or credential files. |
| Tests | 51 unit tests pass; no unit coverage added for Phase 2b/5 call sites (acknowledged). | |
| Manual Test Plan | ✅ | 18/19 acceptance checks passed live; hash-chain regression reproduced and fixed. |
Security Checklist
- ✅ No secrets/keys/emails/IPs in diff
- ✅ Credential router logs only file path keys, never values
- ✅ Auth audit records
usernameonly on failure; success targetsuser.usernameviatarget_id - ✅ MCP internal audit endpoint gated by
verify_internal_secret(C-003,hmac.compare_digest) - ✅
INTERNAL_API_SECRETalready in.env.example:22
Issues Found
Critical (Block Merge): none.
Warnings (Review Required):
- Author self-flagged WIP. PR description's "Why WIP" lists three open items:
- 3 integrations wired but not live-tested:
git_operation.sync/pull/init,execution.schedule_triggered,credentials.oauth_complete - No unit tests added for new audit call sites (only service layer has 51 tests)
- Frontend audit log page visual check pending
- 3 integrations wired but not live-tested:
architecture.mdendpoint table stale. §Platform Audit Log lists 3 endpoints; 4 new ones (/export,/verify,/hash-chain/enable,/api/internal/audit) are inrequirements.mdbut not in arch. Keeps invariants Feature/vector log retention #3/feat: SMARTS trading pipeline with Telegram notifications and Miro visualization #13 in sync.- Phase 5 commit uses
wip:prefix (33d12c0) — cosmetic if squash-merged, but preserved in a merge commit.
Suggestions (Optional):
src/mcp-server/src/server.ts:189–220—createXTools()is invoked twice (once for registration, once for counting). Capture once into locals.- Add a unit test for the
_compute_hashstring-vs-dictdetailsround-trip — that's the exact Phase 5 bug; a test would prevent regression. PlatformAuditService.enable_hash_chainseed (services/platform_audit_service.py:190–199) swallows all exceptions without logging — considerlogger.warning.
Recommendation
REQUEST CHANGES (light) / NEEDS DISCUSSION
Implementation quality is high — clean service boundaries, disciplined call sites (credential audit logs paths not values, request-ID middleware wires request.state.request_id everywhere, fire-and-forget semantics preserved, hash-chain bug caught and fixed with clear reproduction note). Security surface is clean.
The only reason not to land this as-is is that the author explicitly marked it WIP with three pending items they identified themselves.
Suggested path to merge:
- Add the 4 new endpoints to
docs/memory/architecture.md§Platform Audit Log table - Either (a) live-test the 3 uncovered integrations and tick them in the PR description, or (b) open a follow-up issue and drop the WIP flag
- Add a minimal unit test for the hash-chain round-trip (prevents regression of the bug this PR fixed)
- Drop
wip:prefix from Phase 5 commit if merge-committing (no-op if squashing)
Nice-to-have:
- Deduplicate
createXTools()calls insrc/mcp-server/src/server.ts - Log a warning on hash-chain seed failure
🤖 Generated via /validate-pr with Claude Code
…ls, settings, rename (#20) Add audit logging to remaining backend routers: - Authentication: login_success/login_failed for admin + email auth - Authorization: share, unshare, access request approve/reject - Credentials: inject, export, import (file paths only, never values) - Configuration: API key and generic setting updates/deletes - Agent rename with old/new name tracking - Request-ID middleware for cross-request correlation 44 unit tests passing (15 new Phase 2b + 29 existing). Refs #20 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…se 4) (#20) Phase 3 — MCP server integration: - audit.ts: withAudit() wrapper + logToolCall() fire-and-forget POST - server.ts: addAllTools() wraps all 66+ tools transparently at registration - internal.py: POST /api/internal/audit endpoint (C-003 shared-secret auth) - docker-compose.yml: INTERNAL_API_SECRET env var added to mcp-server Phase 4 — hash chain + export: - PlatformAuditService: enable_hash_chain(), verify_chain() methods - audit_log.py: POST /verify, POST /hash-chain/enable, GET /export endpoints - Export supports JSON and CSV (streaming download) 51 unit tests passing (7 new Phase 3+4). Refs #20 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…#20) Phase 5 extends platform audit to cover the remaining AuditEventType actions declared in docs/requirements/AUDIT_TRAIL_ARCHITECTURE.md. Also fixes a hash-chain verify bug found during Phase 4 manual testing. Actions added: - execution: chat_started (routers/chat.py), task_triggered (routers/schedules.py trigger endpoint), schedule_triggered (routers/internal.py execute-task for triggered_by="schedule") - authorization: permission_grant, permission_revoke, permissions_set (routers/agent_files.py) - configuration: autonomy_toggle, resource_limits (routers/agent_config.py) - mcp_operation: key_create, key_revoke, key_delete (routers/mcp_keys.py) - git_operation: sync, pull, init (routers/git.py — added current_user dependency where missing) - system: startup, shutdown (main.py lifespan), emergency_stop (routers/ops.py) - credentials: oauth_complete (routers/slack.py OAuth callback) Hash chain fix (services/platform_audit_service.py): - _compute_hash now normalizes `details` to dict before serializing. Write-time stored details as JSON string via json.dumps; read-time (_row_to_dict) deserialized back to dict. Re-hashing the two forms produced different SHA-256 inputs, so verify_chain returned valid=false for every entry with non-null details. - Added a manual test plan at docs/testing/audit-trail-manual-test-plan.md covering all 19 acceptance checks across Phases 2b/3/4/5. Spec actions intentionally NOT wired (no endpoint exists in Trinity): - agent_lifecycle.recreate, authentication.logout, authentication.token_refresh, credentials.create/delete/reload (CRED-002 replaced with inject/export/import, already audited), git_operation.commit (folded into sync endpoint). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reflects that Phases 1/2a/2b/3/4/5 all shipped via PR #371. Expands the Delivery sections to cover Phase 2b (auth, sharing, credentials, settings, rename, request-ID middleware), Phase 3 (MCP tool call audit via transparent wrapper), Phase 4 (hash chain + verify + export), and Phase 5 (remaining spec-declared actions: execution, authorization, configuration, mcp_operation key ops, git_operation, system, credentials.oauth_complete). Also annotates which spec actions are intentionally not wired because no endpoint exists (recreate, logout, token_refresh, credentials.create/delete/ reload, git.commit). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- architecture.md: document 4 new audit endpoints (export, verify, hash-chain/enable, internal/audit) - platform_audit_service: log warning on hash-chain seed failure instead of swallowing silently - mcp-server/server.ts: dedupe createXTools() calls — build groups once, then register + count - tests/test_audit_log_unit: add hash-chain details round-trip regression tests (string-vs-dict equivalence + end-to-end verify) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
603b74d to
681956f
Compare
PR Validation Report —
|
| Category | Status | Notes |
|---|---|---|
| Commit Messages | ✅ | Conventional (feat/docs/wip/fix), detailed bodies. Phase 5 = wip:. |
| GitHub Issue | ✅ | #20 open, labels priority-p1 + type-feature. Closed on merge. |
| Requirements | ✅ | requirements.md §20.1 SEC-001 expanded across phases. |
| Architecture | ✅ | architecture.md §Platform Audit Log lists all 7 endpoints (prior gap fixed in 681956f). |
| Feature Flow | ✅ | feature-flows/audit-trail.md (+168/−19), all required sections present, phase tables filled. |
| Security Check | ✅ | No keys / real emails / public IPs / .env / hardcoded secrets / credential files. |
| Code Quality | ✅ | Focused scope, audit wrapper centralizes MCP side, createXTools() dedup landed. |
| Tests | 53 unit tests pass (incl. 2 new hash-chain regression tests). Route-level integration still via manual plan. | |
| Manual Test Plan | ✅ | 19/19 acceptance checks passed live; hash-chain regression reproduced + fixed. |
Security Checklist
- ✅ No API keys/tokens in diff
- ✅ No real emails (only
noreply@anthropic.com+@router/@app.middlewaredecorators) - ✅ No public IPs
- ✅ No
.env/ credential files staged - ✅ Credential router logs file-path keys, never values
- ✅ Auth failure audit records
usernameonly; success targets resolved user - ✅
/api/internal/auditgated byverify_internal_secret(C-003,hmac.compare_digest)
Issues Found
Critical: none.
Warnings:
- Author-flagged WIP remnants — three wired integrations (
git_operation.sync/pull/init,execution.schedule_triggered,credentials.oauth_complete) still lack live coverage. Low risk; natural-trigger only. - Frontend audit log page visual check pending (unchanged since last report).
Suggestions: none remaining — prior validation's 3 non-blockers all addressed in 681956f (endpoint table, createXTools() dedup, seed-failure warning, hash-chain regression test).
Recommendation
APPROVE (with WIP-prefix caveat)
Rebase clean onto main (67fbe74). All three non-blocking suggestions from the prior /validate-pr run are resolved in 681956f. Mergeable=CLEAN, 53/53 unit tests pass, security surface clean, docs + architecture + feature flow all aligned. Only open items are author-acknowledged WIP items that are low-risk follow-ups.
Suggested path to merge:
- Squash-merge (auto-drops the
wip:Phase 5 commit prefix), OR reword tofeat:if preserving history. - Open follow-up issue for natural-trigger verification + frontend visual check, then drop WIP tag.
🤖 Generated via /validate-pr with Claude Code
|
🤖 PR Reviewer (Trinity) PR Review — audit trail system — SEC-001 phases 2b/3/4/5 (#20)Overall: Large but well-structured multi-phase PR. The hash-chain fix is legitimate and the audit-never-blocks-caller invariant is correctly maintained throughout. Several items to flag. BugsHash chain still has a serialization fragility: The fix normalizes
SecurityMCP audit endpoint
Credential values: Audit call sites for credentials correctly log only file paths and counts — no values. Good. Missing test coverage (noted as WIP)
ScopeThis PR spans 25 files and 4+ phases, which makes it hard to review atomically. The WIP flag is appropriate. The PR description's "Why WIP" section is honest and appreciated. |
Summary
Complete implementation of the Trinity platform audit trail (SEC-001 / #20) across four phases, landed together on this branch.
docs/requirements/AUDIT_TRAIL_ARCHITECTURE.mdand fixes a hash-chain verify bug.Action coverage vs spec (
AuditEventType)recreatehas no public endpointlogout/token_refresh— no endpoints in Trinitycommitfolded into sync endpointHash chain fix
_compute_hashnormalizesdetailsto dict before serializing. Write-time storeddetailsas a JSON string (json.dumps); read-time (_row_to_dict) deserialized back to a dict. Re-hashing the two forms produced different SHA-256 inputs, soverify_chainreturnedvalid=falsefor every entry with non-nulldetails. Reproduced live (test 13 in the manual plan) and confirmed fixed after the change.API surface
GET /api/audit-log— list + filters (event_type, actor_type, actor_id, target_type/id, source, start/end_time)GET /api/audit-log/{event_id}— single entryGET /api/audit-log/stats— totals + breakdownsGET /api/audit-log/export?format=json|csvPOST /api/audit-log/verify?start_id=&end_id=POST /api/audit-log/hash-chain/enable?enabled=true|falsePOST /api/internal/audit— fire-and-forget write path for MCP serverStorage
audit_logtable in the main SQLite DB, distinct from the Process Engine'saudit_entries(per AUDIT_TRAIL_ARCHITECTURE.md decision). Append-only enforced by SQLite triggers:UPDATEblocked unconditionally,DELETEblocked within a 365-day retention window.Test plan
docs/testing/audit-trail-manual-test-plan.md— 19 acceptance checks across request-ID, auth, sharing, credentials, settings, rename, MCP user/agent/failure scopes, hash chain enable/verify/disable, JSON/CSV export, stats/filters, non-admin 403.valid: true, checked: 3after the fix.login_successaudit entry (only failure path exercised so far).Why WIP
PR marked
wip:because:🤖 Generated with Claude Code