Blog Azure GitHub

Más control sobre GitHub-hosted runners: gobierno de Actions para organizaciones

Ilustración de flujos de GitHub Actions ejecutándose sobre runners hospedados con controles de acceso organizativos

GitHub ha anunciado más control organizativo sobre el uso de GitHub-hosted runners en GitHub Actions. La novedad permite a los administradores deshabilitar labels estándar de runners hospedados, como ubuntu-latest, y ampliar el uso de runner groups para escenarios donde antes había menos capacidad de gobierno, especialmente en macOS.

El cambio puede parecer administrativo, pero tiene implicaciones importantes para seguridad, costes, cumplimiento y arquitectura de plataforma. En organizaciones con muchos repositorios, permitir que cualquier workflow seleccione directamente ubuntu-latest, windows-latest o macos-latest puede ser cómodo, pero también dificulta aplicar políticas homogéneas sobre qué equipos consumen capacidad de ejecución, bajo qué restricciones y con qué nivel de trazabilidad.

La mejora anunciada por GitHub apunta precisamente a ese problema: desplazar parte del control desde la convención en los repositorios hacia la administración central de Actions.

Qué son los GitHub-hosted runners y por qué importan

En GitHub Actions, un runner es el entorno que ejecuta los jobs definidos en un workflow. Cuando un archivo YAML dentro de .github/workflows/ declara un job con runs-on, GitHub busca un runner compatible y ejecuta allí los pasos del pipeline.

Un ejemplo habitual es este:

name: build

on:
  pull_request:
    branches:
      - main

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - name: Descargar el código del repositorio
        uses: actions/checkout@v4

      - name: Configurar Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '22'

      - name: Instalar dependencias
        run: npm ci

      - name: Ejecutar pruebas
        run: npm test

La línea relevante es:

runs-on: ubuntu-latest

Con esa declaración, el job se ejecuta en un runner Linux hospedado por GitHub usando la imagen que GitHub expone bajo ese label. Para equipos pequeños o repositorios de producto, este modelo reduce fricción: no hay que aprovisionar máquinas, aplicar parches ni mantener agentes de CI.

En organizaciones grandes, sin embargo, esa comodidad puede convertirse en una superficie difícil de gobernar. Los runners ejecutan código, instalan dependencias, usan tokens de GitHub, acceden a secretos cuando el workflow los tiene disponibles y, en muchos casos, interactúan con servicios externos o despliegan infraestructura cloud.

Por eso, el control sobre los runners no es solo una cuestión de capacidad de cómputo. Es parte del modelo de seguridad y gobierno de la plataforma de entrega.

Qué cambia con el nuevo control sobre runners hospedados

Según el anuncio de GitHub, las organizaciones tienen ahora más control sobre quién puede usar GitHub-hosted runners en Actions. Las capacidades destacadas son dos:

  1. Los administradores pueden deshabilitar labels estándar de runners hospedados, como ubuntu-latest.
  2. Los administradores pueden añadir macOS runners a runner groups.

La primera capacidad ayuda a evitar que los workflows seleccionen directamente runners genéricos mediante labels estándar. En lugar de depender de que cada equipo siga una guía interna, la organización puede aplicar una restricción desde la capa administrativa de GitHub Actions.

La segunda capacidad es especialmente relevante para organizaciones que necesitan compilar, probar o empaquetar software sobre macOS, por ejemplo en escenarios relacionados con aplicaciones móviles o software que depende del ecosistema de Apple. Según GitHub, los macOS runners pueden integrarse en runner groups para aplicar controles como permisos por grupo y límites de concurrencia.

Nota: El anuncio público es un changelog de producto. Antes de aplicar esta configuración en producción, conviene revisar la documentación oficial de GitHub correspondiente a tu plan, tipo de cuenta y nivel de administración. La disponibilidad y el detalle operativo pueden depender de la configuración de la organización o empresa.

Disponibilidad y limitaciones anunciadas

GitHub indica que esta funcionalidad está disponible en planes Team y Enterprise.

También señala una limitación importante: las network configurations no están soportadas para macOS runners en este momento. Esto es relevante para organizaciones que diseñan pipelines con requisitos específicos de conectividad, aislamiento de red o acceso controlado a servicios internos.

