Skip to content

feat(orb): add a stored tenant-DB-credential secret type + generic revoke path to the token broker - #8080

Merged
JSONbored merged 1 commit into
mainfrom
broker-tenant-db-credential
Jul 22, 2026
Merged

feat(orb): add a stored tenant-DB-credential secret type + generic revoke path to the token broker#8080
JSONbored merged 1 commit into
mainfrom
broker-tenant-db-credential

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

Implements #8064, split from #7852 (itself split from #7180's provisioning core). Broker-side only — control-plane's own injectSecrets/revokeSecrets wiring against this is #8066, separately scoped and blocked on this PR.

  • ORB_SECRET_TYPE_TENANT_DB_CREDENTIAL: a stored (not minted) secret type — a credential the caller already has in hand (e.g. a hosted tenant's Postgres connection string) rather than the GitHub-token type's mint-on-exchange shape.
  • issueOrbStoredSecret encrypts and stores the value at issue time (new secret_value_ciphertext/iv/salt/version columns, mirroring repositories.ts's BYOK provider-key storage shape — not broker.ts's own cached_token_json, which is a TTL'd mint cache, a different thing from a permanently stored value). installation_id is always NULL on these rows: an AMS tenant has no GitHub installation at all, and even a hosted ORB tenant's installation lives in control-plane's own registry (Route incoming GitHub webhooks to the correct tenant's hosted ORB container #7181), not this table's orb_github_installations.
  • brokerOrbToken decrypts and returns the stored value verbatim on exchange — no installation-eligibility re-check, no cache, no re-mint, none of which apply to a value that isn't derived from a GitHub App.
  • revokeOrbEnrollment: a generic revoke path that works for any secret type. brokerOrbToken's revoked_at check has existed since Generalize src/orb/broker.ts into a multi-secret-type broker shared by ORB + AMS hosted #7174 but nothing has ever written to that column until now — this closes that gap. Idempotent: revoking an already-revoked enrollment succeeds without disturbing its original timestamp.
  • POST /v1/internal/orb/enrollments gains an optional { secretType: "tenant_db_credential", secretValue } body for the new issuance path; POST /v1/internal/orb/enrollments/:enrollId/revoke is the new admin-facing revoke route. Both sit behind the existing /v1/internal/* Bearer wall.
  • The GitHub-token type's existing behavior is completely unchanged — this is additive, not a rewrite.

Test plan

  • npx tsc --noEmit clean
  • npx tsx scripts/check-migrations.ts — contiguous, next free 0174
  • npx tsx scripts/check-schema-drift.ts clean (orb_enrollments is raw-SQL-allowlisted, no Drizzle schema to update)
  • npx tsx scripts/write-ui-openapi.ts --check clean (these are internal-only routes, not part of the public OpenAPI surface)
  • npx vitest run — full suite, 1091 files / 20359 tests, 0 failures (an unrelated pre-existing local worktree staleness in test/unit/mcp-cli-tools.test.ts/mcp-cli-maintain-tools.test.ts was resolved by rebuilding @loopover/mcp, confirmed present even on a clean origin/main before that rebuild — not caused by this change)
  • Targeted coverage on src/orb/broker.ts (100%/98.27%/100%/100% — the one branch gap is pre-existing, untouched code in readCachedOrbToken) and confirmed every changed line/branch in src/api/routes.ts's new route code is covered
  • npm audit --audit-level=moderate — no dependency changes in this PR

Closes #8064

…voke path to the token broker (#8064)

Adds ORB_SECRET_TYPE_TENANT_DB_CREDENTIAL to src/orb/broker.ts: a STORED (not
minted) secret type for a credential the caller already has in hand (e.g. a
hosted tenant's Postgres connection string, #7180's provisioning core) rather
than the GitHub-token type's mint-on-exchange shape. issueOrbStoredSecret
encrypts and stores the value at issue time (new secret_value_ciphertext/iv/
salt/version columns, same shape as repositories.ts's BYOK provider-key
storage); brokerOrbToken decrypts and returns it verbatim on exchange, with no
installation-eligibility re-check, cache, or re-mint -- none of which apply to
a value that isn't derived from a GitHub App. installation_id is always NULL
on these rows: an AMS tenant has no GitHub installation at all, and even a
hosted ORB tenant's installation lives in control-plane's own registry
(#7181), not this table's orb_github_installations.

Also adds revokeOrbEnrollment, a generic revoke path that works for ANY
secret type -- brokerOrbToken's existing revoked_at check (since #7174) has
always refused a revoked row, but nothing has ever written to that column
until now. Idempotent: revoking an already-revoked enrollment succeeds
without disturbing its original timestamp.

POST /v1/internal/orb/enrollments gains an optional
{ secretType: "tenant_db_credential", secretValue } body for the new
stored-secret issuance path; POST /v1/internal/orb/enrollments/:enrollId/revoke
is the new admin-facing revoke route. Both sit behind the existing
/v1/internal/* Bearer wall. The GitHub-token type's existing behavior is
completely unchanged -- this is additive.

Broker-side only: control-plane's own injectSecrets/revokeSecrets wiring
against this is #8066, a separate, blocked-on-this sub-issue of #7852.

Closes #8064
@JSONbored JSONbored self-assigned this Jul 22, 2026
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@codecov

codecov Bot commented Jul 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.98%. Comparing base (1026fb3) to head (84c2e31).
⚠️ Report is 3 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #8080   +/-   ##
=======================================
  Coverage   91.98%   91.98%           
=======================================
  Files         748      748           
  Lines       76617    76649   +32     
  Branches    23239    23249   +10     
=======================================
+ Hits        70474    70506   +32     
  Misses       5041     5041           
  Partials     1102     1102           
Flag Coverage Δ
shard-1 53.45% <6.06%> (-0.03%) ⬇️
shard-2 55.55% <6.06%> (-0.03%) ⬇️
shard-3 54.56% <100.00%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/api/routes.ts 95.23% <100.00%> (+0.01%) ⬆️
src/orb/broker.ts 98.57% <100.00%> (+0.65%) ⬆️

@loopover-orb loopover-orb Bot added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 22, 2026
@loopover-orb

loopover-orb Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Important

🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪

🔍 LoopOver is reviewing…

AI analysis is in progress. This comment will update when the review is complete.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed · 🟪 Reviewing

@JSONbored
JSONbored merged commit ed9e296 into main Jul 22, 2026
15 checks passed
@JSONbored
JSONbored deleted the broker-tenant-db-credential branch July 22, 2026 21:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a tenant-DB-credential secret type + generic revoke path to src/orb/broker.ts

1 participant