Capability Passport Revocation v1¶
Source schema: doc/schemas/capability-passport-revocation.v1.schema.json
Signed revocation artifact that invalidates a previously issued capability-passport.v1 or key-delegation.v1. Two signing authorities are recognised: the original issuer (sovereign operator who granted the capability/delegation) and the subject node (self-revocation by the node whose capability is being withdrawn). Issuer-signed revocations may be signed directly or by a proxy key with an inline issuer_delegation proof. The signed_by field discriminates between issuer and subject paths. Federated publication surfaces such as Seed Directory may append accepted revocations to an append-only revocation log; consumers of that federated surface MUST poll GET /revocations?since= and invalidate cached passports/delegations named by passport_id or target_id. Node-local revocations that only affect local dispatch may use the same artifact shape without Seed Directory publication.
Governing Basis¶
doc/project/40-proposals/025-seed-directory-as-capability-catalog.mddoc/project/40-proposals/024-capability-passports-and-network-ledger-delegation.md
Project Lineage¶
Requirements¶
doc/project/50-requirements/requirements-006-node-networking-mvp.mddoc/project/50-requirements/requirements-010-middleware-executor.mddoc/project/50-requirements/requirements-011-dator-arca-contracts.md
Stories¶
doc/project/30-stories/story-001-swarm-node-onboarding.mddoc/project/30-stories/story-004-pod-client-onboarding.mddoc/project/30-stories/story-006-buyer-node-components.mddoc/project/30-stories/story-006-voluntary-swarm-exchange.mddoc/project/30-stories/story-007-settlement-capable-node.md
Fields¶
| Field | Required | Shape | Description |
|---|---|---|---|
schema |
yes |
const: capability-passport-revocation.v1 |
Schema discriminator. MUST be exactly capability-passport-revocation.v1. |
revocation_id |
yes |
string | Stable unique identifier for this revocation record. MUST use the passport-revocation: prefix. |
passport_id |
no |
string | Identifier of the capability-passport.v1 being revoked. MUST use the passport:capability: prefix and MUST match an existing passport known to the verifying party. |
target_id |
no |
string | Identifier of the key-delegation.v1 being revoked. Exactly one of passport_id or target_id MUST be present. |
node_id |
yes |
string | Node whose delegated capability is being revoked. MUST match the node_id in the original passport. |
capability_id |
yes |
string | Bare kebab-case capability identifier being revoked (e.g. network-ledger). MUST match the capability_id in the original passport. |
revoked_at |
yes |
string | RFC 3339 timestamp at which the revocation was declared. The Seed Directory MUST store this timestamp in the revocation log entry. |
signed_by |
yes |
enum: issuer, subject |
Who signed this revocation. issuer — the sovereign operator participant who originally issued the passport (uses issuer/participant_id). subject — the target node revoking its own capability using its node key (no issuer/participant_id; the signer public key is derived from node_id). |
issuer/participant_id |
no |
string | Canonical participant:did:key:z... identifier of the revoking participant. REQUIRED when signed_by == "issuer" and MUST match issuer/participant_id in the original passport. MUST NOT be present when signed_by == "subject". |
reason |
no |
string | Optional human-readable note explaining why the passport was revoked (e.g. operator key rotation, node decommissioned). Not machine-interpreted; informational only. |
issuer_delegation |
no |
ref: #/$defs/delegationProof |
Optional compact inline proof authorising a proxy key to sign this issuer revocation for issuer/participant_id. MUST NOT be present when signed_by == "subject". Excluded from the revocation signature payload. |
signature |
yes |
ref: #/$defs/ed25519Signature |
|
policy_annotations |
no |
object | Optional informational annotations. MUST NOT alter revocation semantics. |
Definitions¶
| Definition | Shape | Description |
|---|---|---|
delegationProof |
object | |
ed25519Signature |
object | Ed25519 signature over the deterministic canonical JSON of the revocation artifact with the signature and issuer_delegation fields omitted entirely from the signed payload. Object keys are sorted lexicographically; no insignificant whitespace; arrays left in original order. For signed_by == "issuer" the signing key is either issuer/participant_id or issuer_delegation.proxy_key; for signed_by == "subject" the signing key belongs to the node identified by node_id. |
Conditional Rules¶
Rule 1¶
Constraint:
{
"description": "Exactly one target field is required: `passport_id` for capability passports or `target_id` for key delegations.",
"oneOf": [
{
"required": [
"passport_id"
],
"not": {
"required": [
"target_id"
]
}
},
{
"required": [
"target_id"
],
"not": {
"required": [
"passport_id"
]
}
}
]
}
Rule 2¶
When:
{
"properties": {
"signed_by": {
"const": "issuer"
}
},
"required": [
"signed_by"
]
}
Then:
{
"required": [
"issuer/participant_id"
]
}
Rule 3¶
When:
{
"properties": {
"signed_by": {
"const": "subject"
}
},
"required": [
"signed_by"
]
}
Then:
{
"properties": {
"issuer/participant_id": false,
"issuer_delegation": false
}
}
Field Semantics¶
schema¶
- Required:
yes - Shape: const:
capability-passport-revocation.v1
Schema discriminator. MUST be exactly capability-passport-revocation.v1.
revocation_id¶
- Required:
yes - Shape: string
Stable unique identifier for this revocation record. MUST use the passport-revocation: prefix.
passport_id¶
- Required:
no - Shape: string
Identifier of the capability-passport.v1 being revoked. MUST use the passport:capability: prefix and MUST match an existing passport known to the verifying party.
target_id¶
- Required:
no - Shape: string
Identifier of the key-delegation.v1 being revoked. Exactly one of passport_id or target_id MUST be present.
node_id¶
- Required:
yes - Shape: string
Node whose delegated capability is being revoked. MUST match the node_id in the original passport.
capability_id¶
- Required:
yes - Shape: string
Bare kebab-case capability identifier being revoked (e.g. network-ledger). MUST match the capability_id in the original passport.
revoked_at¶
- Required:
yes - Shape: string
RFC 3339 timestamp at which the revocation was declared. The Seed Directory MUST store this timestamp in the revocation log entry.
signed_by¶
- Required:
yes - Shape: enum:
issuer,subject
Who signed this revocation. issuer — the sovereign operator participant who originally issued the passport (uses issuer/participant_id). subject — the target node revoking its own capability using its node key (no issuer/participant_id; the signer public key is derived from node_id).
issuer/participant_id¶
- Required:
no - Shape: string
Canonical participant:did:key:z... identifier of the revoking participant. REQUIRED when signed_by == "issuer" and MUST match issuer/participant_id in the original passport. MUST NOT be present when signed_by == "subject".
reason¶
- Required:
no - Shape: string
Optional human-readable note explaining why the passport was revoked (e.g. operator key rotation, node decommissioned). Not machine-interpreted; informational only.
issuer_delegation¶
- Required:
no - Shape: ref:
#/$defs/delegationProof
Optional compact inline proof authorising a proxy key to sign this issuer revocation for issuer/participant_id. MUST NOT be present when signed_by == "subject". Excluded from the revocation signature payload.
signature¶
- Required:
yes - Shape: ref:
#/$defs/ed25519Signature
policy_annotations¶
- Required:
no - Shape: object
Optional informational annotations. MUST NOT alter revocation semantics.
Definition Semantics¶
$defs.delegationProof¶
- Shape: object
$defs.ed25519Signature¶
- Shape: object
Ed25519 signature over the deterministic canonical JSON of the revocation artifact with the signature and issuer_delegation fields omitted entirely from the signed payload. Object keys are sorted lexicographically; no insignificant whitespace; arrays left in original order. For signed_by == "issuer" the signing key is either issuer/participant_id or issuer_delegation.proxy_key; for signed_by == "subject" the signing key belongs to the node identified by node_id.