Repository navigation
Description
Describe the bug
Version / environment
• Copilot CLI 1.0.106, Linux, started with --sandbox --yolo
• GitHub Enterprise Cloud with data residency ( .ghe.com ), repository hosted on that tenant
- In the sandboxed shell only GH_HOST is set. GH_TOKEN , GH_ENTERPRISE_TOKEN , COPILOT_GITHUB_TOKEN and GITHUB_TOKEN are absent, with no sentinels, despite being configured for masking.
- gh falls back to the stored login in hosts.yml and fails with HTTP 401 … api..ghe.com/graphql .
- A token under a neutral name ( MY_GHE_TOKEN , same injectHosts ) arrives as a sentinel (length 40). curl -H "Authorization: token $MY_GHE_TOKEN" https://api..ghe.com/user returns 200 , so masking itself works.
- GH_TOKEN="$MY_GHE_TOKEN" gh issue list works. GH_ENTERPRISE_TOKEN="$MY_GHE_TOKEN" gh issue list still returns 401, so gh in the sandbox does not use GH_ENTERPRISE_TOKEN for *.ghe.com hosts.
COPILOT_GITHUB_TOKEN is set to a different GHE , as this one provides the access to a copilot license.
Suspected cause
The "fixed blocklist" for the sandbox environment appears to remove GitHub token variable names before masking is applied. The blocklist's contents are not documented. The note "must exist in the final child environment" explains the effect but not which names are affected. This is inferred, not confirmed. The observations above are measured.
Suggestions
• Document the blocklist in copilot help sandbox .
• Do not filter variables that are configured in credentials.envVars , or warn at startup that a configured variable is missing after filtering.
• Support automatic masking for GHE tenants via GH_TOKEN / GH_ENTERPRISE_TOKEN and GH_HOST , not only GITHUB_TOKEN on github.com .
• Clarify how GH_HOST , GH_ENTERPRISE_TOKEN and the tenant credential interact.
Workaround
Pass the token under a custom name, list it in credentials.envVars with injectHosts , and call GH_TOKEN="$MY_GHE_TOKEN" gh … .
Affected version
1.0.106, Linux
Steps to reproduce the behavior
- Prerequisites: a GitHub Enterprise Cloud data-residency tenant ( .ghe.com ), a repository on it, and a valid PAT for that tenant. Use a Linux host with sandbox prerequisites installed.
- Start Copilot CLI from a shell, passing the token under several names:
GH_HOST=.ghe.com
GH_TOKEN="$PAT"
GH_ENTERPRISE_TOKEN="$PAT"
COPILOT_GITHUB_TOKEN="$PAT"
MY_GHE_TOKEN="$PAT"
copilot --sandbox --yolo - In /sandbox → Credentials:
• Enable Authenticate gh.
• Under Masked environment variables, add GH_TOKEN , GH_ENTERPRISE_TOKEN , COPILOT_GITHUB_TOKEN and MY_GHE_TOKEN , each with the injection hosts .ghe.com and api..ghe.com . - Restart Copilot CLI so the settings take effect, then ask the agent to run:
env | grep -E '^(GH_HOST|GH_TOKEN|GH_ENTERPRISE_TOKEN|COPILOT_GITHUB_TOKEN|GITHUB_TOKEN|MY_GHE_TOKEN)='
| awk -F= '{print $1": set, length "length($2)}'
Observed: only GH_HOST and MY_GHE_TOKEN (sentinel, length 40) are listed. GH_TOKEN , GH_ENTERPRISE_TOKEN and COPILOT_GITHUB_TOKEN are missing. Expected: all four configured variables are present as sentinels. - Run:
gh issue list -R / --state open
Observed: HTTP 401: Must authenticate to access this API. (https://api..ghe.com/graphql) . gh auth status reports the stored hosts.yml token as invalid. Expected: the issue list. - Confirm masking works for the neutral name:
curl -sS -o /dev/null -w '%{http_code}\n'
-H "Authorization: token $MY_GHE_TOKEN" https://api..ghe.com/user
Observed: 200 . - Compare gh with each variable name:
GH_TOKEN="$MY_GHE_TOKEN" gh issue list -R / # works
GH_ENTERPRISE_TOKEN="$MY_GHE_TOKEN" gh issue list -R / # 401 - For comparison, run the same gh issue list in a session started without --sandbox . It works with the same environment, which points to the sandbox and not to the token.
Expected behavior
Per copilot help sandbox , selected variables are replaced with sentinels and the local proxy injects the real value for approved hosts. gh issue list -R / should work against the tenant.
Additional context
No response
Activity