You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Per Sections 7, 5.1, and 17 of the Source of Truth, every decision (approve/deny) must be logged in a tamper-evident audit log with an incremental Merkle tree. The current system has alerts and spend records but lacks the formal audit trail. Additionally, several planned LLM guard features and API endpoints are not yet implemented.
1. Audit Log System (Section 7 — Week 1-2)
Files:src/audit/
AuditEntry struct per Section 18:
structAuditEntry{id:u64,// auto-incrementtimestamp:u64,// unix timestamp (ms)intent_type:String,// "api_call" | "onchain_tx"service:String,// "openai" | "binance" | "0xUniswap..."action:String,// endpoint path or function selectordecision:String,// "approved" | "denied"reason:Option<String>,// null if approved, reason if deniedcost_usd:Option<f64>,// estimated costpolicy_version_hash:H256,// hash of policy at time of decisionintent_hash:H256,// hash of the full intentpermit_hash:Option<H256>,// hash of signed permit (onchain + approved)merkle_root:H256,// tree root AFTER this entry appended}
SQLite audit_log table — indexed on timestamp, service, decision
Log every proxy decision — both approved and denied requests, across all proxy types (OpenAI, Anthropic, Binance, generic, onchain)
Intent hashing — keccak256 hash of the full intent for each entry
Policy version hash — hash of active fishnet.toml at time of decision (from config hot-reload)
2. Incremental Merkle Tree (Section 7.3)
Owner: Yash | Files:src/audit/merkle.rs
Binary Merkle tree with Keccak-256 hash function (tiny-keccak crate)
Append-only — entries are never modified or deleted
Store leaf hashes + intermediate nodes in a separate SQLite table
Merkle root stored in each AuditEntry — root computed after appending the entry
Tamper-evidence — if any historical entry is modified, the root diverges
Foundation for ZK proofs — tree must support Merkle path extraction for proof generation (Section 12)
3. LLM Guard Enhancements (Section 5.1)
Model restrictions:
Parse model field from request body JSON
Check against allowed_models list in policy
Deny with reason "model not in allowlist: {model}" if not permitted
Token usage parsing from response:
OpenAI: parse usage.total_tokens, usage.prompt_tokens, usage.completion_tokens from response body
Anthropic: parse usage.input_tokens, usage.output_tokens from response body
Compute actual cost using model pricing table (map model name -> cost per 1K tokens)
Update daily spend counter with actual cost (not just estimated)
Pricing table:
gpt-4o: $2.50/$10 per 1M input/output tokens
gpt-4o-mini: $0.15/$0.60 per 1M input/output tokens
claude-sonnet: $3/$15 per 1M input/output tokens
(configurable/extensible for new models)
4. Missing API Endpoints (Section 17)
These endpoints are consumed by the dashboard and are not yet implemented:
[BE-2] Audit Log + Merkle Tree, LLM Guard Enhancements & Missing API Endpoints
Labels:
backend,priority:high,week-1-4Assignee: Backend Dev (audit log), Yash (Merkle tree)
Context
Per Sections 7, 5.1, and 17 of the Source of Truth, every decision (approve/deny) must be logged in a tamper-evident audit log with an incremental Merkle tree. The current system has alerts and spend records but lacks the formal audit trail. Additionally, several planned LLM guard features and API endpoints are not yet implemented.
1. Audit Log System (Section 7 — Week 1-2)
Files:
src/audit/AuditEntrystruct per Section 18:audit_logtable — indexed ontimestamp,service,decisionfishnet.tomlat time of decision (from config hot-reload)2. Incremental Merkle Tree (Section 7.3)
Owner: Yash | Files:
src/audit/merkle.rstiny-keccakcrate)AuditEntry— root computed after appending the entry3. LLM Guard Enhancements (Section 5.1)
modelfield from request body JSONallowed_modelslist in policyusage.total_tokens,usage.prompt_tokens,usage.completion_tokensfrom response bodyusage.input_tokens,usage.output_tokensfrom response body4. Missing API Endpoints (Section 17)
These endpoints are consumed by the dashboard and are not yet implemented:
GET /api/status—{running: true, uptime: "2h 34m", services: ["openai", "binance"], today_spend: {openai: 12.50, binance: 0}, today_requests: {openai: 342, binance: 15}}GET /api/policies— return parsedfishnet.tomlas JSON objectPUT /api/policies— accept updated policy JSON, write back tofishnet.toml, trigger hot-reload, return{saved: true, policy_hash: "0x..."}GET /api/audit?from=&to=&service=&decision=&page=— paginated audit log query, returns{entries: [...], total: 1247, page: 1, pages: 63}GET /api/audit/export— return CSV file download of audit log (with Content-Disposition header)GET /api/spend?days=30—{daily: [{date: "2026-03-01", service: "openai", amount: 15.20}, ...]}Acceptance Criteria
AuditEntrywith all fields populated