• Mensajes
  • Agentes gestionados
  • Administración
Search...
⌘K
Organización
API de administraciónEspacios de trabajo
Autenticación
Descripción generalFederación de identidades de carga de trabajoReferencia de WIF
AWSGoogle CloudMicrosoft AzureGitHub ActionsKubernetesSPIFFEOkta
Monitoreo
API de uso y costosAPI de límites de velocidadAPI de análisis de Claude Code
Datos y cumplimiento
Residencia de datosAPI y retención de datos
API de cumplimiento
Descripción generalObtener accesoFeed de actividadChats, archivos y proyectosOrganizaciones, usuarios, roles y gruposDiseñar tu integraciónErroresPreguntas frecuentes
Log in
GitHub Actions
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...

Solutions

  • AI agents
  • Code modernization
  • Coding
  • Customer support
  • Education
  • Financial services
  • Government
  • Life sciences

Partners

  • Amazon Bedrock
  • Google Cloud's Vertex AI

Learn

  • Blog
  • Courses
  • Use cases
  • Connectors
  • Customer stories
  • Engineering at Anthropic
  • Events
  • Powered by Claude
  • Service partners
  • Startups program

Company

  • Anthropic
  • Careers
  • Economic Futures
  • Research
  • News
  • Responsible Scaling Policy
  • Security and compliance
  • Transparency

Learn

  • Blog
  • Courses
  • Use cases
  • Connectors
  • Customer stories
  • Engineering at Anthropic
  • Events
  • Powered by Claude
  • Service partners
  • Startups program

Help and security

  • Availability
  • Status
  • Support
  • Discord

Terms and policies

  • Privacy policy
  • Responsible disclosure policy
  • Terms of service: Commercial
  • Terms of service: Consumer
  • Usage policy
Administración/Proveedores de identidad

Usar WIF con GitHub Actions

Autentica flujos de trabajo de GitHub Actions en la API de Claude con tokens de identidad de corta duración en lugar de claves de API de larga duración.

Cada ejecución de un flujo de trabajo de GitHub Actions puede solicitar un token de identidad firmado al emisor alojado de GitHub en https://token.actions.githubusercontent.com. Con "Workload Identity Federation" (federación de identidades de cargas de trabajo), tu flujo de trabajo intercambia ese token por un token de acceso de Anthropic de corta duración, de modo que tus trabajos de CI puedan llamar a la API de Claude sin un secreto ANTHROPIC_API_KEY almacenado en tu repositorio.

El claim sub del token codifica el repositorio y el contexto del desencadenador. Para un push a una rama tiene la forma repo:<owner>/<repo>:ref:refs/heads/<branch>. Las ejecuciones de pull request usan repo:<owner>/<repo>:pull_request, y los despliegues controlados por entornos usan repo:<owner>/<repo>:environment:<name>. Tu regla de federación compara este claim (y otros, como repository_owner y ref) para decidir qué ejecuciones de flujo de trabajo tienen permitido autenticarse.

Requisitos previos

  • Familiaridad con los conceptos de WIF: cuentas de servicio, emisores de federación y reglas de federación.
  • Un repositorio de GitHub donde puedas editar archivos de flujo de trabajo y otorgar el permiso id-token: write.
  • Permiso para crear cuentas de servicio, emisores de federación y reglas de federación en Claude Console para tu organización de Anthropic.
  • El ID de tu organización de Anthropic. Puedes encontrarlo en Claude Console en Settings → Organization.

Configura tu flujo de trabajo

GitHub solo emite un token de identidad a los trabajos que lo solicitan explícitamente. Agrega el permiso id-token: write a nivel de flujo de trabajo o de trabajo:

permissions:
  id-token: write
  contents: read

Dentro del trabajo, el runner expone dos variables de entorno: ACTIONS_ID_TOKEN_REQUEST_URL y ACTIONS_ID_TOKEN_REQUEST_TOKEN. Llama a la URL de solicitud usando el token de solicitud como credencial bearer y tu audiencia elegida como parámetro de consulta, luego escribe el "JSON Web Token" (token web JSON), o JWT, devuelto en un archivo:

- name: Fetch GitHub OIDC token
  run: |
    curl -sS -H "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
      "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=https://api.anthropic.com" \
      | jq -r .value > /tmp/gha-jwt

Si prefieres JavaScript, actions/github-script expone la misma capacidad a través de core.getIDToken(audience):

- name: Fetch GitHub OIDC token
  uses: actions/github-script@v8
  with:
    script: |
      const fs = require('fs');
      const token = await core.getIDToken('https://api.anthropic.com');
      fs.writeFileSync('/tmp/gha-jwt', token);

El token decodificado contiene claims que describen la ejecución del flujo de trabajo. Tu regla de federación compara contra estos:

{
  "iss": "https://token.actions.githubusercontent.com",
  "sub": "repo:your-org/your-repo:ref:refs/heads/main",
  "aud": "https://api.anthropic.com",
  "repository": "your-org/your-repo",
  "repository_owner": "your-org",
  "ref": "refs/heads/main",
  "sha": "abc123...",
  "workflow": "CI",
  "actor": "octocat",
  "event_name": "push"
}

