Issue a capability token
Prerequisites
- A running
service-contentinstance you can reach over HTTP, holding its persistent Ed25519 keypair on disk curlor an equivalent HTTP client — no CLI tool exists for any part of this- The role string you intend to grant
- Optionally, a node label and a comma-separated archive scope list to narrow the token
- The receiving peer's reachable
POST /v1/pairendpoint
Purpose
Mint an Ed25519-signed pairing token from service-content and register it with a peer service, so the two can authenticate to each other over HTTP — about five minutes.
Procedure
Warning: no revocation mechanism exists for either token type described here. An issued token is live for its full 24 hours and nothing invalidates it early. Scope every token as narrowly as the work allows before you issue it.
-
Request a pairing token from the issuing service.
node_labelandarchive_scopeare optional;roleis not: -
Read the response, which is JSON carrying two fields:
-
Optional: decode the token to confirm what you just issued. The wire format is
<base64url(payload_json)>.<base64url(ed25519_signature)>, so base64url-decoding the first dot-separated segment yields the payload:issuer,role,nonce,expiry,archive_scope, andpeer_type. -
Record the expiry. It is set 24 hours from issuance, and it is the only thing that ever ends the token's validity.
-
Register the token with the receiving peer. This is the step that creates the pairing — the other party makes this call, not the issuer:
The receiving service verifies the signature against the supplied public key and records the pairing.
-
Send subsequent calls to capability-gated routes with the
X-Foundry-Capabilityheader:
Expected outcome
The receiving peer holds a recorded pairing whose signature it has verified, and it expires 24 hours after the token was issued. Requests carrying a well-formed, correctly-signed, in-date X-Foundry-Capability header reach their handler on the gated routes.
Verification
Confirm the pairing token first, before registering it: base64url-decode the payload segment and check that role, archive_scope, and expiry match what you asked for. A token whose archive_scope is wider than intended cannot be narrowed after issue and cannot be withdrawn.
Confirm the capability header by using it. Exercise a capability-gated route with the header attached and confirm the request reaches the handler; a missing, malformed, badly-signed, or expired header is rejected at the gate before the handler runs. There is no dedicated verification endpoint — the gate itself is the check.
Note: the two credentials are genuinely distinct, not one credential under two names. The pairing token establishes the pairing and carries
issuer/role/nonce/expiry/archive_scope/peer_type. TheX-Foundry-Capabilityheader proves identity on each later call and carriesfrom_instance,user_scope,archive_scope,nonce,expiry,peer_type, and an optionalforwarded_for. They share the base64url-payload-plus-Ed25519-signature shape and nothing else.
Note: exactly two API routes are gated on the capability header today. The rest of the service's routes do not check it, so the header's presence is not a general-purpose access control across the whole API.
Rollback
There is nothing to roll back and no way to undo an issue. A token you did not mean to create stays valid for the remainder of its 24 hours; issuing a replacement does not disturb it.
The one action that makes an issued token permanently unusable before its expiry is a change to the signing service's underlying keypair, which happens only if its persisted key file is deleted and the service restarts. That is a manual operator action, it is not a supported feature, and it invalidates every token and pairing that service has ever signed rather than just the one you regret. Rotate keys and capability tokens covers what replacement actually looks like given these constraints.
Next steps
- Rotate keys and capability tokens — replace a credential within the 24-hour expiry model
- service-content — entity extraction and knowledge-graph host — the service that issues and verifies these tokens
- Capability-based security — the authorization model behind the header