From 7de3b409ed67a6b0d65dca65762089fe3a0d2d7c Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Fri, 21 Aug 2026 14:12:32 -0400 Subject: [PATCH] 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 --- docs/public/integrations/github.mdx | 1 + lib/apps/fabro-cli/src/commands/install.rs | 7 ++++++- lib/apps/fabro-server/src/install.rs | 18 +++++++++++++++++- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/public/integrations/github.mdx b/docs/public/integrations/github.mdx index a08185561..faa251dc9 100644 --- a/docs/public/integrations/github.mdx +++ b/docs/public/integrations/github.mdx @@ -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. diff --git a/lib/apps/fabro-cli/src/commands/install.rs b/lib/apps/fabro-cli/src/commands/install.rs index 973524899..2a3f401b4 100644 --- a/lib/apps/fabro-cli/src/commands/install.rs +++ b/lib/apps/fabro-cli/src/commands/install.rs @@ -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] diff --git a/lib/apps/fabro-server/src/install.rs b/lib/apps/fabro-server/src/install.rs index 5f7d9b05a..0fae34bbb 100644 --- a/lib/apps/fabro-server/src/install.rs +++ b/lib/apps/fabro-server/src/install.rs @@ -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");