Consulta la referencia de claims de sujeto OIDC de GitHub para ver la lista completa de formatos de sub.

Configura Anthropic

Sigue la guía de configuración para registrar un emisor de federación, crear una cuenta de servicio de Anthropic y crear una regla de federación en Claude Console. Usa estos valores específicos de GitHub Actions.

Emisor de federación: GitHub publica su documento de descubrimiento OIDC y su JWKS de forma pública, así que usa el modo de descubrimiento. Anthropic actualiza las claves automáticamente cuando GitHub las rota.

{
  "name": "github-actions",
  "issuer_url": "https://token.actions.githubusercontent.com",
  "jwks_source": "discovery"
}

Regla de federación: Haz coincidir solo las ejecuciones de flujo de trabajo en las que pretendes confiar. Consulta Restringe qué flujos de trabajo pueden autenticarse para saber cómo delimitar estos claims de forma segura.

{
  "name": "gha-main",
  "issuer_id": "fdis_...",
  "match": {
    "subject_prefix": "repo:your-org/your-repo:ref:refs/heads/main",
    "audience": "https://api.anthropic.com",
    "claims": {
      "repository_owner": "your-org"
    }
  },
  "target": {
    "type": "service_account",
    "service_account_id": "svac_..."
  },
  "workspace_id": "wrkspc_...",
  "oauth_scope": "workspace:developer",
  "token_lifetime_seconds": 600
}

Sé tan específico como la carga de trabajo lo permita. Relaja subject_prefix a repo:your-org/your-repo:* (junto con una restricción claims.ref) solo si la regla debe coincidir con múltiples tipos de eventos del mismo repositorio, ya que el segmento final de sub varía entre eventos ref:..., environment:... y pull_request.

Obtén y usa un token

Establece las variables de entorno de federación en el trabajo y llama al SDK normalmente. Anthropic() lee ANTHROPIC_IDENTITY_TOKEN_FILE, intercambia el JWT en la primera solicitud y actualiza el token de acceso automáticamente antes de que expire.

Cada token de identidad emitido por GitHub expira aproximadamente cinco minutos después de su emisión. El endpoint de solicitud de token (ACTIONS_ID_TOKEN_REQUEST_URL) permanece válido durante todo el trabajo, por lo que puedes obtener un token nuevo en cualquier momento. El SDK intercambia el token en el primer uso y almacena en caché el token de acceso de Anthropic resultante. Para trabajos que se ejecutan durante más tiempo que la vida útil del token de Anthropic, el SDK vuelve a leer ANTHROPIC_IDENTITY_TOKEN_FILE en cada actualización, así que vuelve a ejecutar el paso de obtención periódicamente (o envuélvelo en un bucle en segundo plano) para mantener el archivo actualizado. Como alternativa, pasa al SDK un callback proveedor de tokens que llame directamente a ACTIONS_ID_TOKEN_REQUEST_URL en lugar de usar la ruta del archivo.

Verifica la configuración

Un intercambio exitoso devuelve un access_token que comienza con sk-ant-oat01- y un valor expires_in en segundos. Si recibes 400 invalid_grant, consulta Solucionar problemas de un intercambio fallido; la causa más común del lado de GitHub Actions es que el formato del claim sub no coincide (su segmento final varía entre eventos ref:..., environment:... y pull_request).

Restringe qué flujos de trabajo pueden autenticarse

Un subject_prefix de repo:your-org/* por sí solo coincide con todos los repositorios de tu organización, y sin una restricción de ref también coincide con ejecuciones de pull_request desencadenadas desde forks. Cualquiera que pueda abrir un pull request contra un repositorio coincidente podría obtener un token federado de Anthropic.

Limita el bloque match de la regla al alcance más estrecho que se ajuste a tu caso de uso:

  • Fija a un solo repositorio: Usa subject_prefix: "repo:your-org/your-repo:*" para que otros repositorios de la organización no coincidan.
  • Fija a una rama protegida: Agrega "ref": "refs/heads/main" (o tu rama de lanzamiento) bajo claims para que las ejecuciones de pull request y las ramas de funcionalidades no coincidan.
  • Fija el propietario explícitamente: Agrega "repository_owner": "your-org" bajo claims como una verificación de defensa en profundidad contra casos límite en el análisis de sub.
  • Fija a un entorno de despliegue: Para trabajos de despliegue, haz coincidir subject_prefix: "repo:your-org/your-repo:environment:production" y protege ese entorno con revisores obligatorios en GitHub.

Próximos pasos

  • Workload Identity Federation: guía completa de configuración, variables de entorno y precedencia de credenciales.
  • Autenticación: cómo se compara la federación con las claves de API.

Was this page helpful?

  • Requisitos previos
  • Configura tu flujo de trabajo
  • Configura Anthropic
  • Obtén y usa un token
  • Verifica la configuración
  • Restringe qué flujos de trabajo pueden autenticarse
  • Próximos pasos
import anthropic

# Lee ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID,
# ANTHROPIC_SERVICE_ACCOUNT_ID, ANTHROPIC_WORKSPACE_ID y ANTHROPIC_IDENTITY_TOKEN_FILE
# del entorno del trabajo.
client = anthropic.Anthropic()

message = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello, Claude"}],
)
print(message.content[0].text)