Skip to content

aeoess-aps: revocation mapping, two TRACE surfaces, three questions #140

Description

@aeoess

Follow-up to #46 as promised: revocation for the aeoess-aps exporter.

I retested the exporter against the current trace first (#139 carries tested_against: agentrust-trace 0.9.0). Then I mapped APS revocation against TRACE, and it splits into two surfaces that I've kept separate on purpose.

Surface 1, released. agentrust-trace 0.9.0 (newest on PyPI) ships no revocation schema. Its executable revocation path is the RevocationStore consulted by verify_record(): a membership test on the record-signing key's RFC 7638 thumbprint or kid, fail-closed on error, absence accepts. I ran it against an APS key: empty store accepts, listed kid rejects, raising store rejects.

Surface 2, current main at 738358d, untagged. schema/trace-revocation.json and schema/trace-revocation-bundle.json (landed 2026-08-19, in no release). A TraceRevocation/1.0 statement withdraws a record-signing key from a log entry onward; required fields are type, compromised_key_id, last_valid_entry_id, log_id, revocation_key_id, sig, with additionalProperties: false. I reproduced the schema shape and its rejections with jsonschema 4.26.0 (omitting any of the three id fields, empty string, null, and an extra property are all rejected). docs/verification.md says the store does not yet do entry-id-scoped revocation, so nothing executes this statement today.

What APS revocation is. A delegation revocation withdraws a delegationId; a principal-binding revocation withdraws a binding_id. Neither names a record-signing key and neither asserts a compromise. revokedBy is the key that signed the revocation, not the key being withdrawn. This exporter also emits unsigned records with transparency: none, so it has no key in any store and no log position.

Mapping.

Surface 1 (0.9.0 store): no_mapping for all three APS artifacts. TRACE revokes a key; APS withdraws an authority; and there is no record-signing key on this integration's records to enter. Divergence to keep in view: an empty store accepts and an omitted store skips the check, while APS treats "no artifacts observed" as no evidence, not as not revoked.

Surface 2 (main, prospective only):

TRACE field APS source result
type none, emitter constant not APS-derived
compromised_key_id none no_mapping, blocking. APS withdraws an authority and asserts no compromise; revokedBy is the signer and must never land here
last_valid_entry_id none no_mapping, blocking (no log position)
log_id none no_mapping, blocking (transparency none)
revocation_key_id none no_mapping, blocking (names the key that signs the TRACE statement; the exporter holds none)
sig none no_mapping, blocking (different preimage; no signing contract)
revoked_after_entry none optional, omitted
revoked_at revokedAt / revoked_at partial: converted to Unix seconds; informational in TRACE
reason reason / reason_code partial: delegation reason carries; binding reason_code renders as text, code semantics lost
(none) affected_scope, revocation ids, artifact digest no_mapping, no slot
bundle SignedRevocationObservation no_mapping: closest role analogue, but an observation cannot construct a bundle

So: no valid TraceRevocation/1.0 statement can be emitted from this integration today, and no store entry should be manufactured from an APS revocation. That's why this is an issue and not a PR.

Three questions:

  1. Which basis should the APS integration use for revocation? The integration currently pins agentrust-trace 0.9.0, whose executable revocation surface is the key-level RevocationStore. Current main also has TraceRevocation/1.0 and its bundle, but the verifier documentation says entry-id-scoped revocation is not implemented yet. Should the integration describe released 0.9.0 only, or is a separate prospective mapping against current main useful now?
  2. Authority revocation versus key revocation. APS revokes a delegation or principal binding. Neither artifact asserts that an associated record-signing key is compromised or globally revoked. My mapping therefore marks both RevocationStore membership and compromised_key_id as no_mapping. Is that the intended boundary on the TRACE side?
  3. Constructing a current-main statement. The APS exporter has no TRACE log_id / entry boundary and no agreed key that would sign a TraceRevocation/1.0 statement. My reading is that it should emit no revocation statement today, while recording the fields that do map (revoked_at, reason) and the required gaps. Is that the right interpretation?

Whatever you answer, I'll update the exporter's mapping doc accordingly and keep tested_against honest. The APS-side revocation verification these artifacts come from is aeoess/agent-passport-system#123.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-review:HIGHContributor check flagged HIGH risk

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions