---
title: Admin API로 WIF 관리하기
url: https://platform.claude.com/docs/ko/manage-claude/wif-admin-api
description: 인프라스트럭처 코드화(infrastructure-as-code) 및 CI 워크플로를 위해 Workload Identity Federation 서비스 계정, 발급자, 규칙을 프로그래밍 방식으로 생성하고 관리합니다.
---

Admin API를 사용하면 [Workload Identity Federation](https://platform.claude.com/docs/ko/manage-claude/workload-identity-federation) 리소스, 즉 서비스 계정(service accounts), 페더레이션 발급자(federation issuers), 페더레이션 규칙(federation rules)을 프로그래밍 방식으로 생성하고 관리할 수 있습니다. 이를 사용하면 Claude Console에서 일일이 클릭하는 대신 페더레이션 구성을 "infrastructure as code"(인프라스트럭처 코드화)로 유지하고, CI에서 프로비저닝하며, 여러 조직에 걸쳐 재현할 수 있습니다. 이 엔드포인트들은 나머지 [Admin API](https://platform.claude.com/docs/ko/manage-claude/admin-api)와 `/v1/organizations` 경로 접두사를 공유합니다.

## 사전 요구 사항

이 페이지의 모든 요청은 `org:admin` 스코프를 가진 OAuth 베어러 토큰(bearer token)으로 인증합니다. 이 스코프는 admin, owner 또는 primary owner 역할을 가진 조직 구성원에게만 부여되며, 조직 전체에 대한 액세스 권한을 부여합니다. 즉, 워크스페이스 바인딩은 무시됩니다. 토큰을 얻는 방법은 두 가지이며, 각각 다른 권한을 가집니다. 본인의 로그인으로 얻은 토큰은 사용자로서 동작하는 반면, 페더레이션된 토큰은 서비스 계정으로서 동작하며 이 페이지의 모든 작업을 수행할 수는 없습니다.

### 대화형 (터미널)

전용 프로필로 [`ant` CLI](https://platform.claude.com/docs/ko/cli-sdks-libraries/cli/quickstart)에 로그인하면서 `org:admin` 스코프를 요청한 다음([관리자 액세스](https://platform.claude.com/docs/ko/cli-sdks-libraries/cli/authentication#admin-access) 참조), 베어러 토큰을 내보내세요. `--profile admin`으로 로그인하면 `org:admin` 자격 증명이 자체 프로필 이름으로 저장되고 CLI의 활성 프로필로도 설정되며, 내보낸 변수는 해당 셸의 모든 SDK 및 CLI 호출에 적용됩니다. 따라서 관리 전용으로 사용하는 셸을 사용하고, 작업이 끝나면 변수를 해제하고, `ant profile activate default`로 CLI를 다시 전환하세요:

```bash CLI
ant auth login --profile admin --scope "org:admin"
export ANTHROPIC_AUTH_TOKEN=$(ant auth print-credentials --profile admin --access-token)
```

대화형 토큰은 수명이 짧습니다. 요청이 401을 반환하기 시작하면 export 명령을 다시 실행하세요(토큰을 자동으로 갱신합니다).

SDK와 `ant` CLI는 `ANTHROPIC_AUTH_TOKEN`을 자동으로 읽습니다. 같은 셸에서 `ANTHROPIC_API_KEY`는 설정하지 않은 상태로 두세요. 이 엔드포인트들은 API 키를 거부하며, 일부 클라이언트는 둘 다 설정된 경우 키를 우선하기 때문입니다.

### 워크로드 (CI 및 자동화)

`organization_role`이 `admin`인 서비스 계정을 대상으로 하는 `oauth_scope: org:admin` 페더레이션 규칙을 생성하세요. 규칙 자체는 Claude Console에서 생성해야 합니다. 워크로드에 조직 관리자 액세스 권한을 부여하는 것은 의도적인 사람의 행위여야 하며, 자동화가 스스로 부트스트랩할 수 있는 것이 아닙니다. 다음 섹션에서 조직당 한 번 수행하는 이 설정 과정을 안내합니다.

## WIF를 관리할 워크로드 부트스트랩하기

Console에서 생성한 규칙 하나만 있으면 나머지 페더레이션 구성을 infrastructure as code로 관리할 수 있습니다. 신뢰할 수 있는 단일 워크로드에 `org:admin` 스코프를 부여하고, 해당 워크로드가 이 API를 통해 페더레이션 발급자와 모든 워크스페이스 범위 페더레이션 규칙을 관리하도록 하세요.

<Steps>
  <Step title="Console에서 org:admin 규칙 생성하기">
    Claude Console에서 [Workload identity](https://platform.claude.com/settings/workload-identity-federation) 페이지(`platform.claude.com/settings/workload-identity-federation`)로 이동한 다음 **Connect workload**를 선택하여 자동화 워크로드(예: 인프라 리포지토리의 GitHub Actions 워크플로)를 위한 페더레이션 규칙 하나를 생성하세요. **Advanced rule options**에서 규칙의 OAuth 스코프를 `org:admin`으로 설정하세요. 그러면 마법사가 Admin 조직 역할을 가진 새 서비스 계정을 생성합니다(또는 기존 admin 서비스 계정을 대상으로 선택하도록 요청합니다).

    <Warning>
      규칙을 광범위한 패턴이 아닌 정확히 하나의 워크로드 ID에 매칭하세요. `subject_prefix`는 `*`로 끝나지 않는 한 정확히 일치해야 합니다. GitHub Actions의 경우 `repo:my-org/my-repo:ref:refs/heads/main`과 같이 보호된 브랜치에 subject를 고정하세요. `repo:my-org/my-repo:*`와 같은 후행 와일드카드는 포크에서 트리거된 실행을 포함한 `pull_request` 실행과도 일치하므로, 리포지토리에 풀 리퀘스트를 열 수 있는 사람이라면 누구나 `org:admin` 토큰을 발급할 수 있게 됩니다. [인증할 수 있는 워크플로 제한하기](https://platform.claude.com/docs/ko/manage-claude/wif-providers/github-actions#restrict-which-workflows-can-authenticate)를 참조하세요.
    </Warning>
  </Step>

  <Step title="워크로드의 ID 토큰 교환하기">
    SDK 중 하나 또는 `ant` CLI를 사용하는 워크로드는 교환을 직접 수행하지 않습니다. [SDK 클라이언트 구성하기](https://platform.claude.com/docs/ko/manage-claude/workload-identity-federation#construct-the-sdk-client)의 추론용 설정과 정확히 동일하게, 페더레이션 환경 변수로 클라이언트가 규칙을 가리키도록 하고 인수 없이 클라이언트를 생성하세요. 클라이언트는 첫 번째 요청 시 ID 토큰을 교환하고, 결과 액세스 토큰이 만료되기 전에 ID 토큰을 다시 읽어 다시 교환합니다:

    ```bash
    export ANTHROPIC_FEDERATION_RULE_ID=fdrl_...        # the org:admin rule from step 1
    export ANTHROPIC_ORGANIZATION_ID=00000000-0000-0000-0000-000000000000
    export ANTHROPIC_SERVICE_ACCOUNT_ID=svac_...       # the rule's target service account
    export ANTHROPIC_IDENTITY_TOKEN_FILE=/path/to/jwt  # or ANTHROPIC_IDENTITY_TOKEN
    # ANTHROPIC_WORKSPACE_ID는 규칙이 모든 워크스페이스 또는 둘 이상의
    # 워크스페이스에 활성화된 경우에만 필요합니다. org:admin 엔드포인트는 바인딩을 무시합니다.
    unset ANTHROPIC_API_KEY ANTHROPIC_AUTH_TOKEN       # both take precedence over federation
    ```

    `ant` CLI는 동일한 변수를 읽거나 `--federation-rule`, `--organization-id`, `--service-account-id`, `--identity-token-file` 플래그를 받습니다. 둘 이상의 `ant` 명령을 실행하는 워크로드의 경우 플래그나 환경 변수 대신 [페더레이션 프로필](https://platform.claude.com/docs/ko/manage-claude/wif-reference#profile-configuration-file)을 사용하세요. 플래그나 변수를 사용하면 CLI가 모든 프로세스에서 ID 토큰을 다시 교환하는데, `jti` 클레임을 가진 ID 토큰(GitHub Actions 토큰이 그렇습니다)은 한 번만 허용되므로 두 번째 명령은 거부됩니다. 또한 규칙이 모든 워크스페이스 또는 둘 이상의 워크스페이스에 대해 활성화된 경우, 프로필은 교환을 위해 CLI에 `workspace_id`를 제공하는 유일한 방법입니다. SDK와 달리 CLI는 `ANTHROPIC_WORKSPACE_ID`나 `--workspace-id`를 교환에 전달하지 않기 때문입니다. 모든 SDK는 동일한 설정을 명시적 생성자 인수로도 받으며, 이는 [SDK 클라이언트 구성하기](https://platform.claude.com/docs/ko/manage-claude/workload-identity-federation#construct-the-sdk-client)에 언어별로 나와 있습니다. 전체 목록과 순서는 [환경 변수](https://platform.claude.com/docs/ko/manage-claude/wif-reference#environment-variables) 및 [자격 증명 우선순위](https://platform.claude.com/docs/ko/manage-claude/wif-reference#credential-precedence)를 참조하세요.

    curl로 API를 호출하는 워크로드는 다른 페더레이션 워크로드와 동일한 [토큰 교환](https://platform.claude.com/docs/ko/manage-claude/workload-identity-federation#authenticate-from-your-workload)을 사용하여 JWT를 수명이 짧은 `org:admin` 베어러 토큰으로 직접 교환하고, 이를 `authorization: Bearer` 헤더에 담아 보냅니다.
  </Step>

  <Step title="API를 통해 발급자 및 워크스페이스 범위 규칙 관리하기">
    클라이언트가 구성되면(또는 curl의 경우 발급된 토큰이 `ANTHROPIC_AUTH_TOKEN`에 있으면), 워크로드는 이 페이지의 엔드포인트를 사용하여 페더레이션 구성을 생성하고 관리합니다.
  </Step>
</Steps>

워크로드가 발급한 토큰이 수행할 수 있는 작업과 수행할 수 없는 작업은 [권한 및 제약 조건](https://platform.claude.com/docs/ko/manage-claude/wif-admin-api#permissions-and-constraints)을 참조하세요. **Connect workload** 마법사로 이미 발급자, 서비스 계정 또는 규칙을 생성했다면, 다시 생성하는 대신 다음 엔드포인트로 목록을 조회하여 infrastructure-as-code 상태로 가져오세요.

## 인증

모든 엔드포인트는 `https://api.anthropic.com/v1/organizations/` 아래에 있습니다. 페더레이션 및 서비스 계정 엔드포인트에 대한 모든 요청에는 API 버전 헤더와 베어러 토큰이 필요합니다:

SDK에서 이러한 엔드포인트는 `client.organization.service_accounts` (typescript: `client.organization.serviceAccounts`; csharp, go: `client.Organization.ServiceAccounts`; java: `client.organization().serviceAccounts()`; php: `$client->organization->serviceAccounts`), `client.organization.federation.issuers` (csharp, go: `client.Organization.Federation.Issuers`; java: `client.organization().federation().issuers()`; php: `$client->organization->federation->issuers`), `client.organization.federation.rules` (csharp, go: `client.Organization.Federation.Rules`; java: `client.organization().federation().rules()`; php: `$client->organization->federation->rules`)입니다(CLI에서는 `ant organization:service-accounts`, `federation:issuers`, `federation:rules`). SDK 및 CLI 예제는 기본 클라이언트를 생성하며, 이 클라이언트는 `ANTHROPIC_AUTH_TOKEN`의 베어러 토큰을 전송하거나, 자동화된 워크로드에서는 [WIF를 관리할 워크로드 부트스트랩하기](https://platform.claude.com/docs/ko/manage-claude/wif-admin-api#bootstrap-a-workload-to-manage-wif)에 설명된 대로 페더레이션 교환을 직접 수행합니다. SDK 목록 메서드는 필요에 따라 추가 페이지를 가져오므로 `limit`은 페이지 크기를 설정합니다. PHP 및 Ruby 예제는 한 페이지를 읽습니다.

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS "https://api.anthropic.com/v1/organizations/service_accounts" \
    -H "authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
    -H "anthropic-version: 2023-06-01"
  ```

  ```bash CLI
  ant organization:service-accounts list
  ```

  ```python Python
  client = anthropic.Anthropic()

  service_accounts = client.organization.service_accounts.list()

  for service_account in service_accounts:
      print(f"{service_account.id}: {service_account.name}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  for await (const serviceAccount of client.organization.serviceAccounts.list()) {
    console.log(`${serviceAccount.id}: ${serviceAccount.name}`);
  }
  ```

  ```csharp C#
  AnthropicClient client = new();

  var page = await client.Organization.ServiceAccounts.List();

  await foreach (var serviceAccount in page.Paginate())
  {
      Console.WriteLine($"{serviceAccount.ID}: {serviceAccount.Name}");
  }
  ```

  ```go Go
  client := anthropic.NewClient()

  serviceAccounts := client.Organization.ServiceAccounts.ListAutoPaging(context.Background(), anthropic.OrganizationServiceAccountListParams{})

  for serviceAccounts.Next() {
  	serviceAccount := serviceAccounts.Current()
  	fmt.Printf("%s: %s\n", serviceAccount.ID, serviceAccount.Name)
  }
  if err := serviceAccounts.Err(); err != nil {
  	log.Fatal(err)
  }
  ```

  ```java Java
  AnthropicClient client = AnthropicOkHttpClient.fromEnv();

  var serviceAccounts = client.organization().serviceAccounts().list();

  for (var serviceAccount : serviceAccounts.autoPager()) {
      IO.println(serviceAccount.id() + ": " + serviceAccount.name());
  }
  ```

  ```php PHP
  $client = new Client();

  $serviceAccounts = $client->organization->serviceAccounts->list();

  foreach ($serviceAccounts->getItems() as $serviceAccount) {
      echo "{$serviceAccount->id}: {$serviceAccount->name}\n";
  }
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  service_accounts = client.organization.service_accounts.list

  service_accounts.data.each do |service_account|
    puts "#{service_account.id}: #{service_account.name}"
  end
  ```
</CodeGroup>

Admin API 키는 이 엔드포인트들에서 허용되지 않습니다. Admin API 페이지의 `x-api-key` 예제는 여기에 적용되지 않습니다.

## 서비스 계정

[서비스 계정](https://platform.claude.com/docs/ko/manage-claude/workload-identity-federation#service-accounts)(`svac_...`)은 페더레이션된 토큰이 그 역할로 동작하는 비인간 ID입니다. `organization_role`을 `developer`로 설정하세요.

서비스 계정 생성:

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS "https://api.anthropic.com/v1/organizations/service_accounts" \
    -H "authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
    -H "anthropic-version: 2023-06-01" \
    -H "content-type: application/json" \
    -d '{
      "name": "inference-worker",
      "organization_role": "developer"
    }'
  ```

  ```bash CLI
  ant organization:service-accounts create \
    --name inference-worker \
    --organization-role developer
  ```

  ```python Python
  client = anthropic.Anthropic()

  service_account = client.organization.service_accounts.create(
      name="inference-worker", organization_role="developer"
  )

  print(f"id: {service_account.id}")
  print(f"name: {service_account.name}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const serviceAccount = await client.organization.serviceAccounts.create({
    name: "inference-worker",
    organization_role: "developer"
  });

  console.log(`id: ${serviceAccount.id}`);
  console.log(`name: ${serviceAccount.name}`);
  ```

  ```csharp C#
  using Anthropic.Models.Organization.ServiceAccounts;

  AnthropicClient client = new();

  var serviceAccount = await client.Organization.ServiceAccounts.Create(new()
  {
      Name = "inference-worker",
      OrganizationRole = OrganizationRole.Developer
  });

  Console.WriteLine($"id: {serviceAccount.ID}");
  Console.WriteLine($"name: {serviceAccount.Name}");
  ```

  ```go Go
  client := anthropic.NewClient()

  serviceAccount, err := client.Organization.ServiceAccounts.New(context.Background(), anthropic.OrganizationServiceAccountNewParams{
  	Name:             "inference-worker",
  	OrganizationRole: anthropic.OrganizationServiceAccountNewParamsOrganizationRoleDeveloper,
  })
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("id: %s\n", serviceAccount.ID)
  fmt.Printf("name: %s\n", serviceAccount.Name)
  ```

  ```java Java
  import com.anthropic.models.organization.serviceaccounts.ServiceAccountCreateParams;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      var params = ServiceAccountCreateParams.builder()
          .name("inference-worker")
          .organizationRole(ServiceAccountCreateParams.OrganizationRole.DEVELOPER)
          .build();
      var serviceAccount = client.organization().serviceAccounts().create(params);

      IO.println("id: " + serviceAccount.id());
      IO.println("name: " + serviceAccount.name());
  }
  ```

  ```php PHP
  use Anthropic\Organization\ServiceAccounts\ServiceAccountCreateParams\OrganizationRole;
  // ...

  $client = new Client();

  $serviceAccount = $client->organization->serviceAccounts->create(
      name: 'inference-worker',
      organizationRole: OrganizationRole::DEVELOPER,
  );

  echo "id: {$serviceAccount->id}\n";
  echo "name: {$serviceAccount->name}\n";
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  service_account = client.organization.service_accounts.create(
    name: "inference-worker",
    organization_role: :developer
  )

  puts "id: #{service_account.id}"
  puts "name: #{service_account.name}"
  ```
</CodeGroup>

서비스 계정 목록 조회:

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS "https://api.anthropic.com/v1/organizations/service_accounts?limit=20" \
    -H "authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
    -H "anthropic-version: 2023-06-01"
  ```

  ```bash CLI
  ant organization:service-accounts list --limit 20
  ```

  ```python Python
  client = anthropic.Anthropic()

  service_accounts = client.organization.service_accounts.list(limit=20)

  for service_account in service_accounts:
      print(f"{service_account.id}: {service_account.name}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  for await (const serviceAccount of client.organization.serviceAccounts.list({
    limit: 20
  })) {
    console.log(`${serviceAccount.id}: ${serviceAccount.name}`);
  }
  ```

  ```csharp C#
  AnthropicClient client = new();

  var page = await client.Organization.ServiceAccounts.List(new() { Limit = 20 });

  await foreach (var serviceAccount in page.Paginate())
  {
      Console.WriteLine($"{serviceAccount.ID}: {serviceAccount.Name}");
  }
  ```

  ```go Go
  client := anthropic.NewClient()

  serviceAccounts := client.Organization.ServiceAccounts.ListAutoPaging(context.Background(), anthropic.OrganizationServiceAccountListParams{
  	Limit: anthropic.Int(20),
  })

  for serviceAccounts.Next() {
  	serviceAccount := serviceAccounts.Current()
  	fmt.Printf("%s: %s\n", serviceAccount.ID, serviceAccount.Name)
  }
  if err := serviceAccounts.Err(); err != nil {
  	log.Fatal(err)
  }
  ```

  ```java Java
  import com.anthropic.models.organization.serviceaccounts.ServiceAccountListParams;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      var params = ServiceAccountListParams.builder()
          .limit(20)
          .build();
      var serviceAccounts = client.organization().serviceAccounts().list(params);

      for (var serviceAccount : serviceAccounts.autoPager()) {
          IO.println(serviceAccount.id() + ": " + serviceAccount.name());
      }
  }
  ```

  ```php PHP
  $client = new Client();

  $serviceAccounts = $client->organization->serviceAccounts->list(limit: 20);

  foreach ($serviceAccounts->getItems() as $serviceAccount) {
      echo "{$serviceAccount->id}: {$serviceAccount->name}\n";
  }
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  service_accounts = client.organization.service_accounts.list(limit: 20)

  service_accounts.data.each do |service_account|
    puts "#{service_account.id}: #{service_account.name}"
  end
  ```
</CodeGroup>

서비스 계정 보관(archive):

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS -X POST "https://api.anthropic.com/v1/organizations/service_accounts/svac_01ABCDEFabcdef0123456789XY/archive" \
    -H "authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
    -H "anthropic-version: 2023-06-01"
  ```

  ```bash CLI
  ant organization:service-accounts archive svac_01ABCDEFabcdef0123456789XY
  ```

  ```python Python
  client = anthropic.Anthropic()

  service_account = client.organization.service_accounts.archive(
      "svac_01ABCDEFabcdef0123456789XY"
  )

  print(f"id: {service_account.id}")
  print(f"archived_at: {service_account.archived_at}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const serviceAccount = await client.organization.serviceAccounts.archive(
    "svac_01ABCDEFabcdef0123456789XY"
  );

  console.log(`id: ${serviceAccount.id}`);
  console.log(`archived_at: ${serviceAccount.archived_at}`);
  ```

  ```csharp C#
  AnthropicClient client = new();

  var serviceAccount = await client.Organization.ServiceAccounts.Archive(
      "svac_01ABCDEFabcdef0123456789XY"
  );

  Console.WriteLine($"id: {serviceAccount.ID}");
  Console.WriteLine($"archived_at: {serviceAccount.ArchivedAt:O}");
  ```

  ```go Go
  client := anthropic.NewClient()

  serviceAccount, err := client.Organization.ServiceAccounts.Archive(
  	context.Background(),
  	"svac_01ABCDEFabcdef0123456789XY",
  )
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("id: %s\n", serviceAccount.ID)
  fmt.Printf("archived_at: %s\n", serviceAccount.ArchivedAt)
  ```

  ```java Java
  AnthropicClient client = AnthropicOkHttpClient.fromEnv();

  var serviceAccount = client.organization().serviceAccounts()
      .archive("svac_01ABCDEFabcdef0123456789XY");

  IO.println("id: " + serviceAccount.id());
  IO.println("archived_at: " + serviceAccount.archivedAt().orElseThrow());
  ```

  ```php PHP
  $client = new Client();

  $serviceAccount = $client->organization->serviceAccounts->archive(
      serviceAccountID: 'svac_01ABCDEFabcdef0123456789XY',
  );

  echo "id: {$serviceAccount->id}\n";
  echo "archived_at: {$serviceAccount->archivedAt?->format(DATE_ATOM)}\n";
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  service_account_id = "svac_01ABCDEFabcdef0123456789XY"
  service_account = client.organization.service_accounts.archive(service_account_id)

  puts "id: #{service_account.id}"
  puts "archived_at: #{service_account.archived_at}"
  ```
</CodeGroup>

생성 엔드포인트는 새 서비스 계정을 반환합니다:

```json
{
  "id": "svac_...",
  "name": "inference-worker",
  "organization_role": "developer",
  "created_at": "...",
  "type": "service_account",
  "...": "..."
}
```

단일 서비스 계정을 읽거나 업데이트하려면 `/v1/organizations/service_accounts/{service_account_id}`에 `GET` 및 `POST`를 사용하세요. 페더레이션된 토큰이 워크스페이스에서 동작하려면 서비스 계정이 먼저 해당 워크스페이스의 구성원이어야 합니다. 모든 서비스 계정은 조직의 기본 워크스페이스에 암묵적 멤버십을 가집니다. 다른 워크스페이스에 대한 명시적 멤버십은 `/v1/organizations/service_accounts/{service_account_id}/workspaces`에 `GET`, `POST`, `DELETE`를 사용하여 추가하세요. 여기서 `DELETE`는 `.../workspaces/{workspace_id}`를 대상으로 합니다.

전체 매개변수 세부 정보와 응답 스키마는 [서비스 계정 API 레퍼런스](https://platform.claude.com/docs/ko/api/organization/service_accounts)를 참조하세요.

## 페더레이션 발급자

[페더레이션 발급자](https://platform.claude.com/docs/ko/manage-claude/workload-identity-federation#federation-issuers)(`fdis_...`)는 OIDC ID 공급자를 조직에 등록합니다. `jwks` 필드는 Anthropic이 공급자의 서명 키를 가져오는 방식을 제어하는 구별된 유니온(discriminated union)입니다:

| `jwks` 값                                 | 사용 시점                                                        |
| ---------------------------------------- | ------------------------------------------------------------ |
| `{"type": "discovery"}`                  | 공급자가 발급자 URL에서 `/.well-known/openid-configuration`을 제공하는 경우. |
| `{"type": "explicit_url", "url": "..."}` | JWKS 엔드포인트를 직접 가리키는 경우.                                      |
| `{"type": "inline", "keys": [...]}`      | 공용 인터넷에서 접근할 수 없는 공급자를 위해 키 세트를 업로드하는 경우.                    |

발급자를 등록합니다. 이 예제는 JWKS discovery로 GitHub Actions를 등록합니다:

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS "https://api.anthropic.com/v1/organizations/federation_issuers" \
    -H "authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
    -H "anthropic-version: 2023-06-01" \
    -H "content-type: application/json" \
    -d '{
      "name": "github-actions",
      "issuer_url": "https://token.actions.githubusercontent.com",
      "jwks": {"type": "discovery"}
    }'
  ```

  ```bash CLI
  ant organization:federation:issuers create \
    --name github-actions \
    --issuer-url https://token.actions.githubusercontent.com \
    --jwks '{type: discovery}'
  ```

  ```python Python
  client = anthropic.Anthropic()

  issuer = client.organization.federation.issuers.create(
      name="github-actions",
      issuer_url="https://token.actions.githubusercontent.com",
      jwks={"type": "discovery"},
  )

  print(f"id: {issuer.id}")
  print(f"name: {issuer.name}")
  print(f"issuer_url: {issuer.issuer_url}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const issuer = await client.organization.federation.issuers.create({
    name: "github-actions",
    issuer_url: "https://token.actions.githubusercontent.com",
    jwks: { type: "discovery" }
  });

  console.log(`id: ${issuer.id}`);
  console.log(`name: ${issuer.name}`);
  console.log(`issuer_url: ${issuer.issuer_url}`);
  ```

  ```csharp C#
  using Anthropic.Models.Organization.Federation.Issuers;

  AnthropicClient client = new();

  var issuer = await client.Organization.Federation.Issuers.Create(new()
  {
      Name = "github-actions",
      IssuerUrl = "https://token.actions.githubusercontent.com",
      Jwks = new JwksDiscovery()
  });

  Console.WriteLine($"id: {issuer.ID}");
  Console.WriteLine($"name: {issuer.Name}");
  Console.WriteLine($"issuer_url: {issuer.IssuerUrl}");
  ```

  ```go Go
  client := anthropic.NewClient()

  issuer, err := client.Organization.Federation.Issuers.New(context.Background(), anthropic.OrganizationFederationIssuerNewParams{
  	Name:      "github-actions",
  	IssuerURL: "https://token.actions.githubusercontent.com",
  	JWKS: anthropic.OrganizationFederationIssuerNewParamsJWKSUnion{
  		OfDiscovery: &anthropic.JWKSDiscoveryParam{},
  	},
  })
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("id: %s\n", issuer.ID)
  fmt.Printf("name: %s\n", issuer.Name)
  fmt.Printf("issuer_url: %s\n", issuer.IssuerURL)
  ```

  ```java Java
  import com.anthropic.models.organization.federation.issuers.JwksDiscovery;
  import com.anthropic.models.organization.federation.issuers.IssuerCreateParams;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      var params = IssuerCreateParams.builder()
          .name("github-actions")
          .issuerUrl("https://token.actions.githubusercontent.com")
          .jwks(JwksDiscovery.builder().build())
          .build();
      var issuer = client.organization().federation().issuers().create(params);

      IO.println("id: " + issuer.id());
      IO.println("name: " + issuer.name());
      IO.println("issuer_url: " + issuer.issuerUrl());
  }
  ```

  ```php PHP
  $client = new Client();

  $issuer = $client->organization->federation->issuers->create(
      name: 'github-actions',
      issuerURL: 'https://token.actions.githubusercontent.com',
      jwks: ['type' => 'discovery'],
  );

  echo "id: {$issuer->id}\n";
  echo "name: {$issuer->name}\n";
  echo "issuer_url: {$issuer->issuerURL}\n";
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  issuer = client.organization.federation.issuers.create(
    name: "github-actions",
    issuer_url: "https://token.actions.githubusercontent.com",
    jwks: {type: :discovery}
  )

  puts "id: #{issuer.id}"
  puts "name: #{issuer.name}"
  puts "issuer_url: #{issuer.issuer_url}"
  ```
</CodeGroup>

발급자 목록 조회:

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS "https://api.anthropic.com/v1/organizations/federation_issuers?limit=20" \
    -H "authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
    -H "anthropic-version: 2023-06-01"
  ```

  ```bash CLI
  ant organization:federation:issuers list --limit 20
  ```

  ```python Python
  client = anthropic.Anthropic()

  issuers = client.organization.federation.issuers.list(limit=20)

  for issuer in issuers:
      print(f"{issuer.id}: {issuer.name}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  for await (const issuer of client.organization.federation.issuers.list({ limit: 20 })) {
    console.log(`${issuer.id}: ${issuer.name}`);
  }
  ```

  ```csharp C#
  AnthropicClient client = new();

  var page = await client.Organization.Federation.Issuers.List(new() { Limit = 20 });

  await foreach (var issuer in page.Paginate())
  {
      Console.WriteLine($"{issuer.ID}: {issuer.Name}");
  }
  ```

  ```go Go
  client := anthropic.NewClient()

  issuers := client.Organization.Federation.Issuers.ListAutoPaging(context.Background(), anthropic.OrganizationFederationIssuerListParams{
  	Limit: anthropic.Int(20),
  })

  for issuers.Next() {
  	issuer := issuers.Current()
  	fmt.Printf("%s: %s\n", issuer.ID, issuer.Name)
  }
  if err := issuers.Err(); err != nil {
  	log.Fatal(err)
  }
  ```

  ```java Java
  import com.anthropic.models.organization.federation.issuers.IssuerListParams;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      var params = IssuerListParams.builder()
          .limit(20)
          .build();
      var issuers = client.organization().federation().issuers().list(params);

      for (var issuer : issuers.autoPager()) {
          IO.println(issuer.id() + ": " + issuer.name());
      }
  }
  ```

  ```php PHP
  $client = new Client();

  $issuers = $client->organization->federation->issuers->list(limit: 20);

  foreach ($issuers->getItems() as $issuer) {
      echo "{$issuer->id}: {$issuer->name}\n";
  }
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  issuers = client.organization.federation.issuers.list(limit: 20)

  issuers.data.each do |issuer|
    puts "#{issuer.id}: #{issuer.name}"
  end
  ```
</CodeGroup>

발급자 보관:

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS -X POST "https://api.anthropic.com/v1/organizations/federation_issuers/fdis_01ABCDEFabcdef0123456789XY/archive" \
    -H "authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
    -H "anthropic-version: 2023-06-01"
  ```

  ```bash CLI
  ant organization:federation:issuers archive \
    --federation-issuer-id fdis_01ABCDEFabcdef0123456789XY
  ```

  ```python Python
  client = anthropic.Anthropic()

  issuer = client.organization.federation.issuers.archive(
      "fdis_01ABCDEFabcdef0123456789XY"
  )

  print(f"id: {issuer.id}")
  print(f"archived_at: {issuer.archived_at}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const issuer = await client.organization.federation.issuers.archive(
    "fdis_01ABCDEFabcdef0123456789XY"
  );

  console.log(`id: ${issuer.id}`);
  console.log(`archived_at: ${issuer.archived_at}`);
  ```

  ```csharp C#
  AnthropicClient client = new();

  var issuer = await client.Organization.Federation.Issuers.Archive(
      "fdis_01ABCDEFabcdef0123456789XY"
  );

  Console.WriteLine($"id: {issuer.ID}");
  Console.WriteLine($"archived_at: {issuer.ArchivedAt:O}");
  ```

  ```go Go
  client := anthropic.NewClient()

  issuer, err := client.Organization.Federation.Issuers.Archive(
  	context.Background(),
  	"fdis_01ABCDEFabcdef0123456789XY",
  )
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("id: %s\n", issuer.ID)
  fmt.Printf("archived_at: %s\n", issuer.ArchivedAt)
  ```

  ```java Java
  AnthropicClient client = AnthropicOkHttpClient.fromEnv();

  var issuer = client.organization().federation().issuers()
      .archive("fdis_01ABCDEFabcdef0123456789XY");

  IO.println("id: " + issuer.id());
  IO.println("archived_at: " + issuer.archivedAt().orElseThrow());
  ```

  ```php PHP
  $client = new Client();

  $issuer = $client->organization->federation->issuers->archive(
      federationIssuerID: 'fdis_01ABCDEFabcdef0123456789XY',
  );

  echo "id: {$issuer->id}\n";
  echo "archived_at: {$issuer->archivedAt?->format(DATE_ATOM)}\n";
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  issuer_id = "fdis_01ABCDEFabcdef0123456789XY"
  issuer = client.organization.federation.issuers.archive(issuer_id)

  puts "id: #{issuer.id}"
  puts "archived_at: #{issuer.archived_at}"
  ```
</CodeGroup>

단일 발급자를 읽거나 업데이트하려면 `/v1/organizations/federation_issuers/{issuer_id}`에 `GET` 및 `POST`를 사용하세요. OAuth 호출자는 `oauth_scope`가 `workspace:developer` 또는 `workspace:inference` 이외의 값인 규칙을 뒷받침하는 발급자를 업데이트할 수 없습니다. [권한 및 제약 조건](https://platform.claude.com/docs/ko/manage-claude/wif-admin-api#permissions-and-constraints)을 참조하세요.

전체 매개변수 세부 정보와 응답 스키마는 [페더레이션 발급자 API 레퍼런스](https://platform.claude.com/docs/ko/api/organization/federation/issuers)를 참조하세요.

## 페더레이션 규칙

[페더레이션 규칙](https://platform.claude.com/docs/ko/manage-claude/workload-identity-federation#federation-rules)(`fdrl_...`)은 발급자를 서비스 계정에 바인딩합니다. 규칙의 매칭 조건을 충족하는 발급자의 JWT는 규칙의 대상으로 동작하는 토큰을 발급할 수 있습니다. 생성 요청의 `workspace_id`는 생성 시 해당 워크스페이스에서 규칙을 활성화합니다. 나중에 `/federation_rules/{rule_id}/workspaces` 하위 리소스를 통해 더 많은 워크스페이스를 추가하세요. 생성 시 `workspace_id` 또는 `applies_to_all_workspaces: true` 중 하나가 필요합니다.

규칙을 생성합니다. 이 예제는 main 브랜치에서의 GitHub Actions 배포가 서비스 계정으로 동작하도록 허용합니다:

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS "https://api.anthropic.com/v1/organizations/federation_rules" \
    -H "authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
    -H "anthropic-version: 2023-06-01" \
    -H "content-type: application/json" \
    -d '{
      "name": "gha-deploy",
      "issuer_id": "fdis_01ABCDEFabcdef0123456789XY",
      "match": {
        "subject_prefix": "repo:my-org/my-repo:ref:refs/heads/main",
        "claims": {"repository_owner": "my-org"}
      },
      "target": {
        "type": "service_account",
        "service_account_id": "svac_01ABCDEFabcdef0123456789XY"
      },
      "workspace_id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
      "oauth_scope": "workspace:developer",
      "token_lifetime_seconds": 600
    }'
  ```

  ```bash CLI
  ant organization:federation:rules create <<'YAML'
  name: gha-deploy
  issuer_id: fdis_01ABCDEFabcdef0123456789XY
  match:
    subject_prefix: "repo:my-org/my-repo:ref:refs/heads/main"
    claims:
      repository_owner: my-org
  target:
    type: service_account
    service_account_id: svac_01ABCDEFabcdef0123456789XY
  workspace_id: wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ
  oauth_scope: "workspace:developer"
  token_lifetime_seconds: 600
  YAML
  ```

  ```python Python
  client = anthropic.Anthropic()

  rule = client.organization.federation.rules.create(
      name="gha-deploy",
      issuer_id="fdis_01ABCDEFabcdef0123456789XY",
      match={
          "subject_prefix": "repo:my-org/my-repo:ref:refs/heads/main",
          "claims": {"repository_owner": "my-org"},
      },
      target={
          "type": "service_account",
          "service_account_id": "svac_01ABCDEFabcdef0123456789XY",
      },
      workspace_id="wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
      oauth_scope="workspace:developer",
      token_lifetime_seconds=600,
  )

  print(f"id: {rule.id}")
  print(f"name: {rule.name}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const rule = await client.organization.federation.rules.create({
    name: "gha-deploy",
    issuer_id: "fdis_01ABCDEFabcdef0123456789XY",
    match: {
      subject_prefix: "repo:my-org/my-repo:ref:refs/heads/main",
      claims: { repository_owner: "my-org" }
    },
    target: {
      type: "service_account",
      service_account_id: "svac_01ABCDEFabcdef0123456789XY"
    },
    workspace_id: "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
    oauth_scope: "workspace:developer",
    token_lifetime_seconds: 600
  });

  console.log(`id: ${rule.id}`);
  console.log(`name: ${rule.name}`);
  ```

  ```csharp C#
  AnthropicClient client = new();

  var rule = await client.Organization.Federation.Rules.Create(new()
  {
      Name = "gha-deploy",
      IssuerID = "fdis_01ABCDEFabcdef0123456789XY",
      Match = new()
      {
          SubjectPrefix = "repo:my-org/my-repo:ref:refs/heads/main",
          Claims = new Dictionary<string, string> { ["repository_owner"] = "my-org" }
      },
      Target = new() { ServiceAccountID = "svac_01ABCDEFabcdef0123456789XY" },
      WorkspaceID = "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
      OAuthScope = "workspace:developer",
      TokenLifetimeSeconds = 600
  });

  Console.WriteLine($"id: {rule.ID}");
  Console.WriteLine($"name: {rule.Name}");
  ```

  ```go Go
  client := anthropic.NewClient()

  rule, err := client.Organization.Federation.Rules.New(context.Background(), anthropic.OrganizationFederationRuleNewParams{
  	Name:     "gha-deploy",
  	IssuerID: "fdis_01ABCDEFabcdef0123456789XY",
  	Match: anthropic.FederationRuleMatchParam{
  		SubjectPrefix: anthropic.String("repo:my-org/my-repo:ref:refs/heads/main"),
  		Claims:        map[string]string{"repository_owner": "my-org"},
  	},
  	Target: anthropic.ServiceAccountTargetParam{
  		ServiceAccountID: "svac_01ABCDEFabcdef0123456789XY",
  	},
  	WorkspaceID:          anthropic.String("wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"),
  	OAuthScope:           "workspace:developer",
  	TokenLifetimeSeconds: anthropic.Int(600),
  })
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("id: %s\n", rule.ID)
  fmt.Printf("name: %s\n", rule.Name)
  ```

  ```java Java
  import com.anthropic.core.JsonValue;
  import com.anthropic.models.organization.federation.rules.FederationRuleMatch;
  import com.anthropic.models.organization.federation.rules.ServiceAccountTarget;
  import com.anthropic.models.organization.federation.rules.RuleCreateParams;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      var match = FederationRuleMatch.builder()
          .subjectPrefix("repo:my-org/my-repo:ref:refs/heads/main")
          .claims(FederationRuleMatch.Claims.builder()
              .putAdditionalProperty("repository_owner", JsonValue.from("my-org"))
              .build())
          .build();
      var params = RuleCreateParams.builder()
          .name("gha-deploy")
          .issuerId("fdis_01ABCDEFabcdef0123456789XY")
          .match(match)
          .target(ServiceAccountTarget.of("svac_01ABCDEFabcdef0123456789XY"))
          .workspaceId("wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ")
          .oauthScope("workspace:developer")
          .tokenLifetimeSeconds(600)
          .build();
      var rule = client.organization().federation().rules().create(params);

      IO.println("id: " + rule.id());
      IO.println("name: " + rule.name());
  }
  ```

  ```php PHP
  $client = new Client();

  $rule = $client->organization->federation->rules->create(
      name: 'gha-deploy',
      issuerID: 'fdis_01ABCDEFabcdef0123456789XY',
      match: [
          'subjectPrefix' => 'repo:my-org/my-repo:ref:refs/heads/main',
          'claims' => ['repository_owner' => 'my-org'],
      ],
      target: [
          'type' => 'service_account',
          'serviceAccountID' => 'svac_01ABCDEFabcdef0123456789XY',
      ],
      workspaceID: 'wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ',
      oauthScope: 'workspace:developer',
      tokenLifetimeSeconds: 600,
  );

  echo "id: {$rule->id}\n";
  echo "name: {$rule->name}\n";
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  rule = client.organization.federation.rules.create(
    name: "gha-deploy",
    issuer_id: "fdis_01ABCDEFabcdef0123456789XY",
    match: {
      subject_prefix: "repo:my-org/my-repo:ref:refs/heads/main",
      claims: {repository_owner: "my-org"}
    },
    target: {
      type: :service_account,
      service_account_id: "svac_01ABCDEFabcdef0123456789XY"
    },
    workspace_id: "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
    oauth_scope: "workspace:developer",
    token_lifetime_seconds: 600
  )

  puts "id: #{rule.id}"
  puts "name: #{rule.name}"
  ```
</CodeGroup>

규칙 목록 조회(선택적으로 발급자로 필터링):

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS "https://api.anthropic.com/v1/organizations/federation_rules?issuer_id=fdis_01ABCDEFabcdef0123456789XY" \
    -H "authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
    -H "anthropic-version: 2023-06-01"
  ```

  ```bash CLI
  ant organization:federation:rules list \
    --issuer-id fdis_01ABCDEFabcdef0123456789XY
  ```

  ```python Python
  client = anthropic.Anthropic()

  rules = client.organization.federation.rules.list(
      issuer_id="fdis_01ABCDEFabcdef0123456789XY"
  )

  for rule in rules:
      print(f"{rule.id}: {rule.name}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  for await (const rule of client.organization.federation.rules.list({
    issuer_id: "fdis_01ABCDEFabcdef0123456789XY"
  })) {
    console.log(`${rule.id}: ${rule.name}`);
  }
  ```

  ```csharp C#
  AnthropicClient client = new();

  var page = await client.Organization.Federation.Rules.List(new()
  {
      IssuerID = "fdis_01ABCDEFabcdef0123456789XY"
  });

  await foreach (var rule in page.Paginate())
  {
      Console.WriteLine($"{rule.ID}: {rule.Name}");
  }
  ```

  ```go Go
  client := anthropic.NewClient()

  rules := client.Organization.Federation.Rules.ListAutoPaging(context.Background(), anthropic.OrganizationFederationRuleListParams{
  	IssuerID: anthropic.String("fdis_01ABCDEFabcdef0123456789XY"),
  })

  for rules.Next() {
  	rule := rules.Current()
  	fmt.Printf("%s: %s\n", rule.ID, rule.Name)
  }
  if err := rules.Err(); err != nil {
  	log.Fatal(err)
  }
  ```

  ```java Java
  import com.anthropic.models.organization.federation.rules.RuleListParams;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      var params = RuleListParams.builder()
          .issuerId("fdis_01ABCDEFabcdef0123456789XY")
          .build();
      var rules = client.organization().federation().rules().list(params);

      for (var rule : rules.autoPager()) {
          IO.println(rule.id() + ": " + rule.name());
      }
  }
  ```

  ```php PHP
  $client = new Client();

  $rules = $client->organization->federation->rules->list(
      issuerID: 'fdis_01ABCDEFabcdef0123456789XY',
  );

  foreach ($rules->getItems() as $rule) {
      echo "{$rule->id}: {$rule->name}\n";
  }
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  rules = client.organization.federation.rules.list(
    issuer_id: "fdis_01ABCDEFabcdef0123456789XY"
  )

  rules.data.each do |rule|
    puts "#{rule.id}: #{rule.name}"
  end
  ```
</CodeGroup>

규칙 보관:

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS -X POST "https://api.anthropic.com/v1/organizations/federation_rules/fdrl_01ABCDEFabcdef0123456789XY/archive" \
    -H "authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
    -H "anthropic-version: 2023-06-01"
  ```

  ```bash CLI
  ant organization:federation:rules archive \
    --federation-rule-id fdrl_01ABCDEFabcdef0123456789XY
  ```

  ```python Python
  client = anthropic.Anthropic()

  rule = client.organization.federation.rules.archive("fdrl_01ABCDEFabcdef0123456789XY")

  print(f"id: {rule.id}")
  print(f"archived_at: {rule.archived_at}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const rule = await client.organization.federation.rules.archive(
    "fdrl_01ABCDEFabcdef0123456789XY"
  );

  console.log(`id: ${rule.id}`);
  console.log(`archived_at: ${rule.archived_at}`);
  ```

  ```csharp C#
  AnthropicClient client = new();

  var rule = await client.Organization.Federation.Rules.Archive(
      "fdrl_01ABCDEFabcdef0123456789XY"
  );

  Console.WriteLine($"id: {rule.ID}");
  Console.WriteLine($"archived_at: {rule.ArchivedAt:O}");
  ```

  ```go Go
  client := anthropic.NewClient()

  rule, err := client.Organization.Federation.Rules.Archive(
  	context.Background(),
  	"fdrl_01ABCDEFabcdef0123456789XY",
  )
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("id: %s\n", rule.ID)
  fmt.Printf("archived_at: %s\n", rule.ArchivedAt)
  ```

  ```java Java
  AnthropicClient client = AnthropicOkHttpClient.fromEnv();

  var rule = client.organization().federation().rules()
      .archive("fdrl_01ABCDEFabcdef0123456789XY");

  IO.println("id: " + rule.id());
  IO.println("archived_at: " + rule.archivedAt().orElseThrow());
  ```

  ```php PHP
  $client = new Client();

  $rule = $client->organization->federation->rules->archive(
      federationRuleID: 'fdrl_01ABCDEFabcdef0123456789XY',
  );

  echo "id: {$rule->id}\n";
  echo "archived_at: {$rule->archivedAt?->format(DATE_ATOM)}\n";
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  rule_id = "fdrl_01ABCDEFabcdef0123456789XY"
  rule = client.organization.federation.rules.archive(rule_id)

  puts "id: #{rule.id}"
  puts "archived_at: #{rule.archived_at}"
  ```
</CodeGroup>

목록 엔드포인트는 규칙 한 페이지와 다음 페이지를 위한 커서를 반환합니다:

```json
{
  "data": [{ "id": "fdrl_...", "name": "gha-deploy", "...": "..." }],
  "next_page": "..."
}
```

단일 규칙을 읽거나 업데이트하려면 `/v1/organizations/federation_rules/{rule_id}`에 `GET` 및 `POST`를 사용하세요. 규칙이 토큰을 발급할 수 있는 워크스페이스를 관리하려면 `/v1/organizations/federation_rules/{rule_id}/workspaces`에 `GET` 및 `POST`를, `/v1/organizations/federation_rules/{rule_id}/workspaces/{workspace_id}`에 `DELETE`를 사용하세요.

전체 매개변수 세부 정보와 응답 스키마는 [페더레이션 규칙 API 레퍼런스](https://platform.claude.com/docs/ko/api/organization/federation/rules)를 참조하세요.

## 권한 및 제약 조건

<Note>
  * OAuth로 인증된 호출자는 `oauth_scope`가 `workspace:developer` 또는 `workspace:inference`인 규칙만 생성하거나 수정할 수 있습니다. 다른 스코프(예: `org:admin` 또는 `workspace:manage_tunnels`)를 가진 규칙을 생성하거나 수정하려면 Console을 사용하세요.
  * OAuth 호출자는 `oauth_scope`가 `workspace:developer` 또는 `workspace:inference` 이외의 값(예: `org:admin` 또는 `workspace:manage_tunnels`)인 규칙을 뒷받침하는 페더레이션 발급자를 업데이트할 수 없습니다. 워크스페이스 범위 규칙 뒤의 발급자들이 API를 통해 계속 업데이트 가능하도록, 부트스트랩 규칙을 위한 전용 발급자를 등록하는 것을 고려하세요.
  * Admin API 키는 읽기든 쓰기든 이 엔드포인트들에서 허용되지 않습니다. `org:admin` OAuth 토큰을 사용하세요.
</Note>

`oauth_scope: org:admin`인 규칙은 `organization_role`이 `admin`인 서비스 계정을 대상으로 해야 합니다. 리소스 이름은 `^[a-z0-9-]+$`와 일치해야 하고, 1\~255자여야 하며, 각 리소스 유형별로 조직 내에서 고유해야 합니다. 전체 필드 수준 제약 조건은 [유효성 검사 규칙](https://platform.claude.com/docs/ko/manage-claude/wif-reference#validation-rules)을 참조하세요.

## 페이지네이션 및 보관

서비스 계정, 페더레이션 발급자, 페더레이션 규칙 목록 엔드포인트는 `limit`(1\~100, 기본값 20)과 이전 응답에서 가져온 `page` 커서를 받습니다. 응답의 `next_page` 값을 다음 요청의 `page` 쿼리 매개변수로 전달하세요. 규칙-워크스페이스 하위 리소스 목록은 페이지네이션 없이 전체 세트를 반환합니다. 보관된 리소스는 기본적으로 목록에서 숨겨집니다. 포함하려면 `include_archived=true`를 전달하세요.

보관은 소프트 삭제이며 멱등적입니다. 이미 보관된 리소스를 보관해도 성공합니다. 활성 페더레이션 규칙이 여전히 참조하고 있는 동안 발급자나 서비스 계정을 보관하면 `400`이 반환됩니다. 먼저 규칙을 보관하세요.

## 참고 항목

* [Workload Identity Federation](https://platform.claude.com/docs/ko/manage-claude/workload-identity-federation): 개념 및 Console 설정 안내
* [WIF 레퍼런스](https://platform.claude.com/docs/ko/manage-claude/wif-reference): 환경 변수, 유효성 검사 규칙, OAuth 스코프, 오류 코드
* [Admin API](https://platform.claude.com/docs/ko/manage-claude/admin-api): 나머지 조직 관리 기능
* [Admin API 레퍼런스](https://platform.claude.com/docs/ko/api/organization): 서비스 계정 및 페더레이션 엔드포인트에 대해 생성된 요청 및 응답 스키마
