# 서버-서버 인증

서비스에서 사용자의 자격 증명 없이 조직을 대신하여 Copilot 요청을 수행해야 하는 경우 단기 설치 액세스 토큰을 사용합니다. GitHub Actions 기본 제공 GITHUB_TOKEN 을 대신 사용합니다.

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

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

## GitHub Actions (GitHub 액션)

조직 소유 리포지토리의 워크플로의 경우 기본 제공 토큰 권한을 부여하여 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\_TOKEN을 사용한 GitHub Actions에서 Copilot CLI 사용하기](/ko/copilot/how-tos/copilot-cli/use-copilot-cli-in-actions)(을)를 참조하세요.

## 기타 서비스 및 CI 시스템

GitHub Actions 외부 서비스의 경우:

1. Copilot 요청 리포지토리 권한이 **읽기 및 쓰기**로 설정된 **GitHub** 앱을 만듭니다.

2. 요금이 청구되어야 하는 조직에 설치합니다. 현재 Copilot 권한 검사에는 **모든 리포지토리** 액세스가 필요합니다.

3. 리포지토리 ID 및 Copilot 권한이 있는 [GitHub 앱에 대한 설치 액세스 토큰 생성](/ko/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 앱 설치의 Copilot 요청에 대해 조직을 사용하도록 설정해야 합니다. 설치 토큰은 1시간 후에 만료됩니다.

> \[!WARNING]
> SDK `gitHubToken``github_token`또는 동등한 옵션을 통해 설치 토큰을 전달하지 마세요. 이 옵션은 사용자 토큰에 대한 것입니다. 설치 토큰은 런타임 환경 인증 경로를 사용해야 합니다.

## 런타임 구성

다음 예제에서는 minted 토큰이 에 있다고 `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>

In-process FFI의 경우 런타임을 로드하기 전에 호스트 환경에서 설정합니다 `COPILOT_GITHUB_TOKEN` . 클라이언트별 환경 옵션은 지원되지 않습니다. 기존 런타임 URI의 경우 해당 런타임 프로세스에서 설정합니다.

## 토큰 새로 고침

현재 토큰이 만료되기 전에 새 설치 토큰을 생성합니다. 자식 프로세스의 경우 새 환경으로 SDK 클라이언트를 다시 시작합니다. In-Process 또는 기존 런타임의 경우 새 토큰을 사용하여 호스트 런타임을 다시 시작합니다.

## Billing

사용량은 GitHub 앱 설치를 소유한 계정에 기인하고 요금이 청구됩니다. 조직 청구를 위해 조직 설치를 사용합니다. 해당 사용자에 대한 사용자 계정 설치 특성 사용

## Troubleshooting

| 증상                                                                          | 확인                                                             |
| --------------------------------------------------------------------------- | -------------------------------------------------------------- |
| `401 Unauthorized`                                                          | 조직에서 Copilot GitHub 앱 설치 인증을 지원하는지 확인합니다.                      |
| `403 Resource not accessible by integration` 또는 사용자 정보를 언급하는 동안 오류가 발생했습니다. | 설치 토큰이 `COPILOT_GITHUB_TOKEN`SDK의 명시적 토큰 옵션이 아닌 위치에 있는지 확인합니다. |
| `403 Forbidden`Copilot API에서                                                | 토큰 요청에 포함 및 `repository_ids``copilot_requests: write`.         |
| `403 Forbidden` 필요한 토큰 요청이 있는 경우                                            | 앱 설치에 **모든 리포지토리** 액세스 권한이 있는지 확인한 다음 새 토큰을 삭제합니다.             |
| 요청된 모델을 사용할 수 없음                                                            | 조직의 Copilot 정책이 모델을 허용하고 번들 런타임이 지원하는지 확인합니다.                  |
| 잘못된 계정 청구                                                                   | 설치가 의도한 조직에 속하는지 확인합니다.                                        |

## 추가 읽기

* [인증](/ko/copilot/how-tos/copilot-sdk/auth/authenticate): 다른 인증 방법 및 우선 순위
* [GitHub 앱에 대한 설치 액세스 토큰 생성](/ko/apps/creating-github-apps/authenticating-with-a-github-app/generating-an-installation-access-token-for-a-github-app): GitHub 앱 토큰 만들기