- Add NFC ePassport roadmap (ICAO 9303, eIDAS) - Add TensorFlow.js edge face detection (BlazeFace) - Add structured audit logger (GDPR-compliant) - Risk scoring support Part of KYC Apple Native UX v1.1.0
9.3 KiB
EXTREME CERTIFICATION AUDIT — SECTIONS 1-3
Date: 2026-06-05T15:47 UTC
Auditor: TÜV Lead Auditor / Chaos Engineer (subagent)
Baseline: GECL chain v0.3.0 (localhost:3263), Audit Engine (localhost:3251), Ledger (localhost:3250)
SECTION 1: EVENT COMPLETENESS PROOF
[S1.1] GECL Schema Discovery
STATUS: PROVEN
EVIDENCE:
GECL service: amos-gecl-chain v0.3.0 (PID 2609293)
DATABASE: wavult_identity (NOT amos)
Actual routes: /health, /append, /chain, /status, /verify, /block/:hash, /certify,
/streams/:id, /audit/events, /audit/events/batch, /audit/trail/:entity_id,
/audit/trace/:trace_id, /audit/summary
Tables (wavult_identity): audit_events (id, tenant_id, trace_id, correlation_id, user_id,
service, entity_type, entity_id, action, decision_source, before_state, after_state,
metadata, ip_address, session_id, ts)
Initial state: total_blocks=0, chain_hash=000...000 (pristine)
FINDING: GECL has two distinct subsystems: (1) in-memory hash chain (/append, /chain, /status) and (2) SQL audit event store (/audit/events → wavult_identity.audit_events). These are DECOUPLED — audit events written via /audit/events do NOT auto-create chain blocks.
[S1.2] CRUD Operations Audit Trail — CREATE + POST
STATUS: PARTIAL
Test Entry
entry_id: 712f74f4-1a0c-4391-9f21-635fc7bacbbb
trace_id: 9416a41a-fe32-4491-a855-858b431f3f9a
status: draft → posted
period: 2026-07 (opened manually for test; all prod periods closed)
Audit Trail Link-by-Link
| Layer | Status | Evidence |
|---|---|---|
| DB (amos.ledger_journal_entries) | ✅ PROVEN | Row exists: status=posted, created_at=15:44:00, posted_at=15:44:05 |
| DB (amos.ledger_audit_log) | ✅ PROVEN | 2 rows: [created] trace=9416a41a ts=15:44:00 + [posted] trace=8dbef483 ts=15:44:05 |
| Hermes JSONL (/opt/amos/data/hermes/events.jsonl) | ✅ PROVEN | finance.journal.created (trace=9416a41a, ts=15:44:00.360) + finance.journal.posted (trace=8dbef483, ts=15:44:05.146) |
| NATS publish | ❌ FAILED | Redis DOWN → Hermes falls back to JSONL only. No NATS/JetStream publish. AAMOS_AUDIT stream: 0 msgs |
| GECL audit_events (wavult_identity) | ❌ FAILED | audit/trail/712f74f4?tenant_id=wavult-group → count=0. Ledger publishes to hermes JSONL but NOT to GECL audit API |
| GECL chain blocks | ❌ FAILED | total_blocks=0. No auto-integration between ledger ops and GECL chain append |
| Audit Engine 3251 trail | ❌ FAILED | Same wavult_identity.audit_events — also returns count=0 for entity_id |
FINDING:
- Ledger creates complete audit trail in its own DB (amos.ledger_audit_log) ✅
- Hermes event fabric fires events to JSONL fallback (Redis DOWN) ✅
- Cross-system propagation to GECL is BROKEN: no consumer bridges hermes JSONL/Redis → GECL audit_events
- GECL chain (in-memory hash blocks) has 0 blocks — never fed by ledger operations
- Critical Gap: Two separate audit stores (amos.ledger_audit_log vs wavult_identity.audit_events) with no bridge
NOTE on trace_id mismatch: ledger_audit_log shows different trace_ids for created vs posted operations on the same entry (9416... vs 8dbef4...). Correlation_id is also different. This means created and posted events are NOT linked by a shared trace chain.
[S1.3] Rollback Test
STATUS: FAILED
EVIDENCE:
POST /api/ledger/journal/:id/rollback → 404 Cannot POST
POST /api/ledger/journal/:id/void → 404 Cannot POST
FINDING: No rollback or void endpoint exists in the ledger API (aamos-ledger). Only /api/ledger/journal/:id/post is implemented. Rollback/void operations are architecturally missing — there is no reversal mechanism, and therefore no audit trail for reversals.
SECTION 2: EVENT STORM TEST (10,000 events)
[S2.1] Storm Execution
STATUS: PROVEN
EVIDENCE:
Tag: STORM-1780674412596
Target: GECL /audit/events (direct)
Batch size: 100 concurrent
Total sent: 10,000
Success: 10,000 (100%)
Failures: 0
Total time: 22,426ms
Throughput: 446 events/sec
[S2.2] Ordering Verification
STATUS: PROVEN
EVIDENCE:
SELECT ts FROM audit_events WHERE service='storm-test' AND metadata->>'tag'=$1 ORDER BY ts ASC
→ 10,000 rows returned
→ Monotone increasing: TRUE (0 out-of-order pairs detected)
[S2.3] Idempotency / Duplicate Detection
STATUS: PROVEN
EVIDENCE:
SELECT entity_id, COUNT(*) FROM audit_events WHERE service='storm-test'
GROUP BY entity_id HAVING COUNT(*)>1
→ Duplicate entity_ids: 0
[S2.4] GECL Chain Integrity After Storm
STATUS: FAILED
EVIDENCE:
POST /audit/events → writes to audit_events table (SQL) only
GECL chain blocks after storm: total_blocks=0 (chain NOT fed by audit/events)
/verify → ok=true, valid=true, errors=[] (trivially valid — empty chain)
FINDING: The GECL cryptographic hash chain remains empty (0 blocks) despite 10,000 audit events being written. The SQL audit store and the in-memory chain are not connected. Chain integrity is vacuously valid (empty). The total_blocks=0 is a structural concern — the chain provides no tamper-evidence for any audit events.
Rate limiting: GECL audit engine (3251) implements per-tenant rate limiting. For storm at 10k events, batch API (/audit/events/batch) was used successfully without rate-limit rejection.
SECTION 3: LINEAGE INTEGRITY TEST
[S3.1] Event Population
STATUS: PARTIAL
EVIDENCE:
audit_events (wavult_identity, non-storm): 4 events
ledger_audit_log (amos): 46 events
hermes JSONL: multiple event types, ~25+ records
FINDING: Only 4 non-storm events in GECL audit_events table (used for lineage tracking). Ledger's audit log has 46. The two stores are isolated.
[S3.2] Lineage Field Completeness (100 random events)
STATUS: PROVEN (within each store)
EVIDENCE:
GECL audit_events (4 non-storm events):
Complete (trace_id + correlation_id + entity_id + decision_source): 4/4 (100%)
Broken: 0
ledger_audit_log (46 events):
Complete: 46/46 (100%)
Broken: 0
Schema includes: id, tenant_id, trace_id, correlation_id, user_id, service, entity_type,
entity_id, action, decision_source, before_state, after_state, metadata, ip_address, session_id, ts
[S3.3] Cross-System Lineage Chain (event→parent→originator→decision→action)
STATUS: FAILED
EVIDENCE:
Entry 712f74f4:
amos.ledger_journal_entries → has trace_id ✅
amos.ledger_audit_log → 2 entries (created, posted) ✅ but different trace_ids ⚠️
hermes events.jsonl → 2 events matching same entity_id ✅ but trace_ids differ from audit_log posted event
wavult_identity.audit_events → 0 entries ❌
GECL chain blocks → 0 ❌
Multi-event trace groups (same trace_id across multiple events): 0 (no cross-event traces)
FINDING: Full lineage chain (event→parent→originator→decision→action) is BROKEN across system boundaries:
createdandpostedactions on the same entry have DIFFERENT trace_ids (no shared trace)- Hermes JSONL events are not forwarded to GECL
- GECL audit_events has 0 entries for any ledger operation
- No parent_id field exists — there is no explicit parent-child relationship
- Cross-system replay via GECL
/audit/trace/:trace_idor/audit/trail/:entity_idreturns empty results for all ledger entities
SECTION 1-3 SUMMARY SCORECARD
| Check | Status | Score |
|---|---|---|
| S1.1 GECL schema discovery | PROVEN | ✅ |
| S1.2a DB write (ledger_journal_entries) | PROVEN | ✅ |
| S1.2b DB audit log (ledger_audit_log) | PROVEN | ✅ |
| S1.2c Hermes event emission | PROVEN | ✅ (JSONL fallback) |
| S1.2d NATS publish | FAILED | ❌ (Redis DOWN, no NATS publish) |
| S1.2e GECL audit trail cross-DB | FAILED | ❌ (no bridge amos→wavult_identity) |
| S1.2f GECL chain blocks | FAILED | ❌ (0 blocks, not auto-fed) |
| S1.2g Audit engine 3251 visibility | FAILED | ❌ (same gap) |
| S1.3 Rollback endpoint | FAILED | ❌ (does not exist) |
| S2.1 Storm 10k throughput | PROVEN | ✅ (10000/10000, 446 ev/s) |
| S2.2 Monotone ordering | PROVEN | ✅ |
| S2.3 Zero duplicates | PROVEN | ✅ |
| S2.4 Chain integrity | FAILED | ❌ (vacuously valid, 0 blocks) |
| S3.1 Event population | PARTIAL | ⚠️ (isolated stores) |
| S3.2 Field completeness (per-store) | PROVEN | ✅ (100% within stores) |
| S3.3 Cross-system lineage chain | FAILED | ❌ (broken at every boundary) |
Section Scores
| Section | Score | Verdict |
|---|---|---|
| Section 1: Event Completeness | 3/8 checks PROVEN | PARTIAL |
| Section 2: Event Storm | 3/4 checks PROVEN | PARTIAL |
| Section 3: Lineage Integrity | 1/3 checks PROVEN | PARTIAL |
Critical Findings
- GECL chain is empty (0 blocks) — no tamper-evident ledger chain despite service running
- No cross-DB bridge — ledger audit (amos) never reaches GECL audit store (wavult_identity)
- Redis DOWN — Hermes event bus degraded to JSONL-only; no real-time NATS propagation
- Trace fragmentation — created/posted on same entity have different trace_ids, preventing full trace reconstruction
- No rollback/void — no API surface for reversals; irreversible financial records
- GECL chain decoupled from audit_events — the SQL audit store and hash chain are architecturally disconnected