From 8c370517cdfb449c094dbaef69a8bb3c4dc0d54c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 3 Sep 2026 04:41:45 +0000 Subject: [PATCH] docs(auth): document Copilot fine-grained PAT auth-prefix override and GITHUB_COPILOT_INTEGRATION_ID fallback Corrects docs/auth-matrix.md and docs/environment.md to reflect PR #8038 (Fix Copilot proxy auth and GHEC model discovery, merged 2026-09-02): - COPILOT_GITHUB_TOKEN values starting with github_pat_ (fine-grained PATs) now always use the Bearer auth prefix on every Copilot target (github.com, GHEC, GHES, Business), overriding the previous target-based token/Bearer selection that still applies to classic PATs and OAuth tokens. - Copilot-Integration-Id now also falls back to GITHUB_COPILOT_INTEGRATION_ID when COPILOT_INTEGRATION_ID is unset. - Cross-referenced the stronger fine-grained-PAT guarantee from the existing Classic PAT + COPILOT_MODEL remediation guidance in docs/environment.md. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/auth-matrix.md | 15 +++++++++------ docs/environment.md | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/auth-matrix.md b/docs/auth-matrix.md index 855d896dd..c5da1121f 100644 --- a/docs/auth-matrix.md +++ b/docs/auth-matrix.md @@ -169,9 +169,11 @@ AWF follows Anthropic's SDK behavior: JWT-bearer `POST /v1/oauth/token` exchange :::note[Implementation vs. provider documentation] GitHub's [REST API authentication docs](https://docs.github.com/en/rest/authentication/authenticating-to-the-rest-api) state that both Bearer-prefixed and token-prefixed Authorization headers are generally accepted for PATs/OAuth tokens (only JWTs strictly require Bearer). The `token` prefix requirement documented here is **AWF-implementation-specific defensive behavior** for Copilot API requests, not a general GitHub REST API rule: the derived GHEC data-residency target (`copilot-api..ghe.com`), the enterprise target (`api.enterprise.githubcopilot.com`), and the business target (`api.business.githubcopilot.com`) return `400 Bad Request: Authorization header is badly formatted` when sent the wrong prefix (see the regression fixed in [PR #6991](https://github.com/github/gh-aw-firewall/pull/6991) and covered by `copilot-adapter-enterprise.test.js`). AWF detects this via `copilotTargetRequiresGitHubTokenPrefix()` in `copilot-auth.js`, which matches on the specific target hostname (including an `isGhecCopilotApiTarget()` check for the `copilot-api..ghe.com` shape) or GHES-detection heuristics (`AWF_PLATFORM_TYPE=ghes`, or a `GITHUB_SERVER_URL` that isn't `github.com`/`*.ghe.com`). BYOK keys always use the `Bearer` prefix regardless of target. + +**Fine-grained PAT override:** As of [PR #8038](https://github.com/github/gh-aw-firewall/pull/8038), `COPILOT_GITHUB_TOKEN` values that start with `github_pat_` (fine-grained PATs) always use the `Bearer` prefix, on every Copilot target including GHEC/GHES/Business — they never fall back to `token `, even where classic PATs and OAuth tokens on those targets require it. This override lives in `getGitHubTokenAuthPrefix()` in `copilot-auth.js` and is covered by `copilot-adapter-enterprise.test.js` and `copilot-auth.test.js`. ::: -Copilot API host requests also include `Copilot-Integration-Id`. The default is `agentic-workflows`; set `COPILOT_INTEGRATION_ID` to override it. +Copilot API host requests also include `Copilot-Integration-Id`. The default is `agentic-workflows`; set `COPILOT_INTEGRATION_ID` to override it, or set `GITHUB_COPILOT_INTEGRATION_ID` as a fallback (checked only when `COPILOT_INTEGRATION_ID` is unset) — added in [PR #8038](https://github.com/github/gh-aw-firewall/pull/8038). ### Prompt-cache and attribution headers (`*.githubcopilot.com` only) @@ -180,7 +182,7 @@ When the resolved upstream host is a Copilot host (`githubcopilot.com` or a `*.g | Header | Value | Purpose | |--------|-------|---------| | `X-Interaction-Id` | `${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}`, else a UUID minted once per sidecar process | CAPI prompt-cache key — must be stable for a whole run and differ across runs | -| `Copilot-Integration-Id` | `COPILOT_INTEGRATION_ID`, else `agentic-workflows` | Attribution, quota bucket, and model allowlist | +| `Copilot-Integration-Id` | `COPILOT_INTEGRATION_ID`, else `GITHUB_COPILOT_INTEGRATION_ID`, else `agentic-workflows` | Attribution, quota bucket, and model allowlist | Non-empty inbound values are preserved; empty values and case-variant duplicates are replaced so exactly one instance of each header reaches CAPI. Harnesses that do not send a stable `X-Interaction-Id` themselves (aider, Pi, …) therefore still get prompt-cache hits, and a harness that owns its own session identity can override the value simply by sending the header. There is no AWF-specific override env var for `X-Interaction-Id`: outside GitHub Actions the sidecar mints one UUID per process. Neither header is injected on non-Copilot hosts, so BYOK targets (Azure OpenAI, OpenRouter, …) and the OpenAI/Anthropic/Gemini providers are unaffected. @@ -401,13 +403,14 @@ GITHUB_SERVER_URL → deriveCopilotApiTarget(): | Target | Credential Type | Auth Header Format | |--------|----------------|-------------------| | `api.githubcopilot.com` | GitHub token | `Bearer ` | -| `copilot-api.*.ghe.com` | GitHub token | `token ` | -| `api.enterprise.githubcopilot.com` | GitHub token | `token ` | -| `api.business.githubcopilot.com` | GitHub token | `token ` | +| `copilot-api.*.ghe.com` | GitHub token (classic PAT/OAuth) | `token ` | +| `api.enterprise.githubcopilot.com` | GitHub token (classic PAT/OAuth) | `token ` | +| `api.business.githubcopilot.com` | GitHub token (classic PAT/OAuth) | `token ` | +| Any target | GitHub token (fine-grained PAT, `github_pat_*`) | `Bearer ` (always, since [PR #8038](https://github.com/github/gh-aw-firewall/pull/8038)) | | Any target | BYOK key | `Bearer ` (always) | | Any target | OIDC token | `Bearer ` (always) | -The `token` prefix is used for GitHub OAuth tokens on the derived GHEC data-residency, enterprise, and business Copilot targets, or when GHES is otherwise detected (see `copilotTargetRequiresGitHubTokenPrefix()` in `copilot-auth.js`). BYOK and OIDC always use the standard prefix. As noted above, this is AWF-implementation-specific behavior driven by observed `400` errors from those targets — not a general GitHub REST API requirement. +The `token` prefix is used for classic PAT/OAuth GitHub tokens on the derived GHEC data-residency, enterprise, and business Copilot targets, or when GHES is otherwise detected (see `copilotTargetRequiresGitHubTokenPrefix()` in `copilot-auth.js`). BYOK and OIDC always use the standard prefix. As noted above, this is AWF-implementation-specific behavior driven by observed `400` errors from those targets — not a general GitHub REST API requirement. Fine-grained PATs (`github_pat_*`) are detected via `getGitHubTokenAuthPrefix()` and always use `Bearer `, overriding the target-based rule above. --- diff --git a/docs/environment.md b/docs/environment.md index 7e3e6577c..4eb1a056f 100644 --- a/docs/environment.md +++ b/docs/environment.md @@ -121,7 +121,7 @@ Copilot CLI 1.0.21 introduced a startup model validation step: when `COPILOT_MOD ``` **Remediation options:** -1. Replace the classic PAT with a **fine-grained PAT** or **OAuth token** (these are accepted by the `/models` endpoint). +1. Replace the classic PAT with a **fine-grained PAT** or **OAuth token** (these are accepted by the `/models` endpoint). Since [PR #8038](https://github.com/github/gh-aw-firewall/pull/8038), fine-grained PATs (`github_pat_*`) always authenticate to every Copilot target (github.com, GHEC, GHES, Business) with the standard `Bearer` prefix, unlike classic PATs/OAuth tokens which require a `token` prefix on enterprise/GHEC/business targets — see [docs/auth-matrix.md](auth-matrix.md#auth-header-prefix-rules). 2. Remove `COPILOT_MODEL` from the agent environment to skip model validation entirely. ## Anthropic WIF environment notes