@@ -157,6 +157,7 @@ function githubCredentials(args: string[]): {
157157 mode ?: 'app' | 'token' ;
158158 repositoryRouting ?: boolean ;
159159 checkoutRouting ?: boolean ;
160+ installationTokenScope ?: boolean ;
160161 policyIdentity : string ;
161162} {
162163 const token = nonEmpty ( process . env . LIBRECHAT_CODE_GITHUB_TOKEN ) ;
@@ -191,6 +192,18 @@ function githubCredentials(args: string[]): {
191192 'Checkout GitHub repository routing requires a GitHub App without a fixed installation ID' ,
192193 ) ;
193194 }
195+ const tokenScope =
196+ option ( args , '--github-token-scope' ) ?. trim ( ) . toLowerCase ( ) ??
197+ process . env . LIBRECHAT_CODE_GITHUB_TOKEN_SCOPE ?. trim ( ) . toLowerCase ( ) ??
198+ 'repository' ;
199+ if ( tokenScope !== 'repository' && tokenScope !== 'installation' ) {
200+ throw new Error ( 'GitHub token scope must be repository or installation' ) ;
201+ }
202+ if ( tokenScope === 'installation' && ( ! hasApp || installationId ) ) {
203+ throw new Error (
204+ 'Installation-scoped GitHub tokens require a GitHub App without a fixed installation ID' ,
205+ ) ;
206+ }
194207 const configuredHostValue = nonEmpty (
195208 process . env . LIBRECHAT_CODE_GITHUB_HOST ,
196209 ) ;
@@ -225,16 +238,19 @@ function githubCredentials(args: string[]): {
225238 mode : 'app' ,
226239 repositoryRouting : ! installationId ,
227240 checkoutRouting : routing === 'checkout' ,
241+ installationTokenScope : tokenScope === 'installation' ,
228242 policyIdentity : gitHubAuthenticationPolicyIdentity ( {
229243 mode : 'app' ,
230244 host,
231245 appId,
232246 installationId,
233- } ) + ( routing === 'checkout' ? ':routing:checkout' : '' ) ,
247+ } ) + ( routing === 'checkout' ? ':routing:checkout' : '' ) +
248+ ( tokenScope === 'installation' ? ':scope:installation' : '' ) ,
234249 privateKeyPath,
235250 provider : new GitHubAppCredentialProvider ( {
236251 appId : appId ! ,
237252 installationId,
253+ tokenScope,
238254 privateKeyPath : privateKeyPath ! ,
239255 host,
240256 apiUrl,
@@ -568,6 +584,11 @@ async function run(
568584 'Checkout GitHub repository routing requires the trusted-vm command policy' ,
569585 ) ;
570586 }
587+ if ( github . installationTokenScope && commandPolicy . preset !== 'trusted-vm' ) {
588+ throw new Error (
589+ 'Installation-scoped GitHub tokens require the trusted-vm command policy' ,
590+ ) ;
591+ }
571592 const githubDomains = github . provider
572593 ? github . host === 'github.com'
573594 ? [ ...GITHUB_ALLOWED_DOMAINS ]
0 commit comments