background gif

Demos · DEMO-HACK

Gate walkthrough

Same REST/JSON shape as a news poll API: different authority object. Each call carries a one-shot twin proof; the gate burns the nonce before it validates.

Burn-before-validate is the structural reason a second submission of the same envelope always fails.ShippingGate stage 5 spends the nonce in the durable ledger before stage 6 validates the proof.Holds under the reference architecture

Authority expires at the end of each request.The envelope binds method, endpoint_id, request hash, policy hash, tau, and nonce (one message, one use).Holds under the reference architecture

Happy path

Client canonicalizes → challenges → responds → assembles the envelope. Server burns, validates, then fetches headlines. Transcript tags match the platform observability taxonomy.

Allow path transcript6 events
  • canon

    Canonicalized request body

    method=POST endpoint=news.eni6ma.demo/api/news/poll

    0.00s
  • challenge

    Circuit challenge issued

    tau bound · freshness window 5000ms

    0.04s
  • respond

    Twin respond completed

    bearings spent · proof_hash attached

    0.18s
  • envelope

    Envelope assembled

    nonce_uuid reserved · request_hash bound

    0.19s
  • burn

    Nonce burned before validate

    ledger: RESERVED → SPENT

    0.21s
  • verdict

    ALLOW: twin validated

    application policy passed · resource served

    0.27s
Asset needed: DEMO-HACK client Poll tab after first ALLOW.

Gate order

  1. 01

    Request hash

    Recompute digests; reject on mismatch

  2. 02

    Endpoint

    endpoint_id matches server constant

  3. 03

    Policy

    policy_hash from server POLICY_STRING

  4. 04

    Anchor

    Circuit handle active in registry

  5. 05

    Freshness

    tau within the call window

  6. 06

    Burn nonce

    Spend before twin validation

  7. 07

    Validate

    Twin proof check (local or registry)

  8. 08

    Serve

    Application policy, then resource

Reject stages

Every failed submission still teaches the same lesson: the gate order is load-bearing. Below is what each emitted stage means, framed as how the mechanism works, not as a catalog of residual risk.

stage=request-hash

Body or binding mismatch

The gate recomputes the composite digest. Changing feed, limit, or any bound field without a fresh prove fails here.

stage=endpoint

Endpoint retarget

endpoint_id is compared to a server constant. A relayed proof aimed at another route fails the binding.

stage=policy-hash

Policy loosen attempt

policy_hash is derived from the server POLICY_STRING, not attacker-supplied policy text.

stage=anchor

Inactive circuit

The handle must be active. Revocation is one registry state change (deactivated circuits never reach serve).

stage=freshness

Stale tau

Envelopes outside the freshness window are rejected before burn.

stage=nonce

Replay of a fossil

Burn-before-validate spends the nonce on first submission. A second identical envelope dies at nonce.

stage=validate-proof

Twin failure

After burn, twin validation must still pass. Failed validation does not unspend the nonce.

stage=policy

Application policy

Even a valid twin must satisfy route policy (feeds, limits) before the protected resource runs.

Replay reject transcript4 events
  • canon

    Canonicalized request body

    identical bytes to prior envelope

    0.00s
  • envelope

    Envelope received

    same nonce_uuid as previous ALLOW

    0.01s
  • burn

    Nonce already consumed

    stage=nonce · replay detected

    0.02s
  • verdict

    REJECT: fossil envelope

    capture ≠ authority for a second spend

    0.02s
Asset needed: DEMO-HACK adversary UI showing stage=nonce.

Binding & burn

function requestHash({ method, endpoint_id, requestBodyHash, policyHash, tau, nonce_uuid }) {
  const input = [method, endpoint_id, requestBodyHash, policyHash, String(tau), nonce_uuid].join('||');
  return sha256(input);
}