macOS BuildCaptain fija tus pipelines de Jenkins en la barra de menús de macOS — estado, logs y controles de build a un clic.

Tokens de API de Jenkins: crear, acotar, rotar y revocar

En qué se diferencian los tokens de API de Jenkins de las contraseñas, cómo crear uno, a qué se pueden acotar (y a qué no) y cómo guardarlos y rotarlos sin exponer tu servidor de CI.

Loris Siegenthaler Escrito por Loris Siegenthaler · Creador de BuildCaptain
10 min de lectura
Actualizado el 7 de agosto de 2026

Un token de API es la credencial que le entregas a cualquier cosa que no sea un humano sentado ante un navegador: un script, una pipeline de despliegue, una herramienta de monitorización, un cliente de escritorio. Jenkins hace que sean fáciles de crear, y por eso tantos acaban pegados en un shell script dentro de un repositorio, todavía válidos tres años después.

Esta guía recorre el ciclo de vida completo — qué es realmente un token, cómo crear uno, la limitación de alcance de la que nadie te avisa y cómo rotar y revocar sin romper nada.

Tokens frente a contraseñas

Ambos funcionan para la autenticación HTTP básica contra Jenkins, así que, vistos desde la red, son idénticos. La diferencia está en todo lo que los rodea.

  • Los tokens se revocan individualmente. Un token por consumidor significa que puedes matar el que se filtró sin cambiar la contraseña que todos los demás consumidores están usando.
  • Los tokens sobreviven al SSO. Si tu Jenkins se autentica contra SAML, OIDC, LDAP o GitHub OAuth, a menudo no hay ninguna contraseña que enviar — el token es la única credencial que funciona para el acceso no interactivo.
  • Los tokens se saltan el crumb de CSRF. Jenkins protege las peticiones que cambian estado con un crumb (su token CSRF), y la documentación es explícita en que las peticiones autenticadas con un token de API están exentas de él. Por eso un curl -X POST con token funciona sin más, mientras que la misma petición con una cookie de sesión recibe un 403 "No valid crumb was included" a menos que antes obtengas uno de /crumbIssuer/api/json. La propia guía de acceso remoto de Jenkins prefiere los tokens a hacer malabares con crumbs exactamente por esta razón.
  • Los tokens son rastreables. Cada uno lleva el nombre que le diste, una fecha de creación y un contador de uso, así que puedes ver cuáles se están usando de verdad y cuáles se acuñaron para un script que ya no existe.

Lo que los tokens no son es una credencial de privilegios reducidos. Mira la sección de alcance más abajo — esa es la parte que sorprende a más de uno.

Crear un token

Haz clic en tu nombre en la esquina superior derecha y luego en Security en la barra lateral (las versiones antiguas llaman a la página Configure). /me/security es el atajo en cualquier Jenkins. Bajo API Token, elige Add new token, dale un nombre que diga quién lo usa — deploy-script, grafana, buildcaptain-laptop, no token1 — y haz clic en Generate.

Copia el valor ahora. El propio Jenkins lo dice: "Copy this token now, because it cannot be recovered in the future." Solo almacena un hash.

Los administradores pueden hacer lo mismo para una cuenta de servicio cuya contraseña no tienen, en /user/<username>/security (vía Manage Jenkins → Security → Users). Así es como aprovisionas una cuenta bot sin iniciar sesión con ella jamás.

Jenkins sustituyó el antiguo token único por usuario por múltiples tokens con nombre y revocables en la weekly 2.129 / LTS 2.138.1. En instancias actualizadas desde antes de eso, puede seguir existiendo en una cuenta un token legacy visible, marcado con una advertencia en la página de seguridad del usuario. Mueve lo que lo use a un token con nombre y luego revócalo — una vez revocado no puede recrearse, que es justamente la idea. Los administradores también pueden desactivar los tokens legacy en toda la instancia, y ese ajuste queda por defecto en "todavía permitidos" en las instancias actualizadas.

Los tokens también pueden crearse sin la interfaz, que es lo que quieren los scripts de aprovisionamiento:

curl -X POST -u "alice:$JENKINS_ADMIN_TOKEN" \
  "https://jenkins.example.com/user/jenkins-bot/descriptorByName/jenkins.security.ApiTokenProperty/generateNewToken" \
  --data "newTokenName=deploy-script"

El endpoint es solo POST. La respuesta es JSON con un objeto data que contiene tokenName, tokenUuid y tokenValue. Guarda el UUID — es lo que recibe la llamada de revocación correspondiente:

curl -X POST -u "alice:$JENKINS_ADMIN_TOKEN" \
  "https://jenkins.example.com/user/jenkins-bot/descriptorByName/jenkins.security.ApiTokenProperty/revoke" \
  --data "tokenUuid=$TOKEN_UUID"

Usa /me/… en lugar de /user/<id>/… para tu propia cuenta. En cualquier caso necesitas ser ese usuario o un administrador de Jenkins.

Usar un token

Todo en Jenkins tiene una representación JSON — añade /api/json a casi cualquier URL que puedas abrir en un navegador.

# Who am I, and what can I see?
curl -u "jenkins-bot:$JENKINS_TOKEN" \
  "https://jenkins.example.com/api/json?pretty=true"

# The last five builds of one job, only the fields you need
curl -u "jenkins-bot:$JENKINS_TOKEN" \
  "https://jenkins.example.com/job/my-app/api/json?tree=builds[number,result,timestamp]{0,5}"

# The console log of a specific build
curl -u "jenkins-bot:$JENKINS_TOKEN" \
  "https://jenkins.example.com/job/my-app/42/consoleText"

Merece la pena aprender pronto el parámetro tree. Sin él, /api/json en un job con actividad devuelve un payload que se mide en megabytes; con él obtienes los cuatro campos que pediste.

Disparar builds debería ser un POST. El core de Jenkins acepta de hecho GET en ambos endpoints de build, pero POST es lo que usa la documentación y lo que todo proxy, log y revisor espera de una llamada que cambia estado — y un GET a secas a /build en un job parametrizado renderiza el formulario de parámetros en lugar de arrancar nada, lo que da para cinco minutos de confusión.

# A job with no parameters
curl -X POST -u "jenkins-bot:$JENKINS_TOKEN" \
  "https://jenkins.example.com/job/my-app/build"

# A parameterised job
curl -X POST -u "jenkins-bot:$JENKINS_TOKEN" \
  "https://jenkins.example.com/job/my-app/buildWithParameters" \
  --data-urlencode "BRANCH=release/2.4" \
  --data-urlencode "DEPLOY=false"

Un disparo con éxito devuelve 201 Created con una cabecera Location que apunta al elemento de la cola, no a una build. El número de build aún no existe — la build primero tiene que salir de la cola. Sondea el /api/json del elemento de la cola hasta que aparezca un objeto executable y lee el número de ahí.

Una nota de higiene de shell: -u user:token pone el token en la lista de procesos, donde cualquier otro usuario de la máquina puede leerlo. En un host compartido, usa curl --netrc-file con un archivo 0600, o pásale la credencial por una tubería, en lugar de interpolarla en la línea de comandos.

Alcance: la parte que sorprende

Un token de API de Jenkins no tiene alcance. No es una credencial acotada con una lista de permisos adjunta, como sí lo es un token fine-grained de GitHub. Se autentica como tú y, por tanto, lleva todos los permisos que tiene tu cuenta.

Si eres administrador de Jenkins y pegas un token en un shell script, ese script ahora puede reconfigurar jobs, instalar plugins y ejecutar Groovy arbitrario en el controlador. Da igual que lo único que quisieras fuera leer el estado de una build.

Como no hay alcance por token, acota al usuario en su lugar. Crea una cuenta de servicio dedicada por consumidor y dale lo mínimo:

  • Monitorización de solo lecturaOverall/Read, Job/Read y View/Read. Suficiente para listar jobs, leer resultados de builds y obtener logs de consola.
  • Disparar builds — añade Job/Build, y Job/Cancel si la herramienta necesita detener ejecuciones.
  • NuncaOverall/Administer, Job/Configure ni Run/Replay en una cuenta de servicio. Run/Replay en particular significa ejecución arbitraria de código de pipeline.

Los dos plugins que hacen esto práctico son Matrix Authorization Strategy (matrix-auth — una cuadrícula de usuarios contra permisos, opcionalmente por carpeta o por job) y Role-based Authorization Strategy (role-strategy — roles con nombre aplicados a usuarios y a patrones de nombres de jobs). Matrix es más simple y va bien hasta unas cuantas docenas de cuentas; la estrategia de roles escala mejor cuando ya tienes equipos de verdad. En ambos casos el objetivo es el mismo: el radio de impacto de un token filtrado es lo que esa única cuenta de servicio podía hacer.

