Skip to content

Add ComputeID AgentPassport TRACE adapter (community tier) - #176

Merged
imran-siddique merged 6 commits into
agentrust-io:mainfrom
trustedaicompute-ops:main
Sep 10, 2026
Merged

Add ComputeID AgentPassport TRACE adapter (community tier)#176
imran-siddique merged 6 commits into
agentrust-io:mainfrom
trustedaicompute-ops:main

Conversation

@trustedaicompute-ops

Copy link
Copy Markdown
Contributor

Adds a community-tier integration mapping ComputeID AgentPassport /verify evidence into a TRACE v0.2-shaped record, via the third-party-control-plane / external-evidence-source path.

Honest, current result: FAIL at Level 0, 4 of 8 checks fail (missing cnf/proof-of-possession binding, and no policy/appraisal fields, since ComputeID is an identity-issuance system, not an execution-attestation runtime). No trace_conformance_level is declared for this reason. Full result and reasoning in CONFORMANCE.md.

Includes real, reproducible evidence: a genuine, unmodified ComputeID /verify response, an offline verifier requiring zero network calls, and a separate audit-chain integrity tool. The two hardest cryptographic checks (classical RSA-SHA256 and post-quantum ML-DSA-65 signature verification) pass and were adversarially tested (correctly fail against a fake CA certificate).

Will open a separate spec issue on trace-spec for the cnf/proof-of-possession gap and its relation to our existing DPoP support, as requested.

Added integration configuration for ComputeID AgentPassport TRACE Adapter.
Added README for ComputeID AgentPassport TRACE Adapter, detailing its functionality, limitations, usage instructions, and verification process.
Added TRACE conformance result details, including failures and explanations.
Add adapter code and CA certificate

@imran-siddique imran-siddique left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the submission, and for keeping the Level 0 failure and the software-bound scope in the package rather than around it.

I ran the package: convert-to-trace.js against evidence/opaque-diligence-demo-fresh.json, agentrust-trace-tests 0.5.1 from PyPI, and the schema at your pinned commit 3a561d84. The evidence is genuine. Recomputing independently of your code: RSA-SHA256 over signed_payload against public_key verifies, and ML-DSA-65 over the same bytes against pq_public_key verifies with @noble/post-quantum 0.4.1 (pk 1952 bytes, sig 3309 bytes) and fails on a modified payload. The receipt signature verifies against the included ca-cert.pem.

Six changes before this can be listed.

1. CI, two failures are yours to fix.

  • validate: marketplace.category: "Identity and access" is not in the enum. Use Identity & trust.
  • links: repository: https://github.com/trustedaicompute-ops/computeid-backend returns 404. Point it at a reachable URL.
  • (gate is waiting on maintainer approval, not on you.)

2. The documented result does not reproduce. README says FAIL (8 checks, 4 failure(s)). Running 0.5.1 at Level 0 today:

  TR-ENV  PASS        eat_profile sentinel matches
  TR-ENV  FAIL        TR-ENV-002: record is stale: iat 1788607112 is 299155s old, exceeding the maximum allowed age of 86400s
  TR-ENV  PASS        subject is a valid workload identity URI
  TR-ENV  FAIL        cnf must contain jwk with kty
  TR-SIG  FAIL        TR-SIG-004: cnf.jwk.kty is missing
  TR-SIG  UNVERIFIED  TR-SIG-005: no signature present; this record is NOT cryptographically verified
  TR-POL  FAIL        TR-POL-001: policy field is missing or not an object

Result: FAIL  (7 checks, 4 failure(s), 0 skipped)

Two problems. TR-APR-001 is cited in CONFORMANCE.md but does not exist in 0.5.1; the modules are ANC, ENV, POL, RTE, SCA, SIG, TXN. (appraisal is required by the schema, which is a different statement, and worth making in those terms.) And the result is clock-dependent: iat is fixed in a static bundle, so TR-ENV-002 fires once the capture is over 86400s old. Please regenerate against the pinned version, paste verbatim output, and record the capture time and the --max-age used.

3. The emitted record fails the schema at your own pinned commit. 31 errors, 10 of them from references: items require rel, id, resolver, and name/value are rejected as additional properties. TRACE-MAPPING.md §4 already describes the correct pointer shape; the adapter does not emit it. §4 also turns the outcomes into claims rather than pointers, which is the thing §3.1.2 is trying to prevent.

TRACE-MAPPING.md §7 is stale: it still says the mapping "has not been run through, and has not passed, the TRACE conformance suite" and reports 1185 passed, 1 skipped, which is the suite's own self-test, not your result. Delete or rewrite it so it agrees with CONFORMANCE.md.

