Skip to content

Commit a019c60

Browse files
mjudeikisclaude
andcommitted
fix(code): request delete_repo scope so the provider can delete repos
GitHub's `repo` OAuth scope grants full control of private repositories but specifically excludes deletion, which requires the separate `delete_repo` scope. Tokens minted with the old default set could create repositories but every DELETE returned `403 Must have admin rights to Repository`, leaving Repository CRs stuck on their finalizer. Add `delete_repo` to the default scope set in the OAuth handler, the Helm values doc, and the README PAT/env guidance. Existing connections must re-authorize (OAuth) or swap to a `delete_repo`-capable PAT to pick up the broader scope. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 99629a7 commit a019c60

3 files changed

Lines changed: 9 additions & 5 deletions

File tree

providers/code/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,9 @@ lets `?tenant=` / `?token=` stand in for the hub-injected identity headers.
9595
## Connecting an account
9696

9797
- **Personal Access Token (default):** paste a PAT in the portal's Connections
98-
view. A classic PAT needs `repo` (+ `admin:public_key` for deploy keys,
99-
`read:org` for org repos, and **`read:packages`** for the repo Packages panel).
98+
view. A classic PAT needs `repo` (+ `delete_repo` to remove provider-created
99+
repositories, `admin:public_key` for deploy keys, `read:org` for org repos,
100+
and **`read:packages`** for the repo Packages panel).
100101
- **Connect with GitHub (OAuth):** enable the OAuth App (below) and the portal
101102
shows a one-click button — no copy-paste. OAuth tokens are requested with
102103
`read:packages` by default so the Packages panel works out of the box.
@@ -306,7 +307,7 @@ the connection token's `read:packages` scope.
306307
| `GITHUB_OAUTH_CLIENT_SECRET` | (unset) | GitHub OAuth App client secret |
307308
| `GITHUB_OAUTH_REDIRECT_URL` | (unset) | Absolute callback URL (must end in `/callback`); either the hub `/services/providers/code/oauth/github/callback` proxy route or the provider's own host. `/start` is derived from it |
308309
| `GITHUB_OAUTH_PORTAL_ORIGIN` | `*` | postMessage target origin (set to the hub origin in prod) |
309-
| `GITHUB_OAUTH_SCOPES` | `repo,read:org,admin:public_key,read:packages` | Requested OAuth scopes |
310+
| `GITHUB_OAUTH_SCOPES` | `repo,delete_repo,read:org,admin:public_key,read:packages` | Requested OAuth scopes |
310311

311312
### `init` subcommand
312313

providers/code/deploy/chart/values.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ githubOAuth:
6666
# origin). Empty broadcasts to "*" — set this in production.
6767
portalOrigin: ""
6868
# Comma-separated scopes. Empty → provider default
69-
# (repo,read:org,admin:public_key,read:packages).
69+
# (repo,delete_repo,read:org,admin:public_key,read:packages). delete_repo is
70+
# required for the provider to remove repositories it created.
7071
scopes: ""
7172

7273
# Tenant credential resolution. Empty → the provider default ("default"), the

providers/code/oauthgithub/oauth.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@ func FromEnv() (cfg Config, enabled bool, err error) {
100100
scopes := os.Getenv("GITHUB_OAUTH_SCOPES")
101101
if scopes == "" {
102102
// read:packages lets the portal list the packages published under a repo.
103-
scopes = "repo,read:org,admin:public_key,read:packages"
103+
// delete_repo is required to remove repositories the provider created;
104+
// the `repo` scope alone grants full control but NOT deletion.
105+
scopes = "repo,delete_repo,read:org,admin:public_key,read:packages"
104106
}
105107
for _, s := range strings.Split(scopes, ",") {
106108
if s = strings.TrimSpace(s); s != "" {

0 commit comments

Comments
 (0)