Decision (ratified 2026-07-21): live GitHub permission check, not a DB-backed allowlist. Query GitHub's real-time collaborator/permission API (is this login a repo owner or has admin/maintain permission on the specific repo) at each check site, mirroring the existing login === repoOwner pattern already used in src/review/linked-issue-label-propagation-fetch.ts and elsewhere. No new table, no admin UI to keep a list in sync.
Problem: A single global admin-login allowlist (ADMIN_GITHUB_LOGINS, src/auth/security.ts's parseGitHubLoginList) grants maintainer-equivalent trust across every repo in the deployment today — correctly representing "the one operator" for self-host, but there's no concept of a per-customer admin distinct from literal GitHub repo-owner permissions for a hosted model.
Area: ORB / Cloud. Confirmed live call sites of the allowlist check this replaces (for hosted deployments only — self-host keeps the simple global allowlist as its default): src/auth/security.ts (the parser itself), src/queue/processors.ts (6+ call sites), src/queue/review-evasion.ts (3 call sites), src/review/linked-issue-label-propagation-fetch.ts, src/review/visual/visual-followup.ts.
Deliverables:
Resources
src/auth/security.ts (parseGitHubLoginList, the pattern this replaces for hosted)
- Call sites above
src/review/linked-issue-label-propagation-fetch.ts (existing login === repoOwner precedent this mirrors)
Contributor-eligible. Decision is ratified above; this is now mechanical application of a decided pattern across the listed call sites, with an explicit fail-closed test requirement as the safety guardrail.
Decision (ratified 2026-07-21): live GitHub permission check, not a DB-backed allowlist. Query GitHub's real-time collaborator/permission API (is this login a repo owner or has admin/maintain permission on the specific repo) at each check site, mirroring the existing
login === repoOwnerpattern already used insrc/review/linked-issue-label-propagation-fetch.tsand elsewhere. No new table, no admin UI to keep a list in sync.Problem: A single global admin-login allowlist (
ADMIN_GITHUB_LOGINS,src/auth/security.ts'sparseGitHubLoginList) grants maintainer-equivalent trust across every repo in the deployment today — correctly representing "the one operator" for self-host, but there's no concept of a per-customer admin distinct from literal GitHub repo-owner permissions for a hosted model.Area: ORB / Cloud. Confirmed live call sites of the allowlist check this replaces (for hosted deployments only — self-host keeps the simple global allowlist as its default):
src/auth/security.ts(the parser itself),src/queue/processors.ts(6+ call sites),src/queue/review-evasion.ts(3 call sites),src/review/linked-issue-label-propagation-fetch.ts,src/review/visual/visual-followup.ts.Deliverables:
isPerTenantAdmin(login, repoFullName)-shaped helper calling GitHub's real-time permission API (e.g.GET /repos/{owner}/{repo}/collaborators/{username}/permission), used in place ofADMIN_GITHUB_LOGINSmembership at every hosted-deployment call site listed above.ADMIN_GITHUB_LOGINSallowlist) completely unchanged — this only applies to the hosted path.Resources
src/auth/security.ts(parseGitHubLoginList, the pattern this replaces for hosted)src/review/linked-issue-label-propagation-fetch.ts(existinglogin === repoOwnerprecedent this mirrors)Contributor-eligible. Decision is ratified above; this is now mechanical application of a decided pattern across the listed call sites, with an explicit fail-closed test requirement as the safety guardrail.