Skip to content

Sandbox: credential masking ineffective for  GH_TOKEN / GH_ENTERPRISE_TOKEN  on GHE Cloud data-residency tenants; token env vars are dropped before masking #5388

Open

Description

@PeterDaumQS

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

  1. 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.
  2.  gh  falls back to the stored login in  hosts.yml  and fails with  HTTP 401 … api..ghe.com/graphql .
  3. 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.
  4.  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

  1. 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.
  2. 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
  3. 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 .
  4. 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.
  5. 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.
  6. 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 .
  7. 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
  8. 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

  1. added theissue type on Nov 9, 2026
  2. self-assigned this
    on Nov 9, 2026
  3. added
    area:enterpriseGitHub Enterprise (GHE/GHES) support, org policies, and enterprise settings
    area:permissionsTool approval, security boundaries, sandbox mode, and directory restrictions
    and removed on Nov 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:enterpriseGitHub Enterprise (GHE/GHES) support, org policies, and enterprise settingsarea:permissionsTool approval, security boundaries, sandbox mode, and directory restrictions

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions