Skip to content

ADR-0005: BYOK Evolution — Pooled Org Credentials (Model 1)

Status: Accepted (2026-05-17) Author: Operator


Context

Blackrim Vox today is strictly per-operator BYOK: every user supplies their own ASR/TTS API keys (DEEPGRAM_API_KEY, ELEVENLABS_API_KEY, etc.) via environment variable or internal/authsource/byok/. This works well for individuals and small teams.

When an org adopts Vox enterprise via WorkOS SSO (see docs/research/workos-evaluation-2026-05.md §7), the BYOK-per-user model breaks down:

  • Enterprise IT cannot provision N separate Deepgram API keys per user.
  • Keys distributed to end users can leak; centrally-managed keys have narrower blast radius.
  • Per-user BYOK makes vendor billing attribution harder — Deepgram bills the org, Vox has to fan in usage metering to charge per-user.

Three evolutionary models were evaluated:

Model Description
1 — Pooled org creds Org admin sets one key at the IAM org level; all members use it. Simplest.
2 — Hybrid org + user override Org default cred with per-user override. Most flexible.
3 — Vault-managed Encrypted creds stored in an external secret store (WorkOS Vault, HashiCorp Vault, AWS SSM). Most enterprise-friendly.

Decision

Ship model 1 (pooled org credentials) first.

An org admin sets a named credential at the IAM org level via vox iam creds set <name>=<value>. All org members use it transparently. The existing per-operator env-var path is retained as the fallback, so single-user deployments are fully backward-compatible.

Design

  • New package internal/iam exposes the OrgCredentialStore interface with Get, Set, Delete, and List methods keyed by (orgID, name).
  • Two implementations: MemStore (in-process, used in tests and single-user mode) and a WorkOS-backed stub (WorkOSStore, usable once WorkOS is wired).
  • ASR/TTS Open() calls accept an optional "org_cred_store" + "org_id" in their config map. When set, key resolution becomes:
  • Explicit api_key in config (highest priority — test/automation override).
  • Org credential store (orgID + name).
  • Environment variable (backward-compat fallback).
  • CLI commands vox iam creds set and vox iam creds list require VOX_ORG_ADMIN=1 (the v1 admin gate; will be replaced by RBAC when WorkOS ships).

Backward compatibility

If no org_cred_store is configured, the existing env-var path is unchanged. All current single-user tests continue to pass without modification.


Consequences

Positive: - Enterprise IT provisions one Deepgram key per org instead of one per user. - Centrally-managed keys have narrower blast radius on credential leak. - Implementation is small (~200 LoC); no new external dependencies. - Clear upgrade path to model 2 (add per-user override layer to OrgCredentialStore).

Negative / trade-offs: - Usage attribution: Deepgram bills the pooled key; Vox must do its own per-user metering to apportion cost (tracked as a follow-up bd issue). - IAM coupling: ASR/TTS Open() now depends on the iam package. The dependency is optional (nil store = env-var fallback) so local builds stay lean. - WorkOS integration is stubbed — WorkOSStore is a placeholder that logs a warning and falls through to env-var. Real WorkOS storage wiring is deferred to the WorkOS Phase-4 epic (blackrim-vox-cop).


Rejected alternatives

Model 2 — Hybrid org + user override

Adds a user-level override layer on top of the org credential. Maps well to internal/authsource Capabilities (per-provider behavior). Rejected for v1 because: - More complex state machine (org default + user override resolution order). - No customer is asking for it yet; YAGNI until demand materializes. - Can be layered on top of model 1 without changing the interface.

Model 3 — Vault-managed credentials

External secret store (WorkOS Vault, HashiCorp Vault, AWS SSM) with encryption-at-rest managed outside Vox. Rejected for v1 because: - Requires a running external service in every environment, including dev. - WorkOS Vault is not yet in scope (pending the WorkOS sales call outcome). - HashiCorp Vault / AWS SSM add deployment complexity that is not justified until a compliance requirement surfaces (HIPAA BAA, SOC 2 type II). - Model 1 with internal/secrets.Encrypt at the persistence boundary already achieves at-rest encryption for the in-process store.


References

  • docs/research/workos-evaluation-2026-05.md §7 — BYOK-vs-org-creds tension
  • internal/iam/orgcreds.goOrgCredentialStore interface + implementations
  • internal/authsource/byok/byok.go — existing per-user BYOK source
  • blackrim-vox-7wz (implementation issue)
  • blackrim-vox-cop (WorkOS enterprise epic)