POST /api/v1/admin/orgs/:slug/oidc-bindings
This page is auto-generated from
src/admin/routes.ts. Do not edit by hand — seedocs/dev/docs-auto-sync.md.
:warning: Heuristic extraction — not a contract. Response shapes below are mined from
c.json(...)literals in the handler via an AST walker. Computed fields, ternaries, and non-literal returns are shown as placeholders. Refer to the linked source file for the authoritative behaviour.
POST /api/v1/admin/orgs/:slug/oidc-bindings
Section titled “POST /api/v1/admin/orgs/:slug/oidc-bindings”Authentication
Section titled “Authentication”Requires the following capability(ies):
oidc:w
Middleware
Section titled “Middleware”Other middleware observed on this route (heuristic):
requireCapabilityadminBodyLimit
Description
Section titled “Description”POST /api/v1/admin/orgs/:slug/oidc-bindings — create a binding. Body: { “issuer”: “https://token.actions.githubusercontent.com”, “sub_pattern”: “repo:acme/payments:ref:refs/heads/main”, “repository_id”: “12345”, “event_names”: [“pull_request”, “push”], “origin”: “org_admin” | “team_admin”, “project_id”?: ”…”, “team_id”?: ”…” // required iff origin = team_admin }
Validation:
- issuer MUST be in the static allowlist (src/auth/oidc/issuers.ts).
- sub_pattern is required (non-empty, no whitespace).
- repository_id is required when the issuer config sets requiresRepositoryId (GH Actions: true).
- event_names entries must be strings; empty array = any event.
- origin MUST be in OIDC_BINDING_ORIGINS minus ‘platform_admin’ on the customer-facing surface.
- team_admin origin requires team_id; the team must belong to this tenant. The origin-envelope check (does an org_admin binding cover the proposed sub+repo?) lands here too.
Conflicts: the unique partial index on (tenant_id, issuer, sub_pattern, COALESCE(repository_id, ”)) WHERE revoked_at IS NULL turns a duplicate create into a 409 — the existing active binding stays in place.
Responses
Section titled “Responses”HTTP 404
Section titled “HTTP 404”{ "error": "Org not found"}HTTP 400
Section titled “HTTP 400”{ "error": "Invalid JSON body"}HTTP 400
Section titled “HTTP 400”{ "error": "Body must be a JSON object"}HTTP 400
Section titled “HTTP 400”{ "error": "issuer is required (string)"}HTTP 400
Section titled “HTTP 400”{ "error": <template-string>}HTTP 400
Section titled “HTTP 400”{ "error": "sub_pattern is required (string)"}HTTP 400
Section titled “HTTP 400”{ "error": "sub_pattern must be 1..1024 chars with no whitespace / control characters"}HTTP 400
Section titled “HTTP 400”{ "error": "repository_id must be a positive integer string"}HTTP 400
Section titled “HTTP 400”{ "error": "repository_id must be a positive integer or its string form"}HTTP 400
Section titled “HTTP 400”{ "error": "event_names must be an array of strings"}HTTP 400
Section titled “HTTP 400”{ "error": "every event_names entry must be a non-whitespace 1..64-char string"}HTTP 400
Section titled “HTTP 400”{ "error": "origin is required (string)"}HTTP 400
Section titled “HTTP 400”{ "error": "origin must be 'org_admin' or 'team_admin' on this surface"}HTTP 400
Section titled “HTTP 400”{ "error": "project_id must be a string"}HTTP 400
Section titled “HTTP 400”{ "error": "project_id not found for this org"}HTTP 400
Section titled “HTTP 400”{ "error": "team_id must be a string"}HTTP 400
Section titled “HTTP 400”{ "error": "team_id not found for this org"}HTTP 400
Section titled “HTTP 400”{ "error": "team_id is required for origin=team_admin"}HTTP 400
Section titled “HTTP 400”{ "error": "team_admin binding falls outside any active org_admin envelope — ask an org admin to expand the trust envelope first"}HTTP 201
Section titled “HTTP 201”Shape not a JSON literal — passed through from a variable or expression. See source.
HTTP 409
Section titled “HTTP 409”{ "error": "An active binding already exists for this (issuer, sub, repository_id)"}Source
Section titled “Source”- File:
src/admin/routes.ts - Line: 6394