* fix(auth): preserve Copilot tenant credentials during Doctor repair * test(auth): split Copilot ownership cases below file-size limit * docs(copilot): clarify tenant credential sharing Document that agents share Copilot credentials only when supported tenant scopes match, and direct affected agents to authenticate for their intended tenant. Co-authored-by: VasuBansal <148481383+VasuBansal7576@users.noreply.github.com> * fix(auth): preserve Copilot tenant fences during peer settlement Require refreshed shared Copilot credentials to match the fenced peer's normalized routing scope before local fence removal. Cross-tenant peers remain terminally fenced. Co-authored-by: VasuBansal <148481383+VasuBansal7576@users.noreply.github.com> * fix(auth): preserve Copilot tenant scope in ownership Require Copilot OAuth ownership to validate normalized routing scope before accepting an identical refresh generation. Same-tenant peers keep the shared owner shortcut while cross-tenant credentials remain locally owned. Co-authored-by: VasuBansal <148481383+VasuBansal7576@users.noreply.github.com> * test(gateway): await plugin application receipt * test(gateway): await node terminal events --------- Co-authored-by: Peter Steinberger <steipete@gmail.com> Co-authored-by: VasuBansal <148481383+VasuBansal7576@users.noreply.github.com>
16 KiB
summary, read_when, title
| summary | read_when | title | |||
|---|---|---|---|---|---|
| Sign in to GitHub Copilot from OpenClaw using the device flow or non-interactive token import |
|
GitHub Copilot |
GitHub Copilot is GitHub's AI coding assistant. It provides access to Copilot models for your GitHub account and plan. OpenClaw can use Copilot as a model provider or agent runtime in three different ways.
Three ways to use Copilot in OpenClaw
Use the native device-login flow to obtain a GitHub token. By default, OpenClaw puts the token in its protected local secret store and saves only a `tokenRef` in the auth profile. When OpenClaw runs, it validates Copilot access and resolves the account-specific Copilot API endpoint. This is the **default** and simplest path because it does not require VS Code.<Steps>
<Step title="Run the login command">
```bash
openclaw models auth login-github-copilot
```
You will be prompted to visit a URL and enter a one-time code. Keep the
terminal open until it completes.
</Step>
<Step title="Set a default model">
```bash
openclaw models set github-copilot/claude-sonnet-5
```
Or in config:
```json5
{
agents: {
defaults: { model: { primary: "github-copilot/claude-sonnet-5" } },
},
}
```
</Step>
</Steps>
```bash
openclaw plugins install @openclaw/copilot
```
Then opt a model or provider into the runtime:
```json5
{
agents: {
defaults: {
model: "github-copilot/gpt-5.6-sol",
models: {
"github-copilot/gpt-5.6-sol": {
agentRuntime: { id: "copilot" },
},
},
},
},
}
```
Choose this when you want native Copilot CLI sessions, SDK-managed thread
state, and Copilot-owned compaction for those agent turns. Without the
explicit `agentRuntime` opt-in, `github-copilot/*` models keep using the
built-in provider. See [Copilot SDK harness](/plugins/copilot) for the full
runtime contract.
The `copilot-proxy` plugin ships with OpenClaw and is enabled by default.
Configure the base URL and model ids with:
```bash
openclaw models auth login --provider copilot-proxy --set-default
```
<Note>
Choose this when you already run Copilot Proxy in VS Code or need to route
through it. The VS Code extension must stay running.
</Note>
GitHub Enterprise (data residency)
If your organization uses a data-residency GitHub Enterprise tenant (a
*.ghe.com host such as your-org.ghe.com), Copilot lives on tenant-local
endpoints rather than public github.com. OpenClaw exposes this as a
first-class auth choice so you do not have to hand-edit URLs.
Enter the tenant root only (`your-org.ghe.com`). Derived service hosts such
as `api.your-org.ghe.com` or `copilot-api.your-org.ghe.com` are not accepted;
OpenClaw derives those endpoints from the tenant root automatically.
```bash
openclaw models auth login --provider github-copilot --method device-enterprise
```
```json5
{
models: {
providers: {
"github-copilot": { params: { githubDomain: "your-org.ghe.com" } },
},
},
}
```
The device flow and account validation use the tenant's GitHub endpoints, and
Copilot requests use https://copilot-api.your-org.ghe.com. This keeps both
authentication and inference on the configured data-residency tenant instead of
the public endpoints.
Agents share Copilot credentials only when their normalized, supported tenant scopes match; Doctor preserves credentials for different tenants, so authenticate each affected agent for its intended tenant instead of deleting its local credential.
The `COPILOT_GITHUB_DOMAIN` environment variable overrides the resolved domain for every Copilot path that resolves it — the Enterprise device login (`--method device-enterprise`), the standalone `openclaw models auth login-github-copilot` shortcut, account validation, embeddings, and completions. Set it to your `*.ghe.com` host for fully headless or CI setups. Leave it unset (and the config param absent) to use public `github.com`. Logins persist the domain they minted the token for (and clear it when logging in against public `github.com`), so routing stays correct even after the environment variable is unset.Tenant request identity
OpenClaw uses the copilot-developer-cli request identity by default, including
for data-residency tenants. First confirm that your enterprise permits Copilot
CLI and the selected model. A *.ghe.com hostname does not imply a different
integration policy.
If your tenant administrator or GitHub support requires a different identity, use the existing provider header setting:
{
models: {
providers: {
"github-copilot": {
params: { githubDomain: "your-org.ghe.com" },
headers: { "Copilot-Integration-Id": "vscode-chat" },
},
},
},
}
The provider identity applies to model selection during setup, live model
discovery, inference, and embeddings. Header names are case-insensitive; request.headers takes precedence
over provider headers. Embedding-specific memory.search.remote.headers still
takes precedence for embedding discovery and requests. Unrelated provider headers
are not forwarded to the catalog or embedding endpoints. Changing the identity
does not grant access to models or clients disabled by your organization's policy.
Optional flags
| Command | Flag | Description |
|---|---|---|
openclaw models auth login-github-copilot |
--yes |
Overwrite an existing auth profile without prompting |
openclaw models auth login --provider github-copilot --method device |
--set-default |
Also apply the provider's recommended default model |
# Skip the re-login confirmation
openclaw models auth login-github-copilot --yes
# Login and set the default model in one step
openclaw models auth login --provider github-copilot --method device --set-default
Non-interactive onboarding
The device-login flow requires an interactive TTY. For headless setup, import
an existing GitHub OAuth access token with openclaw onboard --non-interactive:
openclaw onboard --non-interactive --accept-risk \
--auth-choice github-copilot \
--github-copilot-token "$COPILOT_GITHUB_TOKEN" \
--skip-channels --skip-health
You can also omit --auth-choice; passing --github-copilot-token infers the
GitHub Copilot provider auth choice. If the flag is omitted, onboarding falls
back to COPILOT_GITHUB_TOKEN. Generic GH_TOKEN and GITHUB_TOKEN do not
enable or authenticate the provider. Use
--secret-input-mode ref with COPILOT_GITHUB_TOKEN set to store an env-backed
tokenRef instead of plaintext in the auth profile store.
Fresh non-interactive setup validates the token before saving it. When setup must choose a default, it also checks the live Copilot model catalog. OpenClaw prefers the provider's current general-purpose model when that model is enabled for the account; otherwise it chooses a deterministic eligible fallback. Setup fails without writing a new auth profile if the account has no picker-visible model that supports streaming and tool calls. An explicitly configured default model is never replaced.
The device-login flow requires an interactive TTY. Run it directly in a terminal, not in a non-interactive script or CI pipeline. Copilot model availability depends on your GitHub plan and organization policy. Interactive onboarding uses the live catalog for its model picker, while non-interactive onboarding selects an eligible model automatically. See GitHub's [supported models per Copilot plan](https://docs.github.com/en/copilot/reference/ai-models/supported-models#supported-ai-models-per-copilot-plan) for the current model list. Once the device-login (or env-var) auth path has resolved a GitHub token, OpenClaw refreshes the model catalog on demand from `${baseUrl}/models` (the same endpoint VS Code Copilot uses) so the runtime tracks per-account entitlement and accurate context windows without manifest churn. The visible live catalog excludes models hidden from GitHub's picker or disabled by account policy. Automatic setup defaults additionally require streaming and tool-call support. Newly published Copilot models become visible without an OpenClaw upgrade, and context windows reflect the real per-model limits (e.g. 400k for the gpt-5.x series, 1M for the internal `claude-opus-*-1m` variants).Failed refreshes report the failure and retain the last successful inventory,
or bundled models before the first success. A successful empty response clears
discovered models. Missing Copilot credentials makes no live request.
Copilot requires explicit provider configuration, a saved Copilot auth
profile, or `COPILOT_GITHUB_TOKEN`, within the agent's model scope.
The old `plugins.entries.github-copilot.config.discovery.enabled` switch
is retired. Config loading ignores it, and Doctor removes it when saving
the config. It no longer prevents live requests for configured Copilot auth.
The device-login flow stores a protected-store `tokenRef` in the Copilot
auth profile. An explicitly selected profile stays selected; an unscoped
lookup can use `COPILOT_GITHUB_TOKEN` before the first saved profile.
Interactive onboarding honors an explicit `--secret-input-mode plaintext`
choice for compatibility. That mode stores the token inline, reports the
choice, and remains visible to `openclaw secrets audit --check`.
The protected store is write-only through OpenClaw's user-facing secret APIs,
but it is not encrypted at rest; its SQLite file relies on state-directory
permissions. At runtime, OpenClaw resolves the reference, validates Copilot
access, resolves the account-specific API endpoint, and uses the GitHub token
for Copilot requests. You do not need to manage runtime authentication
manually.
Usage checks also use the selected profile's GitHub token. For OAuth profiles
that carry a tenant domain, usage follows that domain before the provider's
configured domain. `COPILOT_GITHUB_DOMAIN` still takes precedence.
Memory search embeddings
GitHub Copilot can also serve as an embedding provider for memory search. If you have a Copilot subscription and have logged in, OpenClaw can use it for embeddings without a separate API key.
Config
Set memory.search.provider explicitly to use GitHub Copilot embeddings. If a
GitHub token is available, OpenClaw discovers available embedding models from
the Copilot API and picks the best one automatically.
{
memory: {
search: {
provider: "github-copilot",
// Optional: override the auto-discovered model
model: "text-embedding-3-small",
},
},
}
How it works
- OpenClaw resolves your GitHub token (from env vars or auth profile).
- Validates Copilot access and resolves the account-specific API endpoint.
- Queries the Copilot
/modelsendpoint to discover available embedding models, with a 10-second deadline that includes reading the response body. - Picks the best model (preference order:
text-embedding-3-small,text-embedding-3-large,text-embedding-ada-002). - Sends embedding requests to the Copilot
/embeddingsendpoint.
Model availability depends on your GitHub plan. If discovery fails or no
embedding models are available, OpenClaw uses memory.search.fallback only
when you explicitly configure another provider. Otherwise, setup reports the
error instead of silently selecting a different provider.