Los permisos por carpeta son el truco infravalorado aquí. Concede a la cuenta de servicio Job/Read solo sobre la carpeta platform/, y un token que se filtre ni siquiera podrá enumerar el resto de tus jobs.

Rotación y revocación

Los tokens de Jenkins no caducan. Nada te lo va a recordar, así que ponlo en el calendario — trimestral es un valor por defecto razonable, inmediatamente ante cualquier sospecha y siempre que alguien se marcha del equipo.

Los tokens con nombre convierten la rotación en un trámite, siempre que lo hagas en este orden:

  1. Crea un token nuevo en la misma cuenta, con el nombre del mismo consumidor más una fecha: deploy-script-2026-08.
  2. Despliégalo en el consumidor y confirma que funciona.
  3. Revoca el token antiguo desde Security → API Token.

Nunca revoques primero. La ventana de solapamiento es precisamente la razón de que existan múltiples tokens con nombre.

El contador de uso junto a cada token te dice si una rotación surtió efecto de verdad: después de un día con el token nuevo en su sitio, el contador del antiguo debería haber dejado de moverse. También es la forma más rápida de encontrar tokens muertos — cualquiera sin uso reciente es o un script que ya nadie ejecuta o una credencial que alguien copió y olvidó, y ambos deberían revocarse.

Si un token se ha filtrado, revoca primero; todo lo demás viene después. Revisa entonces Manage Jenkins → System Log y el log de acceso de tu proxy inverso para ver qué hizo esa cuenta, y rota también el resto de los tokens de esa cuenta — una filtración desde un portátil compartido o un repositorio público rara vez implica exactamente un secreto.

Un administrador puede revocar los tokens de otro usuario desde la página de configuración de ese usuario, que es lo que quieres el día en que alguien se marcha. Eliminar o desactivar la propia cuenta invalida todos sus tokens de una vez.

Dónde guardar el token

Las reglas, en su versión más corta:

  • No en un repositorio. Ni en un script, ni en un .env, ni en un archivo YAML, ni en un comentario. Git no olvida; reescribir el historial a posteriori es un suplicio y, aun así, una solución a medias.
  • No en los logs de CI. Nunca hagas echo de un token, y ten cuidado con set -x en un step de shell — imprimirá encantado el comando curl completo.
  • No en una nota de contraseñas compartida. En un token por consumidor se apoya todo el mecanismo; compartir uno entre cuatro herramientas lo echa por tierra.

En macOS el almacén correcto es el Keychain, y se puede usar por script:

# Store it once (the -w flag prompts, so it never lands in your shell history)
security add-generic-password -a jenkins-bot -s jenkins-api-token -w

# Read it back when you need it
JENKINS_TOKEN=$(security find-generic-password -a jenkins-bot -s jenkins-api-token -w)

Dentro del propio Jenkins, un token pertenece al almacén de credenciales como credencial de tipo "Username with password" y se recupera con withCredentials, que lo enmascara en el log de la build:

withCredentials([usernamePassword(
    credentialsId: 'jenkins-bot-api',
    usernameVariable: 'JENKINS_USER',
    passwordVariable: 'JENKINS_TOKEN'
)]) {
    sh 'curl -sS -u "$JENKINS_USER:$JENKINS_TOKEN" "$JENKINS_URL/api/json"'
}

Fíjate en las comillas simples alrededor del script de sh. Con comillas dobles, Groovy interpola el secreto en la cadena del comando antes de que Jenkins llegue a verla, el enmascarado no se aplica y tu token aparece en el log de consola en texto plano.

Una lista de comprobación breve

  • Un token con nombre por consumidor, con el nombre del consumidor.
  • Cuentas de servicio, no tu propia cuenta, para todo lo automatizado.
  • Permisos mínimos vía Matrix o Role Strategy — por carpeta donde puedas.
  • Guardado en un almacén de secretos de verdad: el Keychain, el almacén de credenciales de Jenkins o tu gestor de secretos.
  • Rotado según calendario, con el nuevo antes que el viejo.
  • Revocado en el momento en que un consumidor se retira o un portátil desaparece.

Si estás conectando nuestra propia app, la versión corta de todo esto vive en el centro de ayuda: Conecta tu servidor Jenkins te guía por la creación del token y su introducción en la app. Y por decir lo evidente: BuildCaptain es nuestra app, un cliente nativo de la barra de menús de macOS para Jenkins. Sigue sus propios consejos — el token va al Keychain de macOS, nunca a un archivo de configuración, y una cuenta de servicio de solo lectura con Job/Read basta para vigilar tus pipelines.