Request Packages read permission in the GitHub App manifest

Fabro can mint a scoped sandbox GITHUB_TOKEN via
[run.integrations.github.permissions], but apps registered through the
manifest flow could not grant packages = "read" because the manifest
never requested it. Add Packages (read-only) so freshly registered apps
can download private GitHub Packages (for example npm registry
dependencies) inside sandboxes, mirroring how GitHub Actions workflows
use their built-in GITHUB_TOKEN for registry reads.

Existing apps still need the permission added manually in the app's
settings, as the docs already describe.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Bryan Helmkamp 2026-08-21 14:12:32 -04:00
parent 6e65e93a2f
commit 7de3b409ed
No known key found for this signature in database
3 changed files with 24 additions and 2 deletions

View file

@ -62,6 +62,7 @@ When you choose the GitHub App strategy, the CLI opens GitHub with a pre-filled
| Emails | Read | Read verified email for OAuth login |
| Dependabot alerts | Write | Read and manage repository vulnerability alerts |
| Organization projects | Write | Read and update organization Projects V2 |
| Packages | Read | Download private GitHub Packages (e.g. npm registry) with the sandbox `GITHUB_TOKEN` |
These permissions are included when Fabro registers a new app. For an existing GitHub App, add the missing permissions in the app's settings, then approve the permission update on each installation before workflows can use them.

View file

@ -950,7 +950,8 @@ fn build_github_app_manifest(app_name: &str, port: u16, web_url: &str) -> serde_
"issues": "write",
"emails": "read",
"vulnerability_alerts": "write",
"organization_projects": "write"
"organization_projects": "write",
"packages": "read"
},
"default_events": []
})
@ -2682,6 +2683,10 @@ client_id = "client-id"
manifest["default_permissions"]["organization_projects"],
serde_json::json!("write"),
);
assert_eq!(
manifest["default_permissions"]["packages"],
serde_json::json!("read"),
);
}
#[test]

View file

@ -2059,7 +2059,8 @@ fn build_github_app_manifest(
"issues": "write",
"emails": "read",
"vulnerability_alerts": "write",
"organization_projects": "write"
"organization_projects": "write",
"packages": "read"
},
"default_events": []
})
@ -2375,6 +2376,21 @@ mod tests {
);
}
#[test]
fn github_app_manifest_includes_packages_read_permission() {
let manifest = build_github_app_manifest(
"Fabro Test",
"https://fabro.example/setup",
"https://fabro.example/auth/callback/github",
"https://fabro.example/setup",
);
assert_eq!(
manifest["default_permissions"]["packages"],
serde_json::json!("read"),
);
}
#[test]
fn token_validation_accepts_any_matching_source() {
let state = InstallAppState::for_test("expected");