Keyring

Embed plane

What an embed token reaches: one tenant's keys and nothing else.

Generated from packages/api/src/embed/embed.controller.ts by packages/docs/tools/generate-reference.mjs. Every example is a real exchange recorded against the control plane by packages/api/src/testing/reference-examples.spec.ts, with ids from that run. Credentials in the formats this product issues (kr_, krsk_, krses_, JWTs) and values under credential-named fields (password, *_secret, *_token, *_key, lookup_hash) are elided at record time; the recorded file and every page of this site are swept for credential shapes (kr_, krsk_, krses_, JWTs, URLs carrying a password, password fields) before either is accepted. Do not edit by hand: src/reference.spec.ts regenerates it and fails on a difference.

The embed plane (report section 7.1's second column): our customer's customer, in a browser, managing their own keys.

There is no tenant_id in this file, and there must never be one. Not in a path, not in a query, not in a body, not in a header. The tenant comes from the signed token and reaches the database through TenantScopedRepository, which has no method that takes one — that is what makes horizontal tenant escalation structurally impossible rather than a WHERE clause somebody has to remember. embed-isolation.spec.ts asserts it over the live route table, so a route added later is covered by construction rather than by review.

The same argument applies one level up and is why nothing here reads project_id or env either: all four scope columns come from the token.

GET /v1/embed/session

What the component renders its chrome from: whose keys these are, which environment, what this session may do, and when the token dies so the customer's getToken() can be called before it does.

Answers 200 on success.

Authentication.

  • An embed token minted by POST /v1/embed_tokens, bound to one tenant.

Example.

Request
curl https://keyring-api.belghalem.fr/v1/embed/session \
  -H "Authorization: Bearer $EMBED_TOKEN" \
  -H "Origin: https://app.acme.example"
Response
HTTP/1.1 200 OK
Content-Type: application/json

{
  "object": "embed_session",
  "project": {
    "id": "01a0ade7-b8fb-7711-bb1a-7d1bd5962995",
    "name": "Payments API",
    "slug": "payments-api"
  },
  "env": "test",
  "test_mode": true,
  "tenant": {
    "id": "01a0ade7-b909-7ae2-9477-aa287f446aad",
    "external_id": "cus_8f3k2",
    "name": "Globex Corporation"
  },
  "scopes": [
    "keys:read",
    "keys:write",
    "key_scope:orders:read"
  ],
  "expires_at": "2026-09-17T05:52:20.000Z",
  "expires_in": 300
}

GET /v1/embed/keys

Answers 200 on success.

Authentication.

  • An embed token minted by POST /v1/embed_tokens, bound to one tenant.

Query. Validated by this schema, from the control plane's own source:

const ListKeys = z.object({
  include_revoked: z
    .enum(['true', 'false'])
    .default('false')
    .transform((value) => value === 'true'),
  limit: z.coerce.number().int().min(1).max(100).default(50),
});

Example.

Request
curl https://keyring-api.belghalem.fr/v1/embed/keys \
  -H "Authorization: Bearer $EMBED_TOKEN" \
  -H "Origin: https://app.acme.example"
Response
HTTP/1.1 200 OK
Content-Type: application/json

{
  "object": "list",
  "data": [
    {
      "object": "api_key",
      "id": "01a0ade7-bae9-777c-a8d4-df6181e44b11",
      "project_id": "01a0ade7-b8fb-7711-bb1a-7d1bd5962995",
      "tenant_id": "01a0ade7-b909-7ae2-9477-aa287f446aad",
      "env": "test",
      "display_prefix": "kr_test_VB2fZo",
      "name": "Staging",
      "scopes": [
        "orders:read"
      ],
      "meta": {},
      "rate_limits": null,
      "expires_at": null,
      "revoked_at": null,
      "revoked_reason": null,
      "quarantined_at": null,
      "quarantine_reason": null,
      "rotated_from": null,
      "created_at": "2026-09-17T05:47:20.168Z",
      "last_used_at": null
    },
    {
      "object": "api_key",
      "id": "01a0ade7-b916-78a6-801e-79f4ba8233fb",
      "project_id": "01a0ade7-b8fb-7711-bb1a-7d1bd5962995",
      "tenant_id": "01a0ade7-b909-7ae2-9477-aa287f446aad",
      "env": "test",
      "display_prefix": "kr_test_KVME4u",
      "name": "CI",
      "scopes": [
        "orders:read",
        "orders:write"
      ],
      "meta": {},
      "rate_limits": null,
      "expires_at": null,
      "revoked_at": null,
      "revoked_reason": null,
      "quarantined_at": null,
      "quarantine_reason": null,
      "rotated_from": null,
      "created_at": "2026-09-17T05:47:19.700Z",
      "last_used_at": null
    }
  ]
}

POST /v1/embed/keys

Answers 201 on success.

Authentication.

  • An embed token minted by POST /v1/embed_tokens, bound to one tenant.

Body. Validated by this schema, from the control plane's own source:

const CreateKey = z.object({
  name: Name.optional(),
  scopes: Scopes.optional(),
});

Example.

Request
curl https://keyring-api.belghalem.fr/v1/embed/keys \
  -X POST \
  -H "Authorization: Bearer $EMBED_TOKEN" \
  -H "Origin: https://app.acme.example" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Staging",
    "scopes": [
      "orders:read"
    ]
  }'
