TrustGraph

Browse api referenceAPI referenceAttestationsBind a deviceContent certificatesDevice authorityEdgesEpoch commitmentsExternal signing keysGit signer membershipGraph keysPublic handlesHealth and readinessNodes and account deletionReachabilityRelationship tags

Content certificates

Issue device membership evidence and check current lifecycle status.

Auth: Own-device signed read, operation issue-device-certificate.

Request and response

Angle-bracket values describe placeholders, including nested objects and numeric types; these are wire shapes, not captured service data. Replace them before sending.

POST /v1/graph-keys/certificate HTTP/1.1
Host: trust-staging.rebellion.systems
Content-Type: application/json

{
  "graphKeyId": "<own-device-id>",
  "graphNodeId": "<own-node-id>",
  "authorization": {
    "graphKeyId": "<device-id>",
    "nonce": "<fresh-random-nonce>",
    "signedAt": "<current-ISO-timestamp>",
    "signature": "<base64-DER-signature>"
  }
}

Response shape:

{
  "certificate": "<issuer-signed-device-certificate>"
}

A membership certificate links a device public key to a stable node through an issuer signature. It can travel with signed content so recipients can verify the content locally and separately check current device status.

Issue your own certificate

POST /v1/graph-keys/certificate

Send {graphKeyId, graphNodeId, authorization}. Sign read operation issue-device-certificate over the exact two-field query. The signing device must be the requested key and belong to the requested node. Graph-purpose devices on chained nodes require approval; content-signing keys can request only their own certificate.

The response is {certificate}:

export type DeviceMembershipCertificate = {
  v: 'trust-graph-device-certificate-v1';
  issuer: string;
  certificateId: string;
  graphKeyId: string;
  graphNodeId: string;
  publicKeyJwk: { kty: 'EC'; crv: 'P-256'; x: string; y: string };
  issuedAt: string;
  expiresAt: string;
  attestationKeyId: string;
  signature: string;
};

The issuer is the exact API origin pinned by your application. The Ed25519 signature covers canonical JSON of the other fields. Certificate lifetime is capped at seven days, the device's expiry and, for content-signing keys, the remaining signing window. Issuance requires positive remaining lifetime; exact expiry returns 403 GRAPH_KEY_EXPIRED after proof of possession.

Check lifecycle status

POST /v1/graph-keys/certificate/status accepts {certificate, nonce}. Use a fresh nonce of 16–256 characters. The complete valid issuer-signed certificate authorizes this check; no graph-device read authorization is needed.

The response is {status}. The signed status object contains v: "trust-graph-device-status-v1", certificateDigest, nonce, evaluatedAt, status, revokedAt, attestationKeyId and signature. The digest covers canonical JSON of the complete certificate, including its signature.

StatusMeaning
validCertificate and device pass current lifecycle checks
revokedDevice has been revoked; revokedAt supplies its time
expiredDevice, certificate or content-signing window has expired
unavailableMembership cannot be established

Verify both issuer signatures, pinned origin and key, certificate times, certificate digest, nonce and status freshness. Renewal does not extend an existing certificate. Invalid issuer signatures are refused with 401. Both issuance and status use query rate limits.

Does not establishMembership does not establish humanhood, trust, authorship or when content was signed. Status is lifecycle-based; it is not a fresh device-chain approval assertion. Verify content signatures locally, then query from your own node and verify a positive path locally before claiming a connection.
Checked against server 9f47f2d · SDK 12053abLast updated 2026-11-04Edit on GitHub