External MCP Service-Key Policy (ENG-6796, P2.5) — RETIRED (ENG-7010) #
Classification: Restricted (describes source code, infrastructure, and access control).
This design was retired before any service key was ever issued. tofu-external-mcp is JWT-only (Clerk OAuth pass-through) end to end now — the Tofu-API-Key credential path described below no longer exists in the codebase: src/service-key-policy.ts is deleted, src/middleware/auth.ts has no API-key branch, src/auth-context.ts has no apiKey/getApiKey, and no tool declares a service-key-compatible operation. The rest of this page is kept as a historical record of the design that was implemented and then removed — do not use it as current documentation.
What a service key was going to be #
A bonsapi ApiKey (the same row/HMAC-digest mechanism the customer-facing “API keys” org settings page already creates via createApiKey), presented on the Tofu-API-Key header instead of a Clerk-issued Authorization: Bearer token. bonsapi’s BonsaiUserOrApiKey / BonsaiUserInEntityOrApiKey extractors (apps/bonsapi/src/model/app/bonsai_user.rs) accept either credential; a plain BonsaiUser / BonsaiUserInEntity extractor accepts only the Clerk header — that bonsapi-side extractor split is unaffected by this retirement, only tofu-external-mcp’s own use of it was removed.
An API-key-authenticated request would have gotten permissions = all_access() and skipped entity-scoping entirely on bonsapi’s side — a key acts org-wide, never per-user.
Credential map (historical — ENG-6768, verified 2026-07-22 against main)
#
168/168 external.yaml operations mapped. Exactly 8 were API-key-compatible; every other mapped operation was JWT-only.
| Endpoint | Method | operationId | MCP tool at the time |
|---|---|---|---|
/api/v1/documents |
POST | createDocument |
none yet |
/api/v1/documents |
GET | getDocuments |
list_documents |
/api/v1/documents/stale |
GET | getStaleDocuments |
none yet |
/api/v1/documents/{documentId} |
GET | getDocument |
get_document |
/api/v1/documents/{documentId}/download |
GET | downloadDocumentFile |
download_document_file |
/api/v1/documents/{documentId}/metadata |
GET | getDocumentMetadata |
none yet |
/api/v1/entities |
GET | getEntities |
none yet |
/api/v1/entities/{entityId} |
GET | getEntity |
none yet |
Why it was removed #
No headless consumer ever appeared and no key was ever issued (zero live traffic throughout this design’s lifetime — see the Issuance policy note below). ENG-7010 simplified the server to a single JWT-only auth model rather than carry an unused second credential path and its policy-gate/allowlist maintenance burden.
Issuance policy (as designed — never executed) #
- Super-user issued. Would have been created via bonsapi’s existing
createApiKeyendpoint by BonsAI ops/engineering, not by an end-user org’s own admin. - Named per purpose. The
namefield passed tocreateApiKeywould identify the consumer, not a person. - Stored and rotated in Doppler, under the
TOFU_EXTERNAL_MCP_*prefix. - Never handed to end users.
- First key was to be issued only when a headless consumer actually appeared — that never happened.