---
title: "Create Federation Rule"
method: POST
path: "/v1/organizations/federation_rules?beta=true"
---

# Create Federation Rule

`POST /v1/organizations/federation_rules?beta=true`

**Requires an OAuth access token with the `org:admin` scope**, from `ant auth login --scope org:admin` or a workload identity federation rule; Admin API keys are not accepted. See [Manage WIF with the Admin API](/docs/en/manage-claude/wif-admin-api).

Create a federation rule owned by your organization.

The referenced issuer and the target service account must already exist
in the same organization; invalid references are rejected with a 400
error. The workspace reference is validated. Membership is not checked
at rule creation: token exchange resolves a single enabled workspace per
call and is rejected unless the target service account is a member of
that workspace (it is implicitly a member of the default workspace).
Rules on well-known shared issuers (GitHub Actions, GitLab, Buildkite,
Terraform Cloud, Google) must constrain tenant identity via an
identity-bearing claim, a tenant-pinning subject prefix (such as
`repo:YOUR_ORG/...`), or a CEL condition referencing one of those
identity claims (e.g. `claims.repository_owner`). OAuth callers may only
manage rules whose `oauth_scope` is `workspace:developer` or
`workspace:inference`; other scopes require a Console session.

## Headers

- `anthropic-beta` string — Optional header to specify the beta version(s) you want to use. To use multiple betas, use a comma separated list like `beta1,beta2` or specify the header multiple times for each beta.
- `anthropic-version` string — The version of the Claude API you want to use. Read more about versioning and our version history [here](https://platform.claude.com/docs/en/api/versioning).

## Request body

- BetaFederationRuleCreateParams
  - `applies_to_all_workspaces` boolean — When true, enable this rule for every workspace in the org (including workspaces created later).
  - `attributes` object, nullable — CEL expressions `{name: expr}` extracting named values from claims. Not yet supported; any non-empty value is rejected with 400.
  - `description` string, nullable — Optional free-text description.
  - `issuer_id` string, required — Tagged ID of the federation issuer.
  - `match` BetaRuleMatch, required — Does the incoming JWT qualify? All populated fields must pass; omitted fields are skipped. At least one of `subject_prefix` (other than a wildcard-only value like `*`), `claims`, or `condition` is required; `audience` alone is not sufficient.
    - `audience` string, nullable — Exact match against the `aud` claim (any element if array). When omitted, the JWT's `aud` must still equal Anthropic's expected audience for the issuer; setting this field overrides that default.
    - `claims` object, nullable — Exact-match `{claim: value}` pairs against top-level claims. Only string-valued claims can be matched; use `condition` for non-string claims.
    - `condition` string, nullable — CEL expression over claims for logic the structural fields can't express. Must evaluate to a boolean and may reference only the `claims` variable; a constant-true expression (such as `true`) is rejected with 400.
    - `subject_prefix` string, nullable — Match the verified JWT `sub` claim. Exact match unless the value ends with `*`, in which case it is a prefix match. Example: `repo:my-org/my-repo:ref:refs/heads/main`.
  - `name` string, required — Slug identifier (lowercase, digits, hyphens). Unique within the organization; a duplicate name returns 409.
  - `oauth_scope` string, required — Space-separated OAuth scopes. OAuth callers may only set `workspace:developer` or `workspace:inference`; other scopes (such as `org:admin`) require a Console session.
  - `target` BetaServiceAccountTarget, required — Bind to a fixed service account by ID.
    - `service_account_id` string, required — Tagged ID of the service account to mint tokens for.
    - `service_account_name` string, nullable — Service account's display name at read time. Ignored on writes.
    - `type` 'service_account', required
  - `token_lifetime_seconds` integer — Lifetime in seconds for access tokens minted via this rule (60-86400). Defaults to 3600 (1h). Minted tokens are capped at `max(60, min(this value, 2 × remaining assertion validity))` seconds.
  - `workspace_id` string, nullable — Tagged ID of the workspace to enable this rule for. Required unless `applies_to_all_workspaces` is true. Additional workspaces can be added via the `/federation_rules/{federation_rule_id}/workspaces` sub-resource.

## Response `200`

Successful Response

- BetaFederationRule — Authorization rule binding an external OIDC identity to Anthropic. Evaluates the match conditions and mints an OAuth access token for the resolved target, scoped to a single workspace where the rule is enabled (chosen by the caller at exchange time when the rule is enabled for more than one). For rules enabled via `workspace_ids` or `applies_to_all_workspaces`, the target service account must be a member of that workspace (it is implicitly a member of the default workspace); rules carrying only the legacy `workspace_id` binding do not enforce this.
  - `applies_to_all_workspaces` boolean, required — When true, this rule is enabled for every workspace in the org (including ones created after the rule). `workspace_ids` is ignored at exchange time.
  - `archived_at` string, date-time, nullable, required — If set, this rule is archived and rejects token exchange.
  - `archived_by_actor_id` string, nullable, required — Tagged ID (`user_`/`svac_`) of the actor that archived this rule.
  - `attributes` object, nullable, required — CEL expressions extracting named values from claims. Not yet supported; always null.
  - `created_at` string, date-time, required — When this rule was created.
  - `created_by_actor_id` string, nullable, required — Tagged ID (`user_`/`svac_`) of the actor that created this rule.
  - `description` string, nullable, required — Optional free-text description.
  - `id` string, required — Tagged ID of the federation rule.
  - `issuer_id` string, required — Tagged ID of the issuer whose tokens this rule accepts.
  - `issuer_name` string, nullable, required — Issuer's display name at read time.
  - `match` BetaRuleMatch, required — Does the incoming JWT qualify? All populated fields must pass; omitted fields are skipped. At least one of `subject_prefix` (other than a wildcard-only value like `*`), `claims`, or `condition` is required; `audience` alone is not sufficient.
    - `audience` string, nullable — Exact match against the `aud` claim (any element if array). When omitted, the JWT's `aud` must still equal Anthropic's expected audience for the issuer; setting this field overrides that default.
    - `claims` object, nullable — Exact-match `{claim: value}` pairs against top-level claims. Only string-valued claims can be matched; use `condition` for non-string claims.
    - `condition` string, nullable — CEL expression over claims for logic the structural fields can't express. Must evaluate to a boolean and may reference only the `claims` variable; a constant-true expression (such as `true`) is rejected with 400.
    - `subject_prefix` string, nullable — Match the verified JWT `sub` claim. Exact match unless the value ends with `*`, in which case it is a prefix match. Example: `repo:my-org/my-repo:ref:refs/heads/main`.
  - `name` string, required — Admin-chosen slug identifier.
  - `oauth_scope` string, required — Space-separated OAuth scopes granted on the minted token.
  - `target` BetaServiceAccountTarget, required — Bind to a fixed service account by ID.
    - `service_account_id` string, required — Tagged ID of the service account to mint tokens for.
    - `service_account_name` string, nullable — Service account's display name at read time. Ignored on writes.
    - `type` 'service_account', required
  - `token_lifetime_seconds` integer, required — Lifetime in seconds of access tokens minted via this rule. Minted tokens are capped at `max(60, min(this value, 2 × remaining assertion validity))` seconds.
  - `type` 'federation_rule', required
  - `updated_at` string, date-time, required — When this rule was last updated.
  - `updated_by_actor_id` string, nullable, required — Tagged ID (`user_`/`svac_`) of the actor that last updated this rule.
  - `workspace_id` string, nullable, required — Legacy single-workspace binding. Prefer `workspace_ids` and the `/federation_rules/{federation_rule_id}/workspaces` sub-resource for managing workspace enablement.
  - `workspace_ids` string[], required — Tagged IDs of the workspaces this rule is enabled for. May be empty for older rules that only carry the legacy `workspace_id` binding. Ignored at exchange time when `applies_to_all_workspaces` is true (the list may still be non-empty).

## Other responses

- `400` — Invalid argument - The client specified an invalid argument
- `401` — Unauthenticated - The request does not have valid authentication credentials
- `403` — Permission denied - The caller does not have permission to execute the specified operation
- `404` — Not found - Some requested entity was not found
- `408` — Deadline exceeded - The deadline expired before the operation could complete
- `409` — Aborted - The operation was aborted due to concurrency issue
- `412` — Failed precondition - Operation was rejected because the system is not in required state
- `413` — Out of range - Operation was attempted past the valid range
- `429` — Resource exhausted - Some resource has been exhausted (rate limiting)
- `431` — Request header fields too large - Request metadata was too large
- `499` — Cancelled - The operation was cancelled by the client
- `500` — Internal - Internal server error
- `501` — Unimplemented - The operation is not implemented or supported
- `503` — Unavailable - The service is currently unavailable
- `504` — Deadline exceeded - Upstream service did not respond in time
- `529` — Overloaded - The service is temporarily overloaded

## Changes

- **2026-09-02** `4789294140a2` — 16 info
  - added the non-success response with the status `400`
  - added the non-success response with the status `401`
  - added the non-success response with the status `403`
  - added the non-success response with the status `404`
  - …12 more
- **2026-08-26** `942a11636c42` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/anthropics/apis/anthropic-api/changes/v1/organizations/federation_rules?beta=true/post.md)

---

[API](https://skmtc.dev/anthropics/apis/anthropic-api.md) · [All operations](https://skmtc.dev/anthropics/apis/anthropic-api/llms.txt) · [OpenAPI document](https://skmtc.dev/anthropics/apis/anthropic-api/revisions/1bb7c7a0a4a9?raw)
