Part of #525. From the BYOK security audit.
requireSessionRepoAccess grants repo scope when the caller authored a PR with author_association OWNER/MEMBER/COLLABORATOR on an installed repo (src/services/control-panel-roles.ts ~250-252). MEMBER = org membership (not necessarily repo write); COLLABORATOR can include triage/read. For the secret-bearing ai-key POST/DELETE routes specifically, that's broader than ideal — a low-permission collaborator who opened one PR could set/replace/delete the repo's BYOK key.
Fix: for ai-key writes, require write-capable access — e.g. author_association === OWNER, or resolve real GitHub repo push permission via the installation, rather than inferring from PR author_association. Keep MEMBER/COLLABORATOR acceptable for the non-secret ai-review config. Avoid locking out legitimate write-collaborators.
Severity: low (privilege granularity; authenticated + repo-scoped already required).
Part of #525. From the BYOK security audit.
requireSessionRepoAccessgrants repo scope when the caller authored a PR with author_association OWNER/MEMBER/COLLABORATOR on an installed repo (src/services/control-panel-roles.ts ~250-252). MEMBER = org membership (not necessarily repo write); COLLABORATOR can include triage/read. For the secret-bearingai-keyPOST/DELETE routes specifically, that's broader than ideal — a low-permission collaborator who opened one PR could set/replace/delete the repo's BYOK key.Fix: for
ai-keywrites, require write-capable access — e.g. author_association === OWNER, or resolve real GitHub repo push permission via the installation, rather than inferring from PR author_association. Keep MEMBER/COLLABORATOR acceptable for the non-secretai-reviewconfig. Avoid locking out legitimate write-collaborators.Severity: low (privilege granularity; authenticated + repo-scoped already required).