DevOps10 min read1 visualizaciones

    GitHub Actions en 2026: las 5 novedades que deberías activar ya

    Workflow execution protections, caché de solo lectura y OIDC con custom properties: las 5 novedades de GitHub Actions en 2026 y cómo activarlas.

    Roberto Serrano

    Roberto Serrano

    Ingeniero de Software

    Github

    ¿Te resulta útil? Déjame saber con un like o guárdalo para luego.

    GitHub Actions ha dejado de ser ese YAML que copiabas de un gist y pegabas sin leer. En 2026 la plataforma ha cerrado agujeros reales de supply chain security y ha añadido mejoras de ergonomía que llevaban años pidiéndose. El problema es que muchas siguen desactivadas por defecto o requieren una decisión consciente.

    En este artículo repaso las cinco novedades que merecen un hueco en tu backlog, con sus fechas de disponibilidad general y con una distinción que se pasa por alto: qué se configura en el workflow y qué se configura en Settings o por API. No todo es YAML: algunos cambios importantes no admiten ni una línea de workflow.

    El aviso que corre prisa: pull_request_target cambia el 2 de noviembre

    Antes de entrar en las cinco features, hay una fecha que deberías apuntar: el 2 de noviembre de 2026. Ese día empieza a aplicarse el nuevo comportamiento por defecto de pull_request_target en repositorios públicos. GitHub lo desactiva salvo que lo habilites explícitamente, y el despliegue arranca primero en modo evaluate para que veas el impacto antes de que bloquee nada.

    ¿Por qué? Porque pull_request_target se ejecuta en el contexto de la rama base, con acceso a secretos y a un token de escritura. Si el workflow hace checkout del código del pull request y lo ejecuta, alguien desde un fork puede colar código y exfiltrar credenciales. Es el patrón clásico de los Pwn Requests.

    Si mantienes un repositorio público, revisa ahora qué workflows usan ese trigger. La regla práctica: usa pull_request para todo lo que compile o ejecute código no confiable, y reserva pull_request_target para operaciones de metadatos que no toquen el código del fork. Si necesitas ambas cosas, separa el workflow privilegiado del que ejecuta el código.

    1. Workflow execution protections (GA: 17 de septiembre de 2026)

    Las protecciones de ejecución llevaban meses en preview y llegaron a disponibilidad general el 17 de septiembre de 2026. Permiten definir una allowlist con dos tipos de reglas:

    • Actor rules: quién puede disparar un workflow.
    • Event rules: qué eventos pueden iniciarlo.

    Ambas se evalúan antes de que el run arranque: un workflow bloqueado ni siquiera consume runner.

    La versión GA añadió tres cosas:

    MejoraQué aporta
    Workflow file targetingPolíticas distintas por fichero de workflow
    InsightsAuditoría del impacto antes y después de activar
    REST APIGestión de políticas como código

    Y una cuarta que conviene usar antes de endurecer: el modo Evaluate, o shadow mode. Configuras las reglas sin bloquear y revisas qué ejecuciones se habrían rechazado, para detectar falsos positivos antes de romper el CI de nadie.

    Esto NO se configura en YAML

    Aquí está el error más frecuente. Workflow execution protections no tienen sintaxis de workflow. No existe una clave execution-protections ni un bloque permissions que las active. Se configuran en Settings → Actions → Policies, en el repositorio, la organización o la empresa, o bien mediante la REST API de políticas (/rest/actions/policies).

    Si encuentras un fragmento de YAML que prometa activarlas, es inventado: esto es política de plataforma, no código de repositorio.

    En la misma familia hay dos protecciones que merecen revisión: Require lockfile y Require actions pinned to full-length commit SHA. La segunda evita que una etiqueta móvil como @v4 cambie de contenido sin que tú toques nada.

    Dos avisos antes de activarlas:

    1. Si exiges lockfile, genera y haz commit de los lockfiles antes. Si no, bloquearás tus propios runs.
    2. Las identidades de features, como dependabot[bot], deben añadirse explícitamente a los actores permitidos. No se asumen.

    2. La sintaxis $/ para acciones del mismo repositorio (30 de julio de 2026)

    Históricamente, para usar una composite action de tu propio repositorio necesitabas hacer checkout y referenciarla con una ruta relativa. Eso añadía un step, un clon completo y una dependencia implícita del workspace.

    Desde el 30 de julio de 2026, la sintaxis self-repository resuelve el problema:

    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          # Acción del mismo repo, en el commit en ejecución. Sin checkout.
          - uses: $/.github/actions/hello-world-action
    

    $/ apunta al mismo repositorio en el commit en ejecución, sin checkout y con pinning automático por SHA: la acción no puede cambiar a mitad de rama.

    Funciona en steps, composite actions, composición anidada y reusable workflows. Tiene tres limitaciones:

    • No está disponible en GitHub Enterprise Server.
    • No admite sufijo @{ref}: $/mi-accion@v1 es inválido.
    • Requiere runner 2.336.0 o superior.

    La ventaja no es estética: eliminas un checkout innecesario, reduces tiempo de job y ejecutas exactamente la versión que ves en el repositorio.

    3. OIDC con custom properties: ABAC sin listas estáticas (12 de marzo de 2026)

    Si despliegas en AWS, Azure o GCP con OIDC, conoces el problema: la política de confianza del cloud enumera repositorios, ramas o entornos. Cada repo nuevo obliga a editarla, y con decenas de repositorios se convierte en una lista estática que nadie revisa.

    Desde el 12 de marzo de 2026, el token OIDC de GitHub incluye claims derivados de las custom properties del repositorio, con el prefijo repo_property_. Si tu propiedad se llama business_unit, el claim será repo_property_business_unit. Lo mismo para data_classification, team o cualquier propiedad con la que organices repositorios.

    El alta de esos claims se hace por API, no en el workflow:

    POST /orgs/{org}/actions/oidc/customization/properties/repo
    POST /enterprises/{enterprise}/actions/oidc/customization/properties/repo
    

    El workflow, en cambio, solo necesita pedir el token:

    permissions:
      id-token: write   # imprescindible para OIDC
      contents: read
    
    jobs:
      deploy:
        runs-on: ubuntu-latest
        steps:
          - uses: aws-actions/configure-aws-credentials@v4
            with:
              role-to-assume: arn:aws:iam::123456789012:role/gha-deploy
              aws-region: eu-west-1
          # El token incluirá repo_property_business_unit,
          # repo_property_data_classification, etc.
    

    La política de confianza del cloud puede filtrar por esos claims, por ejemplo exigiendo "repo_property_data_classification": "internal". Eso es ABAC de manual: la autorización depende de atributos del repositorio, no de una lista de nombres que hay que mantener a mano.

    En la práctica, dar de alta un repositorio deja de requerir editar el proveedor cloud. Si hereda las propiedades correctas, hereda el permiso correcto; y si cambia la clasificación de datos, el acceso se ajusta sin tocar workflows.

    4. queue: max: colas de hasta 100 ejecuciones (7 de mayo de 2026)

    El comportamiento clásico de concurrency era frustrante: un run en progreso y uno pendiente. Si llegaba un tercero, cancelaba al pendiente; en un monorepo con pushes frecuentes, solo se desplegaba el último commit.

    Desde el 7 de mayo de 2026, queue: max permite hasta 100 runs en espera por grupo de concurrencia, procesados en orden:

    on:
      push:
        branches: [main]
    
    concurrency:
      group: production-deploy
      queue: max          # hasta 100 runs en espera, en orden
      # NO combinar con cancel-in-progress: true → error de validación
    

    Es la opción correcta cuando quieres que todos los commits se desplieguen en secuencia, sin saltarte ninguno; por ejemplo, en migraciones de base de datos donde el orden importa.

    Hay una incompatibilidad que debes recordar: queue: max y cancel-in-progress: true no se pueden combinar; GitHub devuelve un error de validación. O encolas o cancelas, no ambas. Elige el modelo según lo que necesites.

    5. Caché de solo lectura y cache-mode (26 de junio y 10 de septiembre de 2026)

    El cache poisoning es un ataque silencioso: un trigger no confiable escribe en la caché de Actions y, más tarde, una rama de confianza restaura esa entrada envenenada. Si contiene dependencias compiladas o binarios, el código malicioso acaba ejecutándose en un contexto privilegiado.

    El 26 de junio de 2026, GitHub empezó a emitir un token de caché de solo lectura en dos condiciones simultáneas: el evento es no confiable y el scope de la caché es el SHA de la rama por defecto. Los triggers considerados de confianza, con acceso de lectura y escritura, son:

    push, schedule, workflow_dispatch, repository_dispatch, delete, registry_package y page_build.

    pull_request y release conservan lectura y escritura porque su scope no es la rama por defecto: no es que sean más seguros, es que no comparten espacio de caché.

    Después, el 10 de septiembre de 2026, llegó cache-mode a todos los planes con cuatro valores:

    ValorComportamiento
    readSolo restaura, nunca guarda. Es el valor por defecto en contextos de baja confianza
    writeRestaura y guarda. Valor por defecto en contextos de confianza
    write-onlySolo guarda
    noneDesactiva la caché

    El nivel de job anula el nivel de workflow, y el valor efectivo se expone en la variable ACTIONS_CACHE_MODE. Un ejemplo del patrón seguro:

    on: pull_request_target
    
    jobs:
      build:
        runs-on: ubuntu-latest
        cache-mode: read      # solo restore, nunca save
        steps:
          - uses: actions/cache/restore@v4
            with:
              path: ~/.npm
              key: npm-${{ hashFiles('**/package-lock.json') }}
    

    Y un workflow de confianza que se encarga de calentar la caché:

    on: push
    
    jobs:
      warm-cache:
        runs-on: ubuntu-latest
        cache-mode: write
        steps:
          - uses: actions/cache@v4
            with:
              path: ~/.npm
              key: npm-${{ hashFiles('**/package-lock.json') }}
    

    Dos trampas detectadas en revisiones reales: declarar cache-mode: write en un trigger no confiable reintroduce el riesgo (GitHub avisa, pero lo permite), y en reusable workflows el llamado nunca recibe más acceso de caché que el que llama. Para limitarlo, pon cache-mode: read en el job que invoca.

    Tabla resumen

    NovedadFechaDónde se configuraQué resuelve
    Workflow execution protections17 sep 2026Settings → Actions → Policies o REST APIQuién y qué puede ejecutar workflows
    Self-repository $/30 jul 2026YAML del workflowAcciones locales sin checkout
    OIDC repo_property_*12 mar 2026REST API + política del cloudABAC sin allowlists estáticas
    queue: max7 may 2026YAML del workflowColas de hasta 100 runs en orden
    Caché read-only + cache-mode26 jun y 10 sep 2026YAML + comportamiento de plataformaFin del cache poisoning por defecto

    Cómo adoptarlo sin romper nada

    El orden recomendado, de más urgente a más opcional:

    1. Audita pull_request_target antes del 2 de noviembre. Identifica qué workflows lo usan y si ejecutan código del fork.
    2. Activa el modo Evaluate de workflow execution protections y revisa una semana de impacto antes de bloquear.
    3. Fuerza el pinning por SHA en las acciones de terceros. Es la medida con mejor relación esfuerzo/riesgo.
    4. Pasa a cache-mode: read en todos los triggers no confiables, y deja los saves en workflows de push.
    5. Migra tus acciones locales a $/ cuando actualices runners; elimina checkouts y gana unos segundos por job.
    6. Revisa concurrency: si estabas perdiendo deploys intermedios, queue: max es tu solución.
    7. Plantea OIDC con custom properties si gestionas más de un puñado de repositorios en un cloud.

    Ninguno de estos cambios exige reescribir el CI: son ajustes incrementales que puedes probar en un repositorio piloto antes de extenderlos.

    Conclusión

    GitHub Actions en 2026 ya no va solo de escribir YAML bonito, sino de decidir qué ejecuta, con qué credenciales y desde dónde. Las cinco novedades comparten una lógica: reducir la superficie de ataque sin montar infraestructura propia.

    Si tuviera que quedarme con una, sería la combinación de pinning por SHA y caché de solo lectura: cierran agujeros que muchos equipos ni sabían que tenían. Y si mantienes repositorios públicos, empieza por el aviso del 2 de noviembre; es la única fecha que no puedes negociar.


    Artículos relacionados


    Artículo escrito por Roberto Serrano — Desarrollador web, automatizaciones e IA en Tarragona, España.

    ¿Te ha gustado? Compártelo.

    Más sobre el tema