> ## Documentation Index
> Fetch the complete documentation index at: https://docs.basaltic.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# GitHub Actions

> Permite que GitHub Actions obtenga credenciales temporales de despliegue en Basaltic con la identidad del job.

Usa la identidad de un job de GitHub Actions para obtener una sesión temporal de despliegue en Basaltic. No necesitas almacenar una clave de acceso Basaltic de larga duración en GitHub.

El job solicita un JWT OIDC de GitHub y lo intercambia en el endpoint `AssumeRoleWithWebIdentity` de Basaltic. El token bearer resultante autoriza llamadas de despliegue a la API según las políticas del rol Basaltic.

## Registrar GitHub en la cuenta de despliegue

Sigue el [registro de proveedor](https://docs.basaltic.sh/es/iam/roles.md#trusting-an-oidc-provider) en la misma cuenta que el rol de despliegue. Usa estos valores:

> [tab] API
>
> ```json theme={null}
> {
>   "name": "github",
>   "issuer": "https://token.actions.githubusercontent.com",
>   "audiences": ["urn:example:basaltic:production"]
> }
> ```

La audiencia es el identificador elegido para este intercambio. Usa exactamente el mismo valor en el proveedor, la política de confianza y el workflow. La guía de AWS usa `sts.amazonaws.com` como audiencia de ejemplo.

## Restringir el rol a tu workflow

Crea un [rol IAM](https://docs.basaltic.sh/es/iam/roles.md) llamado `github-deployer` en la cuenta `production`. Su política de confianza debe indicar tu proveedor y el sujeto exacto de GitHub. Este ejemplo usa un entorno protegido llamado `production`:

```json theme={null}
{
  "principals": ["crn:iam::production:oidc-provider/github"],
  "conditions": [
    {
      "operator": "equals",
      "key": "basalt:webidentity:Subject",
      "values": ["repo:acme@123456/app@789012:environment:production"]
    },
    {
      "operator": "equals",
      "set_operator": "for_any_value",
      "key": "basalt:webidentity:Audience",
      "values": ["urn:example:basaltic:production"]
    }
  ]
}
```

Sustituye el propietario, repositorio e IDs del ejemplo por el `sub` exacto de tu token. GitHub admite formatos de sujeto basados en nombres y en IDs inmutables. Los cambios de nombre, transferencias o personalizaciones pueden alterar el valor. Consulta la [referencia de sujetos de GitHub](https://docs.github.com/en/actions/reference/security/oidc#example-subject-claims).

| Ámbito del job | Ejemplo de sujeto |
| - | - |
| Entorno | `repo:acme@123456/app@789012:environment:production` |
| Rama sin entorno | `repo:acme@123456/app@789012:ref:refs/heads/main` |
| Entorno anterior basado en nombres | `repo:acme/app:environment:production` |
| Rama anterior basada en nombres | `repo:acme/app:ref:refs/heads/main` |

Un sujeto de entorno no restringe también la rama. Configura la [protección de entornos de GitHub](https://docs.github.com/en/actions/how-tos/deploy/configure-and-manage-deployments/manage-environments) para limitar las ramas y aprobaciones de despliegue. El workflow de ejemplo usa un entorno, por lo que su confianza debe usar el sujeto de entorno.

Basaltic evalúa el emisor, sujeto y audiencia verificados. Claims como `repository_id`, `ref` y `job_workflow_ref` no son claves de política separadas en Basaltic. Incluye las restricciones necesarias en el sujeto admitido y en la configuración del entorno de GitHub.

## Conceder permisos de despliegue

Adjunta [políticas de permisos](https://docs.basaltic.sh/es/iam/policies.md) para los recursos específicos que modifica el despliegue. La confianza permite autenticarse; no concede acceso de despliegue. Para ejecutar la verificación siguiente, añade esta pequeña política y después los permisos de despliegue de tu aplicación por separado:

```json theme={null}
{
  "version": "2024-01-01",
  "statements": [{
    "effect": "allow",
    "actions": ["iam:GetRole"],
    "resources": ["crn:iam::production:role/github-deployer"]
  }]
}
```

## Obtener una sesión en GitHub Actions

Añade el siguiente workflow tras sustituir los valores de cuenta, rol, audiencia y entorno. El permiso `id-token: write` de GitHub permite al job solicitar su token de identidad; los permisos Basaltic siguen procediendo del rol. El intercambio no usa credenciales Basaltic preexistentes.

Define `BASALTIC_ROLE_ID` con el UUID devuelto al crear el rol; el endpoint de verificación recibe un UUID.

```yaml .github/workflows/deploy.yml theme={null}
name: Deploy to Basaltic
on:
  push:
    branches: [main]
  workflow_dispatch:
permissions:
  contents: read
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
    permissions:
      contents: read
      id-token: write
    env:
      BASALTIC_ACCOUNT: production
      BASALTIC_ROLE: crn:iam::production:role/github-deployer
      BASALTIC_ROLE_ID: REPLACE_WITH_ROLE_UUID
      BASALTIC_AUDIENCE: urn:example:basaltic:production
    steps:
      - name: Exchange GitHub identity
        shell: bash
        run: |
          python3 - <<'PYTHON'
          import json, os, urllib.parse, urllib.request

          url = os.environ["ACTIONS_ID_TOKEN_REQUEST_URL"]
          separator = "&" if "?" in url else "?"
          url += separator + urllib.parse.urlencode({"audience": os.environ["BASALTIC_AUDIENCE"]})
          request = urllib.request.Request(url, headers={
              "Authorization": "Bearer " + os.environ["ACTIONS_ID_TOKEN_REQUEST_TOKEN"]
          })
          with urllib.request.urlopen(request, timeout=30) as response:
              proof = json.load(response)["value"]
          print("::add-mask::" + proof)
          body = json.dumps({
              "role": os.environ["BASALTIC_ROLE"],
              "web_identity_token": proof,
              "session_name": "github-" + os.environ["GITHUB_RUN_ID"],
              "duration_seconds": 900
          }).encode()
          request = urllib.request.Request(
              "https://iam.basaltic.sh/v1/assume-role-with-web-identity",
              data=body, headers={"Content-Type": "application/json"}
          )
          with urllib.request.urlopen(request, timeout=30) as response:
              session = json.load(response)
          token = session["access_token"]
          print("::add-mask::" + token)
          with open(os.environ["GITHUB_ENV"], "a") as output:
              output.write("BASALTIC_TOKEN=" + token + "\n")
          PYTHON
      - name: Verify deployment role
        shell: bash
        run: |
          curl --fail --silent --show-error \
            -H "Authorization: Bearer $BASALTIC_TOKEN" \
            -H "X-Account-Id: $BASALTIC_ACCOUNT" \
            "https://iam.basaltic.sh/v1/roles/$BASALTIC_ROLE_ID" > /dev/null
```

Usa `BASALTIC_TOKEN` en los pasos posteriores de despliegue como token bearer HTTP. Sustituye o complementa la verificación con tus comandos de despliegue, concediendo solo las acciones IAM necesarias. Esta variable la define el ejemplo; las herramientas necesitan su propia configuración documentada de token. No imprimas el token ni subas la respuesta del intercambio como artefacto.

El ejemplo solicita una sesión de 15 minutos. Para jobs más largos, obtén una nueva prueba de GitHub e intercámbiala antes de que caduque la sesión Basaltic. No hay refresh token en este flujo. Consulta la [guía de workflows OIDC de GitHub](https://docs.github.com/en/actions/how-tos/secure-your-work/security-harden-deployments/oidc-in-cloud-providers).

## Solución de problemas

Un `401` durante el intercambio suele indicar un problema con el registro del emisor, audiencia, firma o caducidad. Un `403` apunta a la confianza del rol: compara el sujeto exacto, incluidos los IDs inmutables, rama frente a entorno y el operador de conjunto de audiencia. Un `403` después de iniciar sesión indica permisos ausentes o un límite de permisos. Consulta la [visión general de federación](https://docs.basaltic.sh/es/iam/oidc.md#troubleshooting).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.