Response
HTTP/1.1 201 Created
Content-Type: application/json

{
  "object": "api_key",
  "id": "01a0ade7-bae9-777c-a8d4-df6181e44b11",
  "project_id": "01a0ade7-b8fb-7711-bb1a-7d1bd5962995",
  "tenant_id": "01a0ade7-b909-7ae2-9477-aa287f446aad",
  "env": "test",
  "display_prefix": "kr_test_VB2fZo",
  "name": "Staging",
  "scopes": [
    "orders:read"
  ],
  "meta": {},
  "rate_limits": null,
  "expires_at": null,
  "revoked_at": null,
  "revoked_reason": null,
  "quarantined_at": null,
  "quarantine_reason": null,
  "rotated_from": null,
  "created_at": "2026-09-17T05:47:20.168Z",
  "last_used_at": null,
  "key": "kr_test_VB2fZo…",
  "key_shown_once": true
}

POST /v1/embed/keys/:id/rotate

Answers 200 on success.

Authentication.

  • An embed token minted by POST /v1/embed_tokens, bound to one tenant.

Path parameters. id.

Body. Validated by this schema, from the control plane's own source:

const RotateKey = z.object({
  overlap_hours: z.number().min(0).max(168).default(24),
});

Example.

Request
curl https://keyring-api.belghalem.fr/v1/embed/keys/01a0ade7-bae9-777c-a8d4-df6181e44b11/rotate \
  -X POST \
  -H "Authorization: Bearer $EMBED_TOKEN" \
  -H "Origin: https://app.acme.example" \
  -H "Content-Type: application/json" \
  -d '{
    "overlap_hours": 24
  }'
Response
HTTP/1.1 200 OK
Content-Type: application/json

