Repository navigation
feat: internal reveal endpoint for BYOK provider keys - #80
Merged
Merged
Conversation
POST /internal/organizations/{org_id}/provider-keys/{provider}/reveal
decrypts a stored BYOK key for one outbound provider API call --
shared-secret gated (PROVIDER_KEY_REVEAL_SECRET), the same
service-to-service shape POST /auth/api-keys/exchange already
established. Deliberately no org-membership check: the question this
answers is "does this organization have a key for this provider", not
"may this caller manage it" (manage_org still gates setting/clearing
the key). Called by omnibioai-api-gateway immediately before it
forwards a BYOK-routed /v1/literature/answers call to omnibioai-rag;
never persisted or logged by that caller.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Part of M16 (design audit gap #4: closing the full gap in one coordinated milestone -- paired PRs in omnibioai-rag and omnibioai-api-gateway do the actual Claude/OpenAI routing and token metering).
POST /internal/organizations/{org_id}/provider-keys/{provider}/revealdecrypts a stored BYOK key for one outbound provider API call -- shared-secret gated (PROVIDER_KEY_REVEAL_SECRET), the same service-to-service shapePOST /auth/api-keys/exchangealready established for the gateway/API-key flow.manage_orgdependency on this endpoint: the question it answers is "does this organization have a key for this provider," not "may this particular caller manage it" -- any authenticated member can trigger a BYOK-routed call using the org's own already-configured key, the same way any member can spend the org's quota today.manage_orgstill gates setting/clearing the key (unchanged from M14).exchange_api_keyalready leaves unaudited, for the identical reason./v1/literature/answerscall to omnibioai-rag; never persisted or logged by that caller.Security note worth a careful look: this is the first endpoint in this service that ever returns a decrypted credential in plaintext. Gated the same way the existing exchange endpoint is (shared secret, fail-closed when unset), but flagging explicitly since it's a new class of exposure, not an incremental extension of an existing one.
Test plan
pytest tests/test_organization_provider_keys.py-- 22 passed (14 existing + 8 new: disabled-without-secret, wrong/missing secret, correct decrypt round-trip, no-membership-required, 404 for unconfigured/mismatched provider, unsupported provider name, and a loud 500 rather than a silent failure when encryption isn't configured)pytest tests/test_route_authorization_coverage.py-- confirms the new route correctly sits outside the org-scoped-route tripwire (path doesn't start with/orgs, by design)🤖 Generated with Claude Code