{"meta":{"title":"서버-서버 인증","intro":"서비스에서 사용자의 자격 증명 없이 조직을 대신하여 Copilot 요청을 수행해야 하는 경우 단기 설치 액세스 토큰을 사용합니다. GitHub Actions 기본 제공 GITHUB_TOKEN 을 대신 사용합니다.","product":"GitHub Copilot","breadcrumbs":[{"href":"/ko/copilot","title":"GitHub Copilot"},{"href":"/ko/copilot/how-tos","title":"방법"},{"href":"/ko/copilot/how-tos/copilot-sdk","title":"코필로트 SDK"},{"href":"/ko/copilot/how-tos/copilot-sdk/auth","title":"인증"},{"href":"/ko/copilot/how-tos/copilot-sdk/auth/server-to-server-tokens","title":"서버-서버 토큰"}],"documentType":"article"},"body":"# 서버-서버 인증\n\n서비스에서 사용자의 자격 증명 없이 조직을 대신하여 Copilot 요청을 수행해야 하는 경우 단기 설치 액세스 토큰을 사용합니다. GitHub Actions 기본 제공 GITHUB_TOKEN 을 대신 사용합니다.\n\n<!-- markdownlint-disable GHD046 GHD005 -->\n\n<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->\n\n## GitHub Actions (GitHub 액션)\n\n조직 소유 리포지토리의 워크플로의 경우 기본 제공 토큰 권한을 부여하여 Copilot 요청을 수행합니다.\n\n```yaml\npermissions:\n  contents: read\n  copilot-requests: write\n\njobs:\n  copilot:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n      - run: your-application\n        env:\n          GITHUB_TOKEN: $\n```\n\n조직의 조직 정책에 **청구된 Copilot CLI의 사용 허용을** 사용하도록 설정해야 합니다. 이 방법은 GitHub 앱 또는 저장된 인증 비밀이 필요하지 않습니다. 세부 정보는 [GITHUB\\_TOKEN을 사용한 GitHub Actions에서 Copilot CLI 사용하기](/ko/copilot/how-tos/copilot-cli/use-copilot-cli-in-actions)(을)를 참조하세요.\n\n## 기타 서비스 및 CI 시스템\n\nGitHub Actions 외부 서비스의 경우:\n\n1. Copilot 요청 리포지토리 권한이 **읽기 및 쓰기**로 설정된 **GitHub** 앱을 만듭니다.\n\n2. 요금이 청구되어야 하는 조직에 설치합니다. 현재 Copilot 권한 검사에는 **모든 리포지토리** 액세스가 필요합니다.\n\n3. 리포지토리 ID 및 Copilot 권한이 있는 [GitHub 앱에 대한 설치 액세스 토큰 생성](/ko/apps/creating-github-apps/authenticating-with-a-github-app/generating-an-installation-access-token-for-a-github-app):\n\n   ```json\n   {\n     \"repository_ids\": [123456789],\n     \"permissions\": {\n       \"copilot_requests\": \"write\"\n     }\n   }\n   ```\n\n4. 결과 토큰을 `ghs_` 런타임에 다음과 같이 `COPILOT_GITHUB_TOKEN`전달합니다.\n\nGitHub 앱 설치의 Copilot 요청에 대해 조직을 사용하도록 설정해야 합니다. 설치 토큰은 1시간 후에 만료됩니다.\n\n> \\[!WARNING]\n> SDK `gitHubToken``github_token`또는 동등한 옵션을 통해 설치 토큰을 전달하지 마세요. 이 옵션은 사용자 토큰에 대한 것입니다. 설치 토큰은 런타임 환경 인증 경로를 사용해야 합니다.\n\n## 런타임 구성\n\n다음 예제에서는 minted 토큰이 에 있다고 `INSTALLATION_TOKEN`가정합니다. 자식 런타임에만 전달하고 저장된 사용자 자격 증명에 대한 대체를 사용하지 않도록 설정합니다.\n\n<div class=\"ghd-codetabs\">\n<div class=\"ghd-codetab\" data-lang=\"typescript\" data-label=\"TypeScript\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">TypeScript</div>\n\n```typescript\nimport { CopilotClient, RuntimeConnection } from \"@github/copilot-sdk\";\n\nconst token = process.env.INSTALLATION_TOKEN;\nif (!token) throw new Error(\"INSTALLATION_TOKEN is required\");\n\nconst client = new CopilotClient({\n    connection: RuntimeConnection.forStdio(),\n    env: {\n        ...process.env,\n        COPILOT_GITHUB_TOKEN: token,\n    },\n    useLoggedInUser: false,\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"python\" data-label=\"Python\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Python</div>\n\n```python\nimport os\n\nfrom copilot import CopilotClient, RuntimeConnection\n\nclient = CopilotClient(\n    connection=RuntimeConnection.for_stdio(),\n    env={**os.environ, \"COPILOT_GITHUB_TOKEN\": os.environ[\"INSTALLATION_TOKEN\"]},\n    use_logged_in_user=False,\n)\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"go\" data-label=\"Go\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Go</div>\n\n```golang\npackage main\n\nimport (\n    \"log\"\n    \"os\"\n\n    copilot \"github.com/github/copilot-sdk/go\"\n)\n\nfunc main() {\n    token, ok := os.LookupEnv(\"INSTALLATION_TOKEN\")\n    if !ok {\n        log.Fatal(\"INSTALLATION_TOKEN is required\")\n    }\n    client := copilot.NewClient(&copilot.ClientOptions{\n        Connection:      copilot.StdioConnection{},\n        Env:             append(os.Environ(), \"COPILOT_GITHUB_TOKEN=\"+token),\n        UseLoggedInUser: copilot.Bool(false),\n    })\n    _ = client\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"rust\" data-label=\"Rust\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Rust</div>\n\n```rust\nuse github_copilot_sdk::{ClientOptions, Transport};\n\nfn main() {\n    let token = std::env::var(\"INSTALLATION_TOKEN\").expect(\"INSTALLATION_TOKEN is required\");\n    let options = ClientOptions::new()\n        .with_transport(Transport::Stdio)\n        .with_env([(\"COPILOT_GITHUB_TOKEN\", token)])\n        .with_use_logged_in_user(false);\n    drop(options);\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"dotnet\" data-label=\".NET\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">.NET</div>\n\n```csharp\nusing System.Collections;\nusing GitHub.Copilot;\n\nvar token = Environment.GetEnvironmentVariable(\"INSTALLATION_TOKEN\")\n    ?? throw new InvalidOperationException(\"INSTALLATION_TOKEN is required\");\nvar environment = Environment.GetEnvironmentVariables()\n    .Cast<DictionaryEntry>()\n    .ToDictionary(entry => (string)entry.Key, entry => entry.Value?.ToString() ?? \"\");\nenvironment[\"COPILOT_GITHUB_TOKEN\"] = token;\n\nawait using var client = new CopilotClient(new CopilotClientOptions\n{\n    Connection = RuntimeConnection.ForStdio(),\n    Environment = environment,\n    UseLoggedInUser = false,\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"java\" data-label=\"Java\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Java</div>\n\n```java\nimport com.github.copilot.CopilotClient;\nimport com.github.copilot.rpc.CopilotClientOptions;\nimport java.util.HashMap;\nimport java.util.Objects;\n\nvar environment = new HashMap<>(System.getenv());\nvar token = Objects.requireNonNull(\n    System.getenv(\"INSTALLATION_TOKEN\"), \"INSTALLATION_TOKEN is required\");\nenvironment.put(\"COPILOT_GITHUB_TOKEN\", token);\n\ntry (var client = new CopilotClient(new CopilotClientOptions()\n        .setEnvironment(environment)\n        .setUseLoggedInUser(false))) {\n    // Use the client.\n}\n```\n\n</div>\n\n</div>\n\nIn-process FFI의 경우 런타임을 로드하기 전에 호스트 환경에서 설정합니다 `COPILOT_GITHUB_TOKEN` . 클라이언트별 환경 옵션은 지원되지 않습니다. 기존 런타임 URI의 경우 해당 런타임 프로세스에서 설정합니다.\n\n## 토큰 새로 고침\n\n현재 토큰이 만료되기 전에 새 설치 토큰을 생성합니다. 자식 프로세스의 경우 새 환경으로 SDK 클라이언트를 다시 시작합니다. In-Process 또는 기존 런타임의 경우 새 토큰을 사용하여 호스트 런타임을 다시 시작합니다.\n\n## Billing\n\n사용량은 GitHub 앱 설치를 소유한 계정에 기인하고 요금이 청구됩니다. 조직 청구를 위해 조직 설치를 사용합니다. 해당 사용자에 대한 사용자 계정 설치 특성 사용\n\n## Troubleshooting\n\n| 증상                                                                          | 확인                                                             |\n| --------------------------------------------------------------------------- | -------------------------------------------------------------- |\n| `401 Unauthorized`                                                          | 조직에서 Copilot GitHub 앱 설치 인증을 지원하는지 확인합니다.                      |\n| `403 Resource not accessible by integration` 또는 사용자 정보를 언급하는 동안 오류가 발생했습니다. | 설치 토큰이 `COPILOT_GITHUB_TOKEN`SDK의 명시적 토큰 옵션이 아닌 위치에 있는지 확인합니다. |\n| `403 Forbidden`Copilot API에서                                                | 토큰 요청에 포함 및 `repository_ids``copilot_requests: write`.         |\n| `403 Forbidden` 필요한 토큰 요청이 있는 경우                                            | 앱 설치에 **모든 리포지토리** 액세스 권한이 있는지 확인한 다음 새 토큰을 삭제합니다.             |\n| 요청된 모델을 사용할 수 없음                                                            | 조직의 Copilot 정책이 모델을 허용하고 번들 런타임이 지원하는지 확인합니다.                  |\n| 잘못된 계정 청구                                                                   | 설치가 의도한 조직에 속하는지 확인합니다.                                        |\n\n## 추가 읽기\n\n* [인증](/ko/copilot/how-tos/copilot-sdk/auth/authenticate): 다른 인증 방법 및 우선 순위\n* [GitHub 앱에 대한 설치 액세스 토큰 생성](/ko/apps/creating-github-apps/authenticating-with-a-github-app/generating-an-installation-access-token-for-a-github-app): GitHub 앱 토큰 만들기"}