{
  "object": "api_key",
  "id": "01a0ade7-baf5-7459-9f5e-bb2eb81bd93c",
  "project_id": "01a0ade7-b8fb-7711-bb1a-7d1bd5962995",
  "tenant_id": "01a0ade7-b909-7ae2-9477-aa287f446aad",
  "env": "test",
  "display_prefix": "kr_test_afB2o_",
  "name": "Staging",
  "scopes": [
    "orders:read"
  ],
  "meta": {},
  "rate_limits": null,
  "expires_at": null,
  "revoked_at": null,
  "revoked_reason": null,
  "quarantined_at": null,
  "quarantine_reason": null,
  "rotated_from": "01a0ade7-bae9-777c-a8d4-df6181e44b11",
  "created_at": "2026-09-17T05:47:20.179Z",
  "last_used_at": null,
  "key": "kr_test_afB2o_…",
  "key_shown_once": true,
  "previous_key": {
    "object": "api_key",
    "id": "01a0ade7-bae9-777c-a8d4-df6181e44b11",
    "project_id": "01a0ade7-b8fb-7711-bb1a-7d1bd5962995",
    "tenant_id": "01a0ade7-b909-7ae2-9477-aa287f446aad",
    "env": "test",
    "display_prefix": "kr_test_VB2fZo",
    "name": "Staging",
    "scopes": [
      "orders:read"
    ],
    "meta": {},
    "rate_limits": null,
    "expires_at": "2026-09-18T05:47:20.179Z",
    "revoked_at": null,
    "revoked_reason": null,
    "quarantined_at": null,
    "quarantine_reason": null,
    "rotated_from": null,
    "created_at": "2026-09-17T05:47:20.168Z",
    "last_used_at": null
  }
}

POST /v1/embed/keys/:id/revoke

Idempotent, for the same reason the control plane's revoke is.

Answers 200 on success.

Authentication.

  • An embed token minted by POST /v1/embed_tokens, bound to one tenant.

Path parameters. id.

Body. Validated by this schema, from the control plane's own source:

const RevokeKey = z.object({ reason: z.string().min(1).max(500).optional() });

Example.

Request
curl https://keyring-api.belghalem.fr/v1/embed/keys/01a0ade7-baf5-7459-9f5e-bb2eb81bd93c/revoke \
  -X POST \
  -H "Authorization: Bearer $EMBED_TOKEN" \
  -H "Origin: https://app.acme.example" \
  -H "Content-Type: application/json" \
  -d '{}'
Response
HTTP/1.1 200 OK
Content-Type: application/json

{
  "object": "api_key",
  "id": "01a0ade7-baf5-7459-9f5e-bb2eb81bd93c",
  "project_id": "01a0ade7-b8fb-7711-bb1a-7d1bd5962995",
  "tenant_id": "01a0ade7-b909-7ae2-9477-aa287f446aad",
  "env": "test",
  "display_prefix": "kr_test_afB2o_",
  "name": "Staging",
  "scopes": [
    "orders:read"
  ],
  "meta": {},
  "rate_limits": null,
  "expires_at": null,
  "revoked_at": "2026-09-17T05:47:20.186Z",
  "revoked_reason": null,
  "quarantined_at": null,
  "quarantine_reason": null,
  "rotated_from": "01a0ade7-bae9-777c-a8d4-df6181e44b11",
  "created_at": "2026-09-17T05:47:20.179Z",
  "last_used_at": null
}

GET /v1/embed/keys/:id/usage

Answers 200 on success.

Authentication.

  • An embed token minted by POST /v1/embed_tokens, bound to one tenant.

Path parameters. id.

Query. Validated by this schema, from the control plane's own source:

const Usage = z.object({
  days: z.coerce.number().int().min(1).max(90).default(30),
});

Example.

Request
curl https://keyring-api.belghalem.fr/v1/embed/keys/01a0ade7-b916-78a6-801e-79f4ba8233fb/usage?days=7 \
  -H "Authorization: Bearer $EMBED_TOKEN" \
  -H "Origin: https://app.acme.example"
Response
HTTP/1.1 200 OK
Content-Type: application/json

{
  "object": "usage",
  "key_id": "01a0ade7-b916-78a6-801e-79f4ba8233fb",
  "days": 7,
  "data": [
    {
      "day": "2026-09-17",
      "requests": 2,
      "errors": 0
    }
  ]
}

Shared validators

Defined once in packages/api/src/validation.ts and used by the schemas above.

const Name = z.string().min(1).max(200);
const Scopes = z.array(z.string().min(1).max(200)).max(64);

On this page