Volver a Guías

Andrez Higuera · 2026-10-16 · 12 min

GitHub Actions y AWS con OIDC para eliminar claves de acceso permanentes

Borrador editorial para revisión · 16 de octubre de 2026 · Lectura estimada de 12 minutos

Resumen ejecutivo

Guardar una clave de AWS como secreto de GitHub evita escribirla en el repositorio, pero no elimina su vigencia prolongada ni el trabajo de rotarla. OpenID Connect, u OIDC, permite que un trabajo de GitHub Actions acredite su identidad y obtenga credenciales temporales de un rol de AWS. Así se puede retirar la clave permanente de ese flujo, siempre que la confianza y los permisos estén acotados.

Hecho. GitHub y AWS documentan esta federación sin claves de acceso permanentes almacenadas en GitHub. La política de confianza determina quién puede asumir el rol; las políticas de permisos determinan qué puede hacer la sesión. Son controles distintos. [1][3][7]

Recomendación. Migrar primero un flujo de bajo riesgo. Validar tanto el acceso permitido como el rechazo de contextos no autorizados antes de retirar la clave anterior. Separar los roles de prueba y producción.

Inferencia. Para equipos pequeños, esta migración puede reducir trabajo de rotación y exposición por claves olvidadas. No elimina el riesgo de un workflow, una dependencia o un runner comprometidos: cambia el punto de control desde la custodia de una clave hacia la identidad y la ejecución del pipeline.

Audiencia y alcance

Esta guía está dirigida a desarrolladores, encargados de TI, equipos de AppSec y DevSecOps y responsables de identidad cloud. El caso práctico usa GitHub.com y una cuenta AWS de laboratorio, con un rol de lectura mínima. No publica aplicaciones ni modifica infraestructura productiva.

Se requiere un repositorio administrable, autorización para configurar IAM y un ambiente de prueba. Si no hay cuenta de laboratorio, se puede completar el diseño y la revisión de políticas, pero no presentar esa revisión como una prueba real de federación.

El contenido no demuestra cumplimiento de una ley o certificación por sí solo. Las evidencias pueden apoyar controles de identidad, mínimo privilegio y trazabilidad.

Contexto y hechos técnicos

El flujo tiene cuatro partes: el trabajo solicita un token OIDC a GitHub; AWS valida al emisor y las condiciones de confianza; STS entrega credenciales temporales; el trabajo las usa dentro de los permisos del rol. Las credenciales temporales también son sensibles mientras están vigentes. [1][7]

En la integración habitual con AWS, el emisor es https://token.actions.githubusercontent.com y la audiencia usada por la acción oficial es sts.amazonaws.com. El permiso id-token: write habilita solicitar el token OIDC; no concede por sí solo escritura sobre AWS. [1]

La política de confianza debe restringir el sujeto sub. AWS rechaza determinadas políticas de GitHub sin esa condición o con un valor compuesto únicamente por comodines, pero superar esa validación no prueba que la confianza sea suficientemente estrecha. [3]

El detalle vigente que puede romper una configuración copiada

GitHub documenta que los repositorios creados después del 15 de julio de 2026 usan un formato de sujeto con identificadores de propietario y repositorio. Los anteriores conservan el formato previo salvo adopción del nuevo; los renombrados o transferidos después de esa fecha también cambian. Este comportamiento no incluye GitHub Enterprise Server. [2]

Por eso, no se debe deducir el sujeto solo del nombre visible. La configuración debe coincidir con el sub efectivo del trabajo y con cualquier personalización habilitada. Cuando el trabajo referencia un environment, el contexto del sujeto corresponde a ese environment, no al sufijo de rama del ejemplo habitual. [2]

Impacto para el equipo

La clave permanente deja de ser necesaria para el flujo migrado, pero la capacidad de obtener credenciales queda ligada a quién puede cambiar o ejecutar el workflow. Proteger .github/workflows/, las ramas autorizadas y los ambientes de despliegue pasa a ser parte de la defensa de AWS.

La separación ayuda a explicar las decisiones: una falla en la confianza permite asumir el rol desde un contexto indebido; una falla en permisos permite hacer demasiado después de asumirlo. Una sesión de corta duración con permisos administrativos sigue teniendo un impacto potencial alto.

Acciones iniciales en una hora

Estas acciones son una propuesta práctica, no una ventana garantizada de implementación.

  1. Identificar un solo workflow candidato y al responsable de su servicio.
  2. Inventariar las claves que usa, sus consumidores y permisos, sin copiar sus valores a tickets o documentos.
  3. Elegir una operación de laboratorio de solo lectura sobre un recurso conocido.
  4. Definir repositorio, rama, environment, cuenta y rol permitidos.
  5. Revisar qué protecciones del environment están disponibles en el plan contratado.
  6. Acordar quién revisa el cambio, cómo se valida y cuándo se desactiva la clave anterior.

El entregable inicial es una ficha de migración y un criterio de aceptación, no una nueva clave ni una política con permisos amplios para resolver rápidamente un error.

Desarrollo práctico

1 Diseñar la confianza antes de tocar el workflow

Completar esta matriz con valores del laboratorio:

DecisiónCriterio recomendadoEvidencia
Cuenta de destinoCuenta de prueba expresamente autorizadaIdentificador validado por su responsable
RolUno por función y ambienteNombre y políticas versionadas
SujetoCoincidencia exacta con el trabajo autorizadoClaims pertinentes, sin token completo
AudienciaLa esperada por la integración AWSValor configurado en ambos extremos
PermisosSolo la operación y recurso de pruebaPolítica de permisos revisada
DuraciónLa menor que permita terminar el trabajoValor solicitado y vigencia observada
Retiro de claveConsumidores identificados y validación aprobadaRegistro de desactivación y observación

Evitar un rol compartido por toda la organización y la condición repo:ORG/*. Para producción, agregar revisión de cambios del workflow y del rol por una persona distinta de quien los implementa cuando sea viable.

2 Crear y proteger el environment

Crear explícitamente oidc-lab antes de ejecutar el ejemplo. Restringir las ramas y tags que pueden utilizarlo, y probar que la regla se aplica. No confiar en que escribir environment: oidc-lab en YAML crea una barrera: GitHub puede crear automáticamente un environment inexistente sin reglas de protección. [4]

Hecho sobre disponibilidad. Las posibilidades dependen del plan y de la visibilidad del repositorio. GitHub documenta restricciones para environments privados y para revisores obligatorios. Un repositorio privado con GitHub Pro o Team no dispone necesariamente de las mismas aprobaciones que uno público. [4]

Recomendación. Si el control requerido no está disponible, no describirlo como implementado. Mantener el piloto en lectura y no llevarlo a producción hasta disponer de una barrera equivalente, verificable y aprobada.

3 Registrar el proveedor y observar el sujeto efectivo

Un administrador autorizado configura el proveedor OIDC de GitHub en IAM y su audiencia. Antes de conceder acceso cloud, inspeccionar los claims del trabajo previsto mediante el mecanismo de depuración documentado por GitHub, con acceso limitado a sus logs. [1][2]

Conservar solo iss, aud, sub, contexto de ejecución y fecha. No imprimir ni guardar el JWT completo, el token de sesión o las claves temporales. Tratar también los identificadores internos como información de acceso restringido cuando corresponda.

La referencia documenta la acción github/actions-oidc-debugger. Revisar y fijar su dependencia antes de usarla; retirar el paso de diagnóstico al terminar. No enviar tokens a sitios externos para decodificarlos.

4 Configurar la política de confianza

Esta plantilla está incompleta a propósito. Sustituir CUENTA_LAB y SUB_EXACTO_OBSERVADO por los valores autorizados antes de validarla en IAM. No contiene cuentas, repositorios ni secretos reales.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::CUENTA_LAB:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
          "token.actions.githubusercontent.com:sub": "SUB_EXACTO_OBSERVADO"
        }
      }
    }
  ]
}

Esta política permite asumir el rol; no le concede lectura ni escritura de recursos. Adjuntar una política de permisos independiente para la operación de laboratorio, por ejemplo s3:GetObject sobre un objeto de prueba específico y sin datos sensibles. Evitar AdministratorAccess, acciones comodín y recursos indiscriminados. [3]

Si el sujeto corresponde al environment, mantener la restricción de ramas en sus reglas. No suponer que ese mismo sub también restringe la rama. La aceptación del documento por IAM tampoco sustituye las pruebas negativas.

5 Preparar un workflow de comprobación

La siguiente plantilla no es ejecutable sin completar el marcador SHA_COMPLETO_REVISADO con un commit verificado de aws-actions/configure-aws-credentials. Configurar además las variables AWS_LAB_ROLE_ARN y AWS_LAB_REGION en el environment. El ARN y la región son configuración, no una clave de acceso; aun así, controlar quién puede cambiarlos.

name: Comprobar identidad OIDC en laboratorio

on:
  workflow_dispatch:

permissions: {}

jobs:
  identity-check:
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    timeout-minutes: 10
    environment: oidc-lab
    permissions:
      id-token: write
    steps:
      - name: Obtener credenciales temporales
        uses: aws-actions/configure-aws-credentials@SHA_COMPLETO_REVISADO
        with:
          role-to-assume: ${{ vars.AWS_LAB_ROLE_ARN }}
          aws-region: ${{ vars.AWS_LAB_REGION }}
          audience: sts.amazonaws.com
          role-duration-seconds: 900
          role-session-name: gha-${{ github.run_id }}-${{ github.run_attempt }}
      - name: Comprobar identidad asumida
        run: aws sts get-caller-identity

El ejemplo no hace checkout ni despliega. Su condición de rama es una defensa adicional del workflow, no una restricción de IAM. Proteger los cambios que podrían modificarla.

La acción admite duración y nombre de sesión; el identificador de ejecución ayuda a correlacionar actividad. get-caller-identity comprueba la identidad devuelta, pero no demuestra que los permisos sobre recursos estén bien acotados. Se requiere una prueba de lectura permitida y otra denegada. [5]

Para las dependencias, GitHub recomienda actualmente lockfiles de workflows cuando el repositorio pueda adoptarlos. En su defecto, fijar acciones a un SHA completo verificado y establecer un procedimiento de actualización. El pinning no equivale a una auditoría de la acción. [6]

6 Probar el rechazo además del acceso

Ejecutar los casos únicamente en el laboratorio autorizado. Cuando una barrera impida emitir el token, registrar esa barrera como resultado; no afirmar que IAM rechazó una solicitud que nunca recibió.

CasoResultado esperadoEvidencia mínima
Rama y environment permitidosAsume el rol previstoRun, commit, cuenta y ARN devuelto
Lectura del objeto de prueba autorizadoLectura exitosaOperación y recurso, sin contenido sensible
Lectura de otro objeto de prueba no autorizadoDenegaciónError y solicitud correlacionable
Rama no autorizadaBloqueo por la regla configuradaEstado del job y regla aplicada
Mismo repositorio con otro environmentSin acceso al rolSujeto distinto y rechazo, si llega a STS
Repositorio de prueba no autorizadoSin acceso al rolRechazo sin ampliar la confianza

No usar recursos de terceros para pruebas negativas. Revisar también que los logs no expongan credenciales y que la identidad no provenga accidentalmente de otra fuente del runner.

7 Retirar la clave permanente con control

Después de aprobar el piloto, migrar el flujo real en una ventana acordada. Confirmar que ningún otro proceso depende de la clave antigua. Retirar su uso del workflow y desactivarla en IAM; borrar únicamente el secreto de GitHub no invalida la clave.

Observar al menos un ciclo completo de operación relevante. Si no hay dependencias pendientes y el responsable autoriza el cierre, eliminar la clave ya desactivada. Registrar quién hizo cada cambio y cuándo. Si aparecen consumidores olvidados, detener el retiro y corregir el inventario; no reactivar automáticamente una clave ni ampliar permisos sin autorización.

La reversa preferente es pausar el despliegue o volver a un workflow aprobado con confianza acotada. Mantener un mecanismo de emergencia separado y auditado, no una clave de respaldo de uso cotidiano.

Hoja de ruta recomendada

Plazo orientativoEntregableResponsable funcional
Esta semanaInventario de claves y piloto de lecturaDesarrollo y cloud
En dos semanasMatriz positiva y negativa, revisión de confianzaAppSec e identidad
En 30 díasPrimer flujo migrado y clave anterior desactivadaDueño del servicio
En 60 díasRoles separados por ambiente y migración de otros candidatosPlataforma y operaciones
Cada trimestre o tras cambios relevantesRevisión de sujetos, dependencias, permisos y excepcionesSeguridad y responsables de repositorio

Ajustar los plazos a la capacidad real del equipo. Medir flujos migrados, claves permanentes retiradas, roles sin dueño, confianza con comodines y casos negativos ejecutados. No usar solo el número de pipelines con OIDC como indicador de seguridad.

Evidencia y checklist de aceptación

Conservar un expediente acotado con repositorio, workflow y commit; cuenta y rol; política de confianza; política de permisos; reglas efectivas del environment; resultados de pruebas; aprobación del cambio; y retiro de la clave. Guardar logs depurados con acceso y retención definidos.

  • El sujeto coincide con el trabajo efectivo, incluido formato inmutable o personalizado.
  • Emisor y audiencia están configurados de forma consistente.
  • El rol no admite repositorios ajenos ni contextos innecesarios.
  • Los permisos se limitan a acciones y recursos requeridos.
  • El environment existe y sus reglas fueron probadas en el plan utilizado.
  • El permiso OIDC está limitado al job que lo necesita.
  • No se ejecuta código no confiable en el job privilegiado.
  • Dependencias y cambios del workflow tienen revisión y actualización previstas.
  • Se probó acceso permitido y denegado, distinguiendo la capa que bloqueó.
  • No hay JWT ni credenciales temporales expuestos en evidencia.
  • La clave anterior ya no tiene consumidores y su retiro está registrado.
  • Hay propietario, fecha de revisión y reversa aprobada.

Riesgos y decisiones que no conviene omitir

Confianza demasiado amplia. OIDC no protege si el rol acepta trabajos que no deberían obtenerlo. Usar coincidencia exacta y probar el rechazo.

Cambios de nombre o transferencia. Pueden alterar el sujeto esperado. Incluir la revisión OIDC en el procedimiento de cambio del repositorio; no resolver el error reemplazando la condición por un comodín.

Código no confiable. Una dependencia, script o pull request ejecutado con la identidad cloud puede aprovechar los permisos concedidos. Separar validación de contribuciones y despliegue, y revisar especialmente combinaciones de pull_request_target o workflow_run con checkout de código no confiable. [6]

Runner persistente. En un runner autohospedado, analizar credenciales preexistentes, aislamiento y limpieza entre trabajos. La migración de identidad no resuelve por sí sola el compromiso del host.

Falsa aprobación humana. workflow_dispatch permite iniciar manualmente un workflow; no equivale a una revisión independiente. Tampoco escribir el nombre de un environment demuestra que tenga aprobadores configurados.

Retiro incompleto. El secreto borrado de GitHub puede seguir vigente en AWS o en otro consumidor. Verificar ambos extremos y conservar el inventario de dependencias.

Fuentes primarias enlazadas

Documentación consultada el 16 de octubre de 2026. Son referencias vivas; revisar cambios antes de implementar en producción.

  1. GitHub Docs — Configuring OpenID Connect in Amazon Web Services. Federación, audiencia, permiso OIDC e integración con AWS.
  2. GitHub Docs — OpenID Connect reference. Claims, sujetos por contexto, formato inmutable desde julio de 2026 y depuración.
  3. AWS IAM — Create a role for OpenID Connect federation. Confianza de GitHub, restricciones del sujeto y protección de environments.
  4. GitHub Docs — Managing environments for deployment. Reglas, disponibilidad por plan y creación automática sin protección.
  5. AWS Actions — Configure AWS Credentials. Entradas, duración, nombre de sesión y credenciales temporales.
  6. GitHub Docs — Secure use reference. Mínimo privilegio, código no confiable y dependencias de workflows.
  7. AWS IAM — Credenciales de seguridad temporales. Roles, STS y federación sin distribución de claves permanentes.

Nota para revisión editorial

Título SEO propuesto: GitHub Actions y AWS con OIDC para eliminar claves de acceso permanentes.

Descripción propuesta: Aprende a migrar GitHub Actions a credenciales temporales de AWS con OIDC, confianza acotada, pruebas negativas y retiro controlado de claves.

Slug propuesto: github-actions-aws-oidc-sin-claves-permanentes.

Selección e inferencia editorial: el tema reúne una consulta práctica de desarrollo con identidad cloud y seguridad del pipeline. Su potencial de búsqueda y crecimiento es una hipótesis editorial, no una estimación basada en métricas de audiencia.

Revisión de duplicación actualizada el 16 de octubre de 2026: se revisaron la lista pública de Guías, la mesa Revista y el catálogo privado de Guías. Ya están publicadas las guías de respuesta a incidentes para pymes y priorización de vulnerabilidades. No se encontró otra guía OIDC en esos inventarios. La pieza de recuperación verificable del 13 de octubre y esta guía constituyen los dos originales de la semana; esta carga reutiliza la entrega de la Guía práctica semanal, sin crear una tercera pieza. Guías · Noticia relacionada

Enlaces internos sugeridos para edición: Academia AppSec y la guía de priorización de vulnerabilidades cuando su URL pública esté confirmada. No enlazar un borrador privado como si estuviera publicado.

Estado: preparado para revisión técnica, de enlaces y de estilo. Los ejemplos no fueron desplegados ni ejecutados contra una cuenta AWS. No se modificó ni publicó el sitio.