copilot-sdk

Server-to-server authentication

Use a short-lived installation access token when a service needs to make Copilot requests on behalf of an organization without a user’s credentials. In GitHub Actions, use the built-in GITHUB_TOKEN instead.

GitHub Actions

For workflows in an organization-owned repository, grant the built-in token permission to make Copilot requests:

permissions:
  contents: read
  copilot-requests: write

jobs:
  copilot:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - run: your-application
        env:
          GITHUB_TOKEN: $

The organization’s Allow use of Copilot CLI billed to the organization policy must be enabled. This approach needs no GitHub App or stored authentication secret. For details, see Using Copilot CLI in GitHub Actions with GITHUB_TOKEN.

Other services and CI systems

For services outside GitHub Actions:

  1. Create a GitHub App with the Copilot Requests repository permission set to Read & write.
  2. Install it on the organization that should be billed. The current Copilot permission check requires All repositories access.
  3. Create an installation access token with a repository ID and the Copilot permission:

    {
      "repository_ids": [123456789],
      "permissions": {
        "copilot_requests": "write"
      }
    }
    
  4. Pass the resulting ghs_ token to the runtime as COPILOT_GITHUB_TOKEN.

The organization must be enabled for Copilot requests from GitHub App installations. Installation tokens expire after one hour.

[!WARNING] Do not pass an installation token through the SDK’s gitHubToken, github_token, or equivalent option. That option is for user tokens. Installation tokens must use the runtime environment authentication path.

Configure the runtime

The following examples assume the minted token is in INSTALLATION_TOKEN. They pass it only to the child runtime and disable fallback to stored user credentials.

TypeScript ```typescript import { CopilotClient, RuntimeConnection } from "@github/copilot-sdk"; const token = process.env.INSTALLATION_TOKEN; if (!token) throw new Error("INSTALLATION_TOKEN is required"); const client = new CopilotClient({ connection: RuntimeConnection.forStdio(), env: { ...process.env, COPILOT_GITHUB_TOKEN: token, }, useLoggedInUser: false, }); ```
Python ```python import os from copilot import CopilotClient, RuntimeConnection client = CopilotClient( connection=RuntimeConnection.for_stdio(), env={**os.environ, "COPILOT_GITHUB_TOKEN": os.environ["INSTALLATION_TOKEN"]}, use_logged_in_user=False, ) ```
Go ```go package main import ( "log" "os" copilot "github.com/github/copilot-sdk/go" ) func main() { token, ok := os.LookupEnv("INSTALLATION_TOKEN") if !ok { log.Fatal("INSTALLATION_TOKEN is required") } client := copilot.NewClient(&copilot.ClientOptions{ Connection: copilot.StdioConnection{}, Env: append(os.Environ(), "COPILOT_GITHUB_TOKEN="+token), UseLoggedInUser: copilot.Bool(false), }) _ = client } ```
Rust ```rust use github_copilot_sdk::{ClientOptions, Transport}; fn main() { let token = std::env::var("INSTALLATION_TOKEN").expect("INSTALLATION_TOKEN is required"); let options = ClientOptions::new() .with_transport(Transport::Stdio) .with_env([("COPILOT_GITHUB_TOKEN", token)]) .with_use_logged_in_user(false); drop(options); } ```
.NET ```csharp using System.Collections; using GitHub.Copilot; var token = Environment.GetEnvironmentVariable("INSTALLATION_TOKEN") ?? throw new InvalidOperationException("INSTALLATION_TOKEN is required"); var environment = Environment.GetEnvironmentVariables() .Cast() .ToDictionary(entry => (string)entry.Key, entry => entry.Value?.ToString() ?? ""); environment["COPILOT_GITHUB_TOKEN"] = token; await using var client = new CopilotClient(new CopilotClientOptions { Connection = RuntimeConnection.ForStdio(), Environment = environment, UseLoggedInUser = false, }); ``` </details>
Java ```java import com.github.copilot.CopilotClient; import com.github.copilot.rpc.CopilotClientOptions; import java.util.HashMap; import java.util.Objects; var environment = new HashMap<>(System.getenv()); var token = Objects.requireNonNull( System.getenv("INSTALLATION_TOKEN"), "INSTALLATION_TOKEN is required"); environment.put("COPILOT_GITHUB_TOKEN", token); try (var client = new CopilotClient(new CopilotClientOptions() .setEnvironment(environment) .setUseLoggedInUser(false))) { // Use the client. } ```
For in-process FFI, set `COPILOT_GITHUB_TOKEN` in the host environment before loading the runtime; per-client environment options are not supported. For an existing runtime URI, set it on that runtime process. ## Refresh tokens Mint a new installation token before the current token expires. For a child process, restart the SDK client with the new environment. For an in-process or existing runtime, restart the host runtime with the new token. ## Billing Usage is attributed and billed to the account that owns the GitHub App installation. Use an organization installation for organization billing; a user-account installation attributes usage to that user. ## Troubleshooting | Symptom | Check | |---|---| | `401 Unauthorized` | Confirm the organization supports GitHub App installation authentication for Copilot. | | `403 Resource not accessible by integration` or an error mentioning user information | Confirm the installation token is in `COPILOT_GITHUB_TOKEN`, not the SDK's explicit token option. | | `403 Forbidden` from the Copilot API | Confirm the token request contains `repository_ids` and `copilot_requests: write`. | | `403 Forbidden` with the required token request | Confirm the app installation has **All repositories** access, then mint a new token. | | Requested model is unavailable | Confirm the organization's Copilot policy allows the model and the bundled runtime supports it. | | Wrong account billed | Confirm the installation belongs to the intended organization. | ## Further reading * [Authenticate Copilot SDK](/copilot-sdk/auth/authenticate.html): other authentication methods and priority * [Generating an installation access token](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-an-installation-access-token-for-a-github-app): GitHub App token creation