4. offline-verifier.js does not verify the passport signatures. It reads bundle.signature_valid and bundle.pq_signature_valid from the service response and reshapes them. Its only cryptographic operation is checkIssuerTrusted. So the "independently computed" and "adversarially tested" framing does not describe the shipped code, even though the underlying evidence supports it (see above). Move those two computations into the verifier and the claim becomes true.

Related: verify-audit-chain.js requires pg, and there is no package.json or install step in the directory.

5. The receipt does not bind the passport keys. The receipt payload is:

{"expires_at":"...","issued_at":"...","key_id":"ebb276c2f18ed34f","passport_id":"f5d6cf87-...","signature_valid":true,"status":"active"}

It does not cover public_key, pq_public_key, or signed_payload. So the CA signature attests that ComputeID asserts this passport verified, not that these are the keys ComputeID issued for this subject. An offline verifier still has to trust the assertion for key binding. This is the question from my note of September 2 about how the two public keys are bound to the same subject and lifecycle, and it sits upstream of the cnf gap. Please carry it into the spec issue rather than filing cnf alone.

6. The record is unsigned. TR-SIG-005 reports it as not cryptographically verified. You already sign with two algorithms, so signing the emitted record is the shortest path to moving a check.

Not blocking, and correctly handled: no trace_conformance_level declared, runtime.platform: software-only, origin.kind: third-party-control-plane, and the hardware-attestation scope statement.

Community listing follows CI passing and a maintainer review of the revised package. Verified status requires us to run the integration end to end.

@imran-siddique imran-siddique left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Starting with the part that decides whether this gets listed at all: you declared your own failure. The metadata description says the adapter "does not currently pass TRACE conformance at any level", the PR body states FAIL at Level 0 with four of eight checks failing and gives the reason, no trace_conformance_level is claimed, and offline-verifier.js carries a note saying the wrapper only reshapes fields the live endpoint genuinely computes. A community-tier entry that publishes its own shortfall is worth more to a reader than one that passes quietly, because the catalog is only useful if an entry's claims can be believed.

Your CI had never actually run. Eight workflow runs were sitting in action_required, so the two checks you could see were not a verdict. They are released now and there are exactly two failures, both one line in integration.yaml, neither touching the adapter itself.

validate, on the schema enum:

marketplace: {category: "Identity and access", mark: CID}

Identity and access is not one of the eight permitted categories. The one you want is Identity & trust. Full set: Compliance, Developer tools, Evidence & receipts, Frameworks, Identity & trust, Model & weight custody, Observability, Security & policy.

links, one 404:

repository: https://github.com/trustedaicompute-ops/computeid-backend

That repository does not resolve. Your public repositories include computeid-passport, computeid-sdk, computeid-cli and computeid-mcp-gateway, so I expect this is a rename or a private repository rather than a wrong claim. Point it at something a reader can open; a maintainer cannot verify a listing whose source is unreachable.

Everything else is green: check, ruff and all four verify jobs.

One note, not blocking. tested_against pins agentrust-trace: "0.5.1" and the current release is 0.10.0. Recording the version you actually tested is correct and I would not have you change it to a version you did not run; it is worth knowing whether the mapping still holds on 0.10.0 before this is cited anywhere.

Your #307 in trace-spec is the substantive half of this and I have read it. It is a different conversation from the two lines above and will get its own answer there rather than here, so this PR is not waiting on it.

@carloshvp carloshvp left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed exact head bdc9ab7b98b774c327f9b31f127f83db6212df20. I independently reproduce the blockers, so I am requesting changes.

  1. The repository validator fails this submission because marketplace.category: "Identity and access" is outside the schema enum. The valid category is Identity & trust. The declared repository URL also returns HTTP 404.

  2. The adapter output does not validate against the TRACE schema at the pinned commit 3a561d84. I generated the record from opaque-diligence-demo-fresh.json and received 31 schema errors. All six references items omit required rel, id, and resolver properties and use rejected name/value fields. Required top-level claims are also absent, and runtime.measurement is missing. TRACE-MAPPING.md already shows the correct pointer shape, so the implementation and its own documentation currently disagree.

  3. offline-verifier.js does not independently verify the passport signatures it reports. Its only cryptographic verification is the receipt signature. The classical and ML-DSA outcomes are copied from bundle.signature_valid === true and bundle.pq_signature_valid === true. The receipt payload does not commit to public_key, pq_public_key, or signed_payload, so its valid CA signature cannot authenticate those key and payload inputs. Either perform both passport signature checks locally over the exact signed payload and keys or describe these fields as service assertions rather than independently verified outcomes.

  4. The conformance documentation is not reproducible as written. The generated record is clock-dependent because its fixed iat ages out, TR-APR-001 is not a check in the pinned 0.5.1 suite, and the 1185 passed, 1 skipped text in TRACE-MAPPING.md is the reference package's self-test rather than validation of this emitted record. Regenerate and record the exact adapter validation command, capture time, max-age setting, and verbatim result.

Local checks on this head: git diff --check is clean, the merge simulation against current main is conflict-free, the receipt signature verifies against the included CA certificate, and the offline verifier reports the expired receipt honestly. Those points do not resolve the catalog validation and evidence-provenance defects above.

1. integration.yaml: category "Identity and access" -> "Identity & trust"
   (schema enum fix); repository URL now points at the real,
   publicly-reachable computeid-trace-adapter repo instead of a private
   computeid-backend that 404s for readers.

2. convert-to-trace.js: references[] now uses the schema's actual shape
   (rel/id/resolver/digest, schema/trace-claim.json's
   additionalProperties: false rejects name/value). Emits a single
   reference pointing at the evidence bundle by SHA-256 digest (hex,
   per the digest pattern - an earlier attempt used base64url and would
   still have failed schema validation). The record now carries a real
   cnf.jwk and is genuinely Ed25519-signed (adapter-signing-key.pem /
   adapter-signing-pubkey.pem), so TR-ENV-004 and both TR-SIG checks now
   pass for real, not by fabricating a proof-of-possession claim about
   the underlying passport itself - cnf here names the key that signs
   this TRACE record, a separate concern from the AgentPassport's own
   RSA + ML-DSA-65 identity keys, which remain in the referenced bundle.

3. offline-verifier.js: classical_signature_valid and
   ml_dsa_signature_valid were reading the service's own
   signature_valid/pq_signature_valid fields rather than independently
   recomputing them - contradicting the file's own "independent
   verification" claim. Both are now genuinely recomputed from raw
   public_key/signature/signed_payload bytes in the bundle (RSA-SHA256
   via node:crypto, ML-DSA-65 via @noble/post-quantum 0.4.1). Verified
   adversarially: true against a genuine bundle, false against a
   locally tampered payload.

4. CONFORMANCE.md: regenerated against a freshly registered ComputeID
   passport (not the stale fixture, which was correctly failing
   TR-ENV-002 on staleness rather than anything real), with the exact
   command, tool version, and verbatim result recorded. Removed the
   TR-APR-001 citation - no TR-APR module exists in trace-tests 0.5.1.
   Real result: FAIL (7 checks, 1 failure - TR-POL-001 only, an honest
   and permanent scope gap). Added the raw JSON Schema validation
   result against schema/trace-claim.json @ 3a561d84 alongside it: 5
   errors, down from 31, all five being the same disclosed fact
   (model/policy/data_class/build_provenance/runtime.measurement do
   not exist for an identity-only issuer) - none fabricated to force a
   pass.

Added package.json/package-lock.json (previously missing from this
integration's directory - offline-verifier.js and convert-to-trace.js
both require dependencies that were never declared here) and
adapter-signing-pubkey.pem (the record-signing public key named in
cnf.jwk). The corresponding private key is intentionally not
committed (.gitignore'd, matching computeid-trace-adapter's own
pattern) and is held by the maintainer.
@trustedaicompute-ops

trustedaicompute-ops commented Sep 10, 2026 via email

Copy link
Copy Markdown
Contributor Author

@trustedaicompute-ops

trustedaicompute-ops commented Sep 10, 2026 via email

Copy link
Copy Markdown
Contributor Author

@imran-siddique imran-siddique left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving for Community listing.

The two red checks are ours, not the contributor's. validate fails on a stale README integration index, which is a generated file on our side and is regenerated on main immediately after this merge. gate was waiting on this review.

Scope note so the record is clear: Community covers structural validation. No trace_conformance_level is declared, the Level 0 failures are preserved and disclosed, the repository resolves, and offline-verifier.js now recomputes both the RSA-SHA256 and ML-DSA-65 signatures rather than reading signature_valid/pq_signature_valid off the service response, which is what made the independence claim true.

The cnf / proof-of-possession spec issue and our own end-to-end conformance run belong to the Verified track and are not blockers here.

@imran-siddique
imran-siddique merged commit 2d8144e into agentrust-io:main Sep 10, 2026
8 of 10 checks passed
imran-siddique added a commit that referenced this pull request Sep 10, 2026
scripts/generate_integration_index.py output went stale when the ComputeID
adapter landed, which is what the validate job flags. The index is generated
and the row is ours to add rather than the contributor's, so it is done here
instead of being sent back as a review comment.


Claude-Session: https://claude.ai/code/session_01CDzMWcn12dszchgrKfXzZY

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants