ShrubberyDocs
Sign in

BYOK Provider Keys

Overview

BYOK ("Bring Your Own Key") is the rule that every AI feature in Shrubbery — today only Smart Paste extraction — runs on the user's own provider key (OpenAI / Anthropic / Gemini). The platform never trains on user data and never falls back to a platform-side key. This guide walks the lifecycle: mint at the provider, store in the Vault, use via the Squire, rotate, clear.

Actors

  • Lead (or any user with AI features) — mints the key at the AI provider, stores and rotates it inside Shrubbery.
  • Squire — the only consumer of stored BYOK keys. The Squire resolves the key server-side at call time; the plaintext never leaves the server boundary toward the browser.
  • Provider (OpenAI / Anthropic / Gemini) — the upstream API the Squire calls. The provider sees the user's key, not Shrubbery's.

Flow

  1. Lead mints a key at the AI provider (e.g. sk-... at OpenAI).
  2. Lead opens Settings → BYOK and pastes the key with the provider selector set. The form submits to a server action that calls set_byok_key() — the RPC writes an envelope-encrypted entry into Supabase Vault and stores the secret UUID + provider + last-4 fingerprint on public.users. Plaintext is never persisted on the application table.
  3. Lead triggers a Smart Paste — the Squire server action calls read_byok_key(provider), which returns the decrypted key in-memory for the duration of the /api/gather request.
  4. The Squire calls the provider with the plaintext key, gets the structured extraction, returns to the UI. The plaintext is never written to logs, never sent to the browser, and is dropped from memory after the request.
  5. Lead rotates — pastes a new key in the same form; the old Vault secret is deleted and the new one written. Audit event: byok_key_rotated.
  6. Lead clears — Settings → BYOK → Clear key. RPC clear_byok_key() deletes the Vault row and nulls the columns on public.users. Audit event: byok_key_cleared. The next Smart Paste returns a clear error directing the Lead back to BYOK settings.

Edge cases

  • Expired or revoked provider key — Squire surfaces the provider's 401 verbatim and prompts the Lead to rotate. The Draft is not created.
  • Wrong provider selector — e.g. an Anthropic key stored under OpenAI. The Squire's first request fails with a provider-side 401; no silent fallback.
  • Two users in the same org — each mints their own key. There is no org-level shared key; this is intentional, since billing and rate-limit lives with the user.
  • Vault encryption rotation — Supabase Vault handles key rotation transparently; the application code does not need to re-encrypt.
  • Self-handshake demo / solo Lead — the same user is Lead and Knight; BYOK still applies to the Smart Paste step on the Lead side. The Knight side has no AI dependency.

Last updated: 17 May 2026