Secure Transfer · Live labOverview and diagrams

Run a transfer. Inspect the database evidence.

This lab calls the real local Java services and reads their PostgreSQL records. It uses dedicated teaching accounts and simulated USD. No financial or attack action runs until you click; readiness and evidence reads run automatically.

Start the local lab helper

From the full project, keep a PowerShell terminal open and run:

powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\live-demo.ps1 -StartStack

Open the running local lab. Opening this file by itself does not connect to the databases.

No operation observed yet.

Waiting for an experiment

Database observations will appear here when the local helper is connected.

Steps below are derived from persisted rows and audit events, not captured network traffic. Some processing stages may complete between polls. Each database is read separately; the logical table-group views are not one atomic snapshot. Missing or unavailable evidence never counts as success.

Delivery: Primary outbox → embedded ActiveMQ (persistent KahaDB) → protected SQL job → verification → accounting. The queue is part of the processor JVM, not a third PostgreSQL database or an independent failover server.

Incident email: a new integrity incident also queues one protected notification for that operation. A separate sender retries delivery without authorizing or settling transfers. Open the local test inbox after inserting a fresh forged row. Default Mailpit capture does not deliver to Gmail, even when a real recipient address is displayed. Repeating a previously demonstrated operation does not create another initial alert.

Primary DB

Attacker-controlled source. Instructions and status projections, not authoritative balances.

Not observed

Audit / Protected DB

One PostgreSQL database, separate evidence and accounting roles. Java calculates; protected SQL commits the financial effect. The simulated Primary attacker cannot write here.

Receipts and history

Not observed

Execution and accounting

Not observed

What the two actions demonstrate

Valid transfer: the application requests a MAC, the key service commits a receipt, Primary DB receives the operation and an outbox hint. Embedded ActiveMQ delivers the UUID to a protected job; the processor checks the operation before atomic settlement. Expected balances: Alice $975, Bob $25. Exactly two postings.

Forged row: the helper inserts a fresh operation and an outbox row directly into Primary DB with a fake tag and no independent issuance. Expected result: QUARANTINED: No independent issuance receipt. There are no postings and the protected balances do not change.

This forged-row case fails before HMAC recomputation. It demonstrates refusal of an unauthenticated instruction, not a measured MAC mismatch. The helper's observation access to both databases is trusted lab tooling; the attacker action writes only Primary DB.

Fixed attack SQL shape
INSERT INTO transactions
  (id, operation_json, key_id, content_hash, mac, created_at_micros)
VALUES
  (server_owned_id, fixed_fixture_payload, 'live-demo-forged-key',
   repeat('0', 64), repeat('0', 64), fixed_fixture_time);

INSERT INTO transaction_outbox (...) VALUES (..., 'LIVE_DEMO_FORGED', ...);

-- Both inserts commit together. Retries use the same fixture IDs.
-- No issuance API call, audit write, settlement write or arbitrary SQL input.
Current evidence JSON (dedicated fixtures only)
Not observed.

Secret keys and backend credentials stay on the server. Displayed HMAC tags and key IDs are operation metadata, not secret key bytes. Stop the helper with Ctrl+C in its terminal. Fixture rows and audit history are retained.