# 服务器到服务器身份验证

当服务需要在没有用户凭据的情况下代表组织发起 Copilot 请求时，请使用短期有效的安装访问令牌。 在GitHub Actions中，改用内置GITHUB_TOKEN。

<!-- markdownlint-disable GHD046 GHD005 -->

<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->

## GitHub Actions

对于组织拥有的仓库中的工作流，授予内置令牌发出 Copilot 请求的权限：

```yaml
permissions:
  contents: read
  copilot-requests: write

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

必须启用组织的**允许使用向组织计费的 Copilot CLI** 策略。 此方法不需要GitHub应用或存储的身份验证机密。 有关详细信息，请参阅 [在 GitHub Actions 中使用 GITHUB\_TOKEN 运行 Copilot CLI](/zh/copilot/how-tos/copilot-cli/use-copilot-cli-in-actions)。

## 其他服务和 CI 系统

对于GitHub Actions之外的服务：

1. 创建GitHub应用，其中**Copilot请求**存储库权限设置为 **“读取和写入**”。

2. 将其安装在应计费的组织上。 当前Copilot权限检查需要**所有存储库**访问权限。

3. 具有存储库 ID 和Copilot权限的 [为 GitHub 应用生成安装访问令牌](/zh/apps/creating-github-apps/authenticating-with-a-github-app/generating-an-installation-access-token-for-a-github-app)：

   ```json
   {
     "repository_ids": [123456789],
     "permissions": {
       "copilot_requests": "write"
     }
   }
   ```

4. 将生成的 `ghs_` 令牌以 `COPILOT_GITHUB_TOKEN` 的形式传递给运行时。

必须为该组织启用来自 GitHub App 安装的 Copilot 请求。 安装令牌在一小时后过期。

> \[!WARNING]
> 不要通过 SDK 的 `gitHubToken`或 `github_token`等效选项传递安装令牌。 此选项适用于用户令牌。 安装令牌必须使用运行时环境身份验证路径。

## 配置运行时

以下示例假定铸造的令牌存储在 `INSTALLATION_TOKEN` 中。 它们仅将其传递给子运行时，并禁用回退到存储的用户凭据。

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

```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,
});
```

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

```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,
)
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

```golang
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
}
```

</div>

<div class="ghd-codetab" data-lang="rust" data-label="Rust"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Rust</div>

```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);
}
```

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

```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<DictionaryEntry>()
    .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,
});
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

```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.
}
```

</div>

</div>

对于进程内 FFI，请在加载运行时之前于主机环境中设置 `COPILOT_GITHUB_TOKEN`；不支持每个客户端的环境选项。 对于现有运行时 URI，请在该运行时进程中设置它。

## 刷新令牌

在当前令牌过期之前，先挖掘新的安装令牌。 对于子进程，请使用新环境重启 SDK 客户端。 对于进程内或现有运行时，请使用新令牌重启主机运行时。

## Billing

使用情况将归属于拥有 GitHub App 安装的账户，并向该账户计费。 使用组织级安装可按组织计费；用户账户级安装会将使用量归属于该用户。

## Troubleshooting

| 症状                                                      | 检查                                                     |
| ------------------------------------------------------- | ------------------------------------------------------ |
| `401 Unauthorized`                                      | 确认该组织支持适用于 Copilot 的 GitHub App 安装身份验证。                |
| `403 Resource not accessible by integration` 或涉及用户信息的错误 | 确认安装令牌位于 `COPILOT_GITHUB_TOKEN` 中，而不是 SDK 的显式令牌选项中。    |
| `403 Forbidden`来自 Copilot API                           | 确认令牌请求包含 `repository_ids` 和 `copilot_requests: write`。 |
| `403 Forbidden`，带有所需令牌请求                                | 确认应用安装具有 **“所有仓库”** 访问权限，然后生成一个新令牌。                    |
| 请求的模型不可用                                                | 确认组织的 Copilot 策略允许使用该模型，并且随附的运行时支持它。                   |
| 错误的帐户计费                                                 | 确认该安装归属于目标组织。                                          |

## 延伸阅读

* [Authentication](/zh/copilot/how-tos/copilot-sdk/auth/authenticate)：其他身份验证方法和优先级
* [为 GitHub 应用生成安装访问令牌](/zh/apps/creating-github-apps/authenticating-with-a-github-app/generating-an-installation-access-token-for-a-github-app)：GitHub创建应用令牌