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.
- Identificar un solo workflow candidato y al responsable de su servicio.
- Inventariar las claves que usa, sus consumidores y permisos, sin copiar sus valores a tickets o documentos.
- Elegir una operación de laboratorio de solo lectura sobre un recurso conocido.
- Definir repositorio, rama, environment, cuenta y rol permitidos.
- Revisar qué protecciones del environment están disponibles en el plan contratado.
- 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ón | Criterio recomendado | Evidencia |
|---|---|---|
| Cuenta de destino | Cuenta de prueba expresamente autorizada | Identificador validado por su responsable |
| Rol | Uno por función y ambiente | Nombre y políticas versionadas |
| Sujeto | Coincidencia exacta con el trabajo autorizado | Claims pertinentes, sin token completo |
| Audiencia | La esperada por la integración AWS | Valor configurado en ambos extremos |
| Permisos | Solo la operación y recurso de prueba | Política de permisos revisada |
| Duración | La menor que permita terminar el trabajo | Valor solicitado y vigencia observada |
| Retiro de clave | Consumidores identificados y validación aprobada | Registro 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-identityEl 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ó.
| Caso | Resultado esperado | Evidencia mínima |
|---|---|---|
| Rama y environment permitidos | Asume el rol previsto | Run, commit, cuenta y ARN devuelto |
| Lectura del objeto de prueba autorizado | Lectura exitosa | Operación y recurso, sin contenido sensible |
| Lectura de otro objeto de prueba no autorizado | Denegación | Error y solicitud correlacionable |
| Rama no autorizada | Bloqueo por la regla configurada | Estado del job y regla aplicada |
| Mismo repositorio con otro environment | Sin acceso al rol | Sujeto distinto y rechazo, si llega a STS |
| Repositorio de prueba no autorizado | Sin acceso al rol | Rechazo 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 orientativo | Entregable | Responsable funcional |
|---|---|---|
| Esta semana | Inventario de claves y piloto de lectura | Desarrollo y cloud |
| En dos semanas | Matriz positiva y negativa, revisión de confianza | AppSec e identidad |
| En 30 días | Primer flujo migrado y clave anterior desactivada | Dueño del servicio |
| En 60 días | Roles separados por ambiente y migración de otros candidatos | Plataforma y operaciones |
| Cada trimestre o tras cambios relevantes | Revisión de sujetos, dependencias, permisos y excepciones | Seguridad 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.
- GitHub Docs — Configuring OpenID Connect in Amazon Web Services. Federación, audiencia, permiso OIDC e integración con AWS.
- GitHub Docs — OpenID Connect reference. Claims, sujetos por contexto, formato inmutable desde julio de 2026 y depuración.
- AWS IAM — Create a role for OpenID Connect federation. Confianza de GitHub, restricciones del sujeto y protección de environments.
- GitHub Docs — Managing environments for deployment. Reglas, disponibilidad por plan y creación automática sin protección.
- AWS Actions — Configure AWS Credentials. Entradas, duración, nombre de sesión y credenciales temporales.
- GitHub Docs — Secure use reference. Mínimo privilegio, código no confiable y dependencias de workflows.
- 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.