En la práctica, esto significa que la incorporación de macOS runners a runner groups mejora el control de acceso y consumo, pero no debe interpretarse como soporte completo para todos los patrones de red disponibles en otros tipos de runners o configuraciones.

Por qué deshabilitar ubuntu-latest puede ser una buena idea

ubuntu-latest es uno de los labels más usados en GitHub Actions. Es simple, cómodo y suficiente para muchos pipelines. Pero en entornos gobernados también tiene inconvenientes.

El primero es la ambigüedad operativa. ubuntu-latest no expresa una versión fija de Ubuntu en el YAML del repositorio, sino una referencia gestionada por GitHub. Cuando GitHub actualiza la imagen subyacente, un workflow puede empezar a ejecutarse sobre una base distinta sin que el archivo del repositorio haya cambiado.

Para muchos proyectos esto es aceptable. Para compilaciones reguladas, pipelines con dependencias nativas o procesos donde la reproducibilidad sea importante, puede ser preferible declarar una versión concreta:

name: build-linux

on:
  push:
    branches:
      - main

jobs:
  test:
    runs-on: ubuntu-24.04

    steps:
      - name: Descargar el código
        uses: actions/checkout@v4

      - name: Mostrar versión del sistema operativo
        run: cat /etc/os-release

      - name: Ejecutar validaciones
        run: echo "Aquí se ejecutarían las pruebas del proyecto"

La diferencia parece pequeña, pero comunica una intención más precisa. ubuntu-24.04 expresa mejor la versión esperada del entorno que ubuntu-latest.

El segundo motivo es el consumo no gobernado. Aunque GitHub gestione la infraestructura, los jobs de Actions consumen minutos, concurrencia y capacidad asociada al plan contratado. Si cualquier repositorio puede ejecutar workflows sobre labels estándar sin pasar por un modelo de aprobación, resulta más difícil atribuir consumo, priorizar workloads críticos o aplicar límites.

El tercer motivo es la separación de confianza. No todos los repositorios tienen la misma sensibilidad. Un repositorio experimental, un monorepo de producto y un repositorio que despliega infraestructura no deberían necesariamente tener el mismo acceso a capacidad de ejecución.

Deshabilitar labels estándar puede ayudar a que el camino más fácil no sea también el menos controlado.

Runner groups como interfaz de gobierno

La mejora más interesante no es bloquear un label concreto, sino reforzar el uso de runner groups como mecanismo de gobierno.

En GitHub Actions, los runner groups permiten agrupar runners y controlar qué repositorios, organizaciones o workflows pueden usarlos, según el nivel de administración disponible. Con la novedad anunciada, GitHub destaca tres escenarios para macOS runners:

  • Restringir acceso a macOS runners mediante permisos a nivel de grupo.
  • Aplicar límites de concurrencia para controlar cuántos jobs macOS pueden ejecutarse simultáneamente.
  • Dirigir jobs mediante política, referenciando runner groups por nombre en los workflows.

Este enfoque permite que los equipos de aplicación no seleccionen infraestructura arbitraria, sino una capacidad publicada y aprobada por la plataforma.

Un workflow podría declarar un runner group de forma explícita:

name: ci-platform-approved

on:
  pull_request:
    branches:
      - main

jobs:
  validate:
    runs-on:
      group: ci-linux-standard

    permissions:
      contents: read

    steps:
      - name: Descargar el código
        uses: actions/checkout@v4

      - name: Ejecutar comprobaciones de calidad
        run: echo "Ejecutando validaciones sobre un runner group aprobado"

En este ejemplo, ci-linux-standard es un nombre ilustrativo. No es un runner group creado automáticamente por GitHub. Debe existir en la organización o empresa y estar configurado con los runners y permisos adecuados.

Advertencia: No sustituyas ubuntu-latest por nombres de grupos o labels inventados sin comprobar la configuración real de tu organización. Si el runner group no existe o el repositorio no tiene permiso para usarlo, los jobs no podrán ejecutarse correctamente.

El beneficio de este patrón es separar responsabilidades:

  • Los equipos de producto declaran qué tipo de capacidad necesitan.
  • El equipo de plataforma decide cómo se implementa esa capacidad.
  • Seguridad y gobierno pueden aplicar permisos, límites y revisiones de forma centralizada.

Caso especial: macOS runners

La incorporación de macOS runners a runner groups es una parte relevante del anuncio porque los entornos macOS suelen requerir más control de capacidad y coste que los runners Linux generalistas.

En organizaciones con varios equipos compilando aplicaciones móviles, SDKs o componentes dependientes de macOS, la falta de límites claros puede provocar competencia por la misma capacidad. Con runner groups, GitHub permite aplicar controles de acceso y concurrencia para que el uso de macOS sea más predecible.

Un ejemplo conceptual podría ser:

name: build-macos

on:
  pull_request:
    branches:
      - main

jobs:
  build:
    runs-on:
      group: macos-builds

    permissions:
      contents: read

    steps:
      - name: Descargar el código
        uses: actions/checkout@v4

      - name: Ejecutar build
        run: echo "Ejecutando build en un runner macOS autorizado"

De nuevo, macos-builds es un nombre de ejemplo. La organización tendría que crear y configurar el runner group correspondiente, asignar los runners adecuados y definir qué repositorios pueden usarlo.

La limitación anunciada por GitHub también debe tenerse presente: las network configurations no están soportadas para macOS runners en este momento. Si un pipeline macOS necesita conectividad especial hacia redes privadas o servicios internos, habrá que validar cuidadosamente el diseño antes de asumir que el nuevo control resuelve ese requisito.

Relación con seguridad y DevSecOps

Controlar runners no es solo una decisión de costes. Un runner ejecuta código potencialmente complejo, descarga dependencias, usa credenciales temporales y puede actuar sobre sistemas externos. En muchos pipelines modernos, un job de Actions puede desplegar infraestructura, publicar contenedores, lanzar análisis de seguridad o interactuar con entornos cloud.

Por eso, los runners deben considerarse parte de la superficie de seguridad de CI/CD.

Un job bien diseñado debería limitar sus permisos explícitamente:

name: security-conscious-ci

on:
  pull_request:
    branches:
      - main

jobs:
  validate:
    runs-on: ubuntu-24.04

    permissions:
      contents: read
      pull-requests: read

    steps:
      - name: Descargar el código
        uses: actions/checkout@v4

      - name: Ejecutar análisis estático
        run: echo "Ejecutando análisis estático sin permisos de escritura"

El bloque permissions reduce el alcance del token disponible para el job. Este control no sustituye a la política de runners, pero la complementa. La seguridad efectiva en GitHub Actions suele ser acumulativa:

  • permisos mínimos;
  • triggers adecuados;
  • uso prudente de secretos;
  • entornos protegidos para despliegues;
  • revisión de workflows;
  • y runners gobernados mediante grupos, labels o políticas de organización.

La nueva capacidad encaja especialmente bien en organizaciones que ya tratan CI/CD como una plataforma compartida. Si el pipeline es el mecanismo que valida, empaqueta y despliega software, entonces el entorno donde se ejecuta el pipeline también debe estar bajo control.

Impacto en despliegues cloud y automatización sobre Azure

En pipelines que interactúan con Azure, el control de runners es especialmente importante.

Un workflow de GitHub Actions puede autenticarse mediante federación OIDC contra Microsoft Entra ID, desplegar Bicep o Terraform, publicar imágenes de contenedor, ejecutar pruebas de integración o modificar configuración de servicios administrados. En esos casos, la distinción entre un job de validación y un job de despliegue no es menor.

Un patrón recomendable es separar workflows o jobs según su nivel de impacto:

  • jobs de validación con permisos de lectura;
  • jobs de planificación o análisis con permisos limitados;
  • jobs de despliegue sujetos a entornos protegidos, aprobaciones y runners más restringidos.

Por ejemplo:

name: deploy-infra

on:
  workflow_dispatch:

jobs:
  plan:
    runs-on:
      group: ci-linux-standard

    permissions:
      contents: read
      id-token: write

    steps:
      - name: Descargar el código
        uses: actions/checkout@v4

      - name: Autenticación federada con Azure
        run: echo "Este paso representaría la autenticación OIDC con Azure"

      - name: Validar plantilla de infraestructura
        run: echo "Validando infraestructura antes del despliegue"

  deploy:
    needs: plan
    runs-on:
      group: ci-linux-deploy

    environment: production

    permissions:
      contents: read
      id-token: write

    steps:
      - name: Descargar el código
        uses: actions/checkout@v4

      - name: Desplegar infraestructura
        run: echo "Desplegando cambios tras aprobación del entorno"

Los nombres ci-linux-standard y ci-linux-deploy son ilustrativos. La idea es mostrar una separación de capacidades:

  • ci-linux-standard para validaciones generales;
  • ci-linux-deploy para trabajos con mayor impacto operativo.

En una organización real, esos grupos deberían estar configurados en GitHub con permisos coherentes, límites adecuados y una documentación clara para los equipos consumidores.

Cómo planificar una migración desde labels estándar

Deshabilitar labels estándar sin preparación puede romper workflows existentes. La adopción debería tratarse como una migración de plataforma, no como un cambio aislado en la consola de administración.

El primer paso es inventariar el uso actual de runs-on en los repositorios. Conviene localizar referencias a labels como:

  • ubuntu-latest;
  • windows-latest;
  • macos-latest;
  • versiones concretas de runners hospedados;
  • grupos o labels personalizados ya existentes.

Un script sencillo para revisar un repositorio local podría ser:

#!/usr/bin/env bash
set -euo pipefail

echo "Buscando referencias a runners hospedados estándar en workflows..."

grep -RInE "runs-on:\s*(ubuntu-latest|windows-latest|macos-latest)" .github/workflows || true

Este ejemplo solo cubre casos simples. En organizaciones grandes, la revisión debería contemplar múltiples repositorios y workflows con sintaxis más compleja, incluyendo arrays, objetos YAML y plantillas reutilizables.

El segundo paso es definir la matriz de runners o runner groups permitidos. No todas las organizaciones necesitan una gran variedad. A menudo es mejor empezar con pocas capacidades bien documentadas:

  • Linux estándar para CI general;
  • Windows para compilaciones o pruebas específicas;
  • macOS para builds que realmente lo necesiten;
  • grupos separados para despliegues;
  • grupos con mayor control para workloads sensibles.

El tercer paso es publicar ejemplos de migración. Si un equipo ve que su workflow deja de ejecutarse sin entender la causa, percibirá la política como fricción. Si recibe una guía clara con equivalencias aprobadas, el cambio será más fácil de adoptar.

El cuarto paso es aplicar la restricción gradualmente. Una estrategia razonable puede ser:

  1. auditoría inicial;
  2. pilotos en repositorios no críticos;
  3. migración de equipos con acompañamiento;
  4. activación progresiva de restricciones;
  5. monitorización de jobs en cola, fallos de workflow y solicitudes de nuevos runner groups.

Recomendaciones prácticas para administradores

La nueva capacidad será más útil si forma parte de un modelo explícito de gobierno. Bloquear ubuntu-latest sin ofrecer una alternativa clara solo trasladará el problema a los equipos de desarrollo.

Algunas recomendaciones prácticas:

  • Define runner groups con propósito claro.
  • Documenta qué repositorios pueden usar cada grupo.
  • Establece límites de concurrencia donde el coste o la capacidad sean relevantes.
  • Evita usar latest en pipelines que requieran reproducibilidad estricta.
  • Limita permisos de GITHUB_TOKEN en cada workflow.
  • Revisa los triggers, especialmente en pull requests.
  • Separa validación, publicación y despliegue.
  • Usa entornos protegidos para producción.
  • Monitoriza consumo y colas de ejecución.
  • Mantén una vía clara para solicitar nuevas capacidades.

También conviene versionar las decisiones de plataforma. Si un grupo llamado ci-linux-standard representa una capacidad aprobada, los equipos deberían saber qué pueden esperar de él: sistema operativo, herramientas principales, restricciones, límites y proceso de cambio.

Un cambio pequeño con impacto de plataforma

La posibilidad de deshabilitar labels estándar de GitHub-hosted runners introduce un control importante para organizaciones que quieren madurar su uso de GitHub Actions.

Para equipos pequeños, labels como ubuntu-latest seguirán siendo cómodos cuando estén permitidos. Para organizaciones con requisitos de seguridad, coste, cumplimiento o despliegues cloud, el nuevo control permite construir una capa de ejecución más intencional.

El valor no está solo en bloquear una etiqueta. Está en usar esa capacidad para ordenar la relación entre equipos de producto, plataforma y seguridad. GitHub Actions es ya una pieza central de muchas arquitecturas modernas de entrega de software; controlar dónde y cómo se ejecutan sus jobs es una decisión de arquitectura, no una preferencia menor de YAML.

Fuente