
Encuentra los secretos en texto plano en tu Mac y muévelos detrás de Touch ID, inyectados justo a tiempo sin romper las herramientas que los leen. Gratuito y local-first.
Credenciales just-in-time para tu máquina de desarrollo.
Documentación · Inicio rápido · Herramientas compatibles · Referencia de comandos · Seguridad
Estado: solo macOS (Apple Silicon), y aún en desarrollo.
Tus secretos viven en texto plano por toda tu máquina: archivos .env,
~/.aws/credentials, exports de ~/.zshrc, tokens de .npmrc, configuraciones de MCP. Cualquier cosa que se ejecute como tú puede leerlos. Un mal curl | sh, un npm install sospechoso, o uno de los agentes de IA que ahora se ejecutan en tu editor con todos tus permisos.
jit mueve cada secreto a una bóveda cifrada local protegida por Touch ID, y reescribe los archivos para que tus herramientas sigan funcionando. En el disco ahora hay un señuelo. El valor real solo aparece, en memoria, para el proceso específico que lo solicitó, después de una solicitud biométrica. El resultado: desbloqueas una vez, jit pregunta antes de entregar una credencial a una herramienta (o a un agente), y hay un señuelo en el disco el resto del tiempo.
| lanzado por Code | lanzado por claude |
|---|---|
![]() | ![]() |
Lo que no hace: no hace seguro una cuenta ya comprometida, y no protege un secreto una vez que está en la memoria del proceso que lo solicitó. Los límites se exponen en una página, desde el principio: los límites deliberados.
Sin extensión de kernel, sin controlador de sistema de archivos, sin FUSE. Tres mecanismos, elegidos por lo que la herramienta puede hacer:
execve. La propia imagen de jit es reemplazada por tu comando, así que el valor vive en ese único proceso y jit desaparece de la memoria.credential_process de AWS, ayudantes de credenciales de docker y git, plugins exec de kubectl, el ayudante de credenciales de Terraform. La herramienta pregunta, jit responde, sin archivos de por medio.El montaje es un FIFO POSIX, creado con mkfifo(2) en modo 0600. Un programa que llama a open(".env") se bloquea en el kernel hasta que un escritor se conecta. El servicio en segundo plano es ese escritor: abre la ruta con O_WRONLY, lo que libera al lector, escribe los bytes descifrados desde la memoria en el buffer del pipe del kernel, cierra, y vuelve a open(2) para el siguiente lector. Nada toca el disco. Lo que se escribe se decide por lectura: señuelos para un lector ambiental, valores reales solo dentro de una ejecución que autorizaste.
La identidad del llamante explica y audita, nunca decide. Los nombres de proceso son falsificables, y un lector FIFO que se cierra rápido puede evadir la identificación por completo. El humano que responde a la solicitud es la puerta; el nombre del proceso solo te dice qué responder. Detalle completo en cómo funciona y montajes en vivo.
brew install jitpass/tap/jitpass
Esa es la ruta recomendada, y para una herramienta de seguridad el motivo importa. Las versiones están firmadas con un Apple Developer ID y notarizadas por Apple. Homebrew pone en cuarentena lo que descarga, así que Gatekeeper verifica el binario contra su ticket de notarización antes de que se le permita ejecutarse. Para verificarlo tú mismo en lugar de fiarte de nuestra palabra, ejecuta jit doctor: su línea jit informa signed CZC6BH93GJ, la misma comprobación que jit upgrade ejecuta antes de instalar nada.
curl -sL https://dl.jitpass.com/jitpass/jit/releases/latest/download/jitpass_darwin_arm64.tar.gz | tar -xz jit
shasum -a 256 jit # compara con checksums.txt en la página de la versión
codesign -dv --verify --verbose=2 ./jit # espera: Developer ID, TeamIdentifier=CZC6BH93GJ
sudo mv jit /usr/local/bin/
Esto está aquí para personas sin Homebrew, y es genuinamente la ruta más débil: curl no establece el bit de cuarentena, así que Gatekeeper nunca consulta el ticket de notarización, y lo mismo ocurre con go install. El binario sigue firmado y notarizado, así que las dos líneas anteriores te permiten verificar ambas cosas antes de ejecutarlo, pero tienes que ejecutarlas de verdad. Si tienes Homebrew, usa Homebrew.
Solo Apple Silicon. En un Mac Intel, compila desde el código fuente con
go install github.com/jitpass/jit/cmd/jit@latest.
Elige una ruta. Si instalaste desde el tarball antes y estás cambiando a Homebrew, elimina la copia antigua después del brew install (sudo rm /usr/local/bin/jit); de lo contrario, dos jits estarán en PATH actualizándose por separado, y jit doctor lo señalará.
Actualización: brew upgrade jitpass, o jit upgrade: una auto-actualización verificada (firma Developer-ID y checksum ambos comprobados antes del intercambio, reinicia el servicio). De cualquier manera, tu bóveda no se toca.
Homebrew instala la finalización de shell con el binario, así que jit <TAB> completa subcomandos, flags, rutas de bóveda y nombres de herramientas envolubles de fábrica. Si instalaste desde el tarball o desde el código fuente, añádela tú mismo:
echo 'source <(jit completion zsh)' >> ~/.zshrc && exec zsh
De cualquier manera, jit doctor te dice si la finalización no está llegando a tu shell.
jit scan # solo lectura. no cambia ningún archivo que escanea, no imprime ningún valor real.
jit vault init # crea la bóveda (clave maestra en tu llavero de inicio de sesión)
jit migrate --dry-run # previsualiza todo el plan de corrección a nivel de máquina
jit migrate # aplícalo: muestra el plan, pregunta [y/N], un Touch ID
jit migrate ~/code/myapp # o corrige solo un proyecto
jit run -- npm run dev # ejecuta tu herramienta; los valores reales se inyectan solo en ese proceso
jit scan sin ruta recorre todo tu directorio personal, así que dale un momento si es grande. Para ir directo a un lugar, apúntalo a una ruta: jit scan ~/.aws.
En el día a día es principalmente jit run -- <cmd>. Para CLIs que llevan su propio token de inicio de sesión (gh, glab, stripe, y más) haces jit wrap gh una vez y luego sigues escribiendo gh como siempre, para siempre.
¿No estás seguro de si algo necesita jit wrap, jit migrate, o nada? No tienes que saberlo. jit scan divide todo lo que encuentra en lo que jit protegerá (un comando - los wraps incluidos) y lo que solo tú puedes corregir, y jit migrate sin más ejecuta todo ese plan:
$ jit scan
TUS SECRETOS: 7 — 0 protegidos por jit (0%)
▱▱▱▱▱▱▱▱▱▱ al 100%: un comando +71% · 2 secretos que solo tú puedes corregir +29%
jit protegerá estos — 5 secretos en 4 archivos, 0% → 71%
→ jit migrate
~/.zshrc STRIPE_API_KEY, DB_PASSWORD
~/.config/gh/hosts.yml token de GitHub CLI · envuelve gh
...
solo tú puedes proteger estos — 2 secretos, 71% → 100%
[rota, luego elimina cada copia]
! Una contraseña de base de datos de producción en 2 archivos
→ rótala ahora, luego elimina cada copia
(jit scan --full sigue dando el inventario clásico por categorías con severidades, incluyendo la sección Tokens CLI Envolubles.)
Migra la credencial una vez, luego sigue usando la herramienta como siempre lo has hecho.
# AWS (y Terraform, y cada SDK de AWS)
jit migrate ~/.aws/credentials # las claves se mueven a la bóveda; no queda archivo en texto plano
aws s3 ls # se resuelve desde la bóveda bajo demanda. sin prefijo, sin flag.
terraform apply # mismas credenciales, mismo comando
# Credenciales de aplicación predeterminadas de GCP (una credencial a nivel de máquina)
jit migrate ~/.config/gcloud/application_default_credentials.json
terraform apply # el proveedor de google lee ADC; funciona tras una solicitud de Touch ID
# Docker / docker-compose
jit migrate ~/.docker/config.json # los inicios de sesión de registros se mueven a la bóveda
jit run -- docker compose up # jit los inyecta para esta ejecución
docker login ghcr.io # sigue funcionando; el ayudante almacena en la bóveda
# Exports de shell que solían estar en ~/.zshrc
jit migrate ~/.zshrc # deja un hook de una línea; los nuevos shells solo tienen las variables
./deploy.sh # los scripts que leen esas variables funcionan sin cambios
# Tokens que una vez escribiste en el prompt, ahora en tu historial de shell
jit migrate ~/.zsh_history # cada uno se mueve a la bóveda; tus comandos se quedan, los secretos no
jit guard history # y evita que el siguiente se registre por completo (zsh)
# (`jit migrate` sin más también lo ofrece, en el plan que te pide confirmar)
# Una CLI que lleva su propio token (gh, stripe, glab)
jit wrap gh # una vez
gh pr list # token inyectado por llamada, para siempre
La primera vez que cada herramienta busca una credencial real, jit pregunta una vez y recuerda tu respuesta hasta que la bóveda se bloquea. Consulta Dos momentos de Touch ID, no uno para ver cómo se superpone al desbloqueo de la bóveda, qué hace --trust, y cómo desactivar las solicitudes por herramienta.
¿Por qué algunas herramientas no necesitan configuración mientras que otras requieren un jit run? Una regla: ¿puede la herramienta pedirle el secreto a jit por sí misma? AWS (vía credential_process), tu shell al iniciar sesión, y los inicios de sesión de registros de docker (vía un ayudante de credenciales) pueden, así que no escribes nada extra. Las herramientas que solo leen un archivo en tiempo de ejecución (docker compose, SDKs simples) no pueden pedirlo, así que jit run les entrega el valor.
Los archivos de credenciales globales de la máquina (ADC de GCP, sops, npm, netrc) funcionan igual en el día a día: ejecuta tu herramienta y aprueba la solicitud por proceso. Añade jit run --with <name> solo cuando quieras que sea explícito: para scripts y CI donde no hay prompt que responder, o cuando quieras una puerta dura que la propia configuración de un proyecto nunca pueda alcanzar. Herramientas compatibles lista exactamente qué escribir para cada herramienta, y cómo se entrega cada una.
jit pide tu huella digital en dos momentos diferentes, haciendo dos trabajos diferentes:
jit después de que se bloquea, un Touch ID abre la bóveda para toda la sesión (5 minutos de actividad, luego se vuelve a bloquear; y nunca más de 8 horas, por muy ocupado que estés). Desbloqueas una vez, no una vez por comando.jit pregunta antes de entregarla y nombra qué está pidiendo. Esto es lo que evita que un programa que no ejecutaste use silenciosamente tus claves mientras la bóveda está abierta.$ aws s3 ls
Touch ID -> desbloquea tu bóveda # puerta 1: abre la bóveda por 5 min
Touch ID -> aws quiere tu credencial de aws # puerta 2: esta herramienta, esta credencial
...tus buckets...
$ aws s3 cp ./file s3://bucket/ # misma herramienta, misma sesión: sin solicitud
$ terraform apply
Touch ID -> terraform quiere tu credencial de aws # una herramienta diferente: pregunta por su cuenta
La puerta 2 es lo que evita que una bóveda desbloqueada sea un acceso libre para todos: incluso después de que tú mismo hayas usado aws, un npm install sospechoso que busque esas mismas claves sigue disparando una solicitud que lo nombra, para que puedas decir que no.
¿No quieres la segunda puerta? Desactívala; el bloqueo de la bóveda permanece (desactivarla en sí requiere un Touch ID, ya que reabre la ventana que cierra):
jit service consent off # las herramientas se resuelven silenciosamente mientras la bóveda está desbloqueada
jit service consent on # preguntar por herramienta de nuevo (el valor predeterminado)
¿Vas a lanzar algo que necesita varias credenciales a la vez? jit run --trust -- terraform apply aprueba las herramientas de toda esa ejecución con un solo gesto. Detalles completos:
consentimiento por proceso.
jit grantAmbas puertas asumen que hay un humano presente para responder. Un agente de IA trabajando toda la noche, una compilación larga, un trabajo programado: la pantalla se bloquea, la sesión se cae, y la ejecución se detiene en una solicitud que nadie verá. Una concesión de proceso mueve tu decisión más temprano en lugar de eliminarla - un Touch ID, dado mientras sigues ahí, que nombra exactamente lo que estás firmando:
$ jit grant --process claude --profile jamf --for 8h
Touch ID -> permitir que claude bajo iTerm2 use 2 secretos (jamf) sin supervisión por 8h
✓ concedido g-7f3a2c81 claude -> jamf hasta las 17:42
└ cubre claude bajo iTerm2: 1 ejecutándose ahora, cualquiera iniciado antes de las 17:42
Durante las próximas 8 horas, cada claude bajo la terminal donde escribiste eso (y lo que lance) obtiene esos secretos sin solicitudes - a través del bloqueo de pantalla y todo, incluyendo sesiones que inicies más tarde: una nueva pestaña, el siguiente claude, un script que se dispara a las 3am. Es tu terminal la que se nombra, no un nombre en el que se confía: un programa que se llame claude en otro lugar de la máquina no desciende de ese árbol y no hereda nada. La concesión termina en su fecha límite, cuando cierras esa terminal, o en el momento en que escribes jit grant revoke (que no necesita huella digital - quitar acceso siempre es gratis). ¿Quieres un proceso exacto en su lugar, que desaparezca cuando salga? --pid. Cada concesión aterriza en el registro de auditoría como su propio evento, así que a la mañana siguiente puedes leer exactamente qué tocó tu agente mientras dormías. Detalles completos:
concesiones de proceso.
El agente en tu editor se ejecuta como tú, con tus permisos, y lee archivos por ti todo el día. Ese es el punto completo de él, y también es por lo que un .env en texto plano en tu repositorio es ahora un riesgo muy diferente al de hace dos años. jit trata a los agentes como ciudadanos de primera clase, en cuatro frentes:
jit migrate ~/.claude.json # configuraciones de servidores MCP: las claves se mueven a la bóveda,
# cada servidor ahora se lanza a través de `jit run`
jit wrap claude # los propios CLIs de IA: claude, codex, gemini,
# cursor-agent, copilot, cline, opencode, kiro-cli
jit grant --process claude --profile myapp --for 8h
# déjalo trabajar toda la noche sin una solicitud que nadie responde
jit audit --parent claude # lee exactamente qué tocó mientras dormías
claude, cada uno nombrado. Un agente leyendo silenciosamente ~/.aws/credentials es una solicitud, no un éxito silencioso.jit run. Una configuración MCP migrada contiene rutas de bóveda, no claves, así que el propio archivo de configuración es seguro de tener en disco y seguro de entregar al agente que lo lee..env en tu repositorio y lo lea en frío obtiene valores de relleno, y la lectura queda registrada.jit audit --parent claude muestra cada secreto que un agente usó, cada solicitud que disparó, y cada una que rechazaste.Más en Herramientas MCP / IA y consentimiento por proceso.
Cada comando de jit y cada desbloqueo aterriza en un registro duradero que lees con jit audit, del más reciente al más antiguo, una línea key=value por evento, así que se filtra como un registro de servicio real. Los argumentos de los comandos están enmascarados, así que el registro prueba que un comando se ejecutó sin almacenar nunca el secreto que llevaba.
$ jit audit --since 1h
time=2026-07-24 10:15:04 level=info kind=cmd status=ok dur=312ms cmd="jit migrate ~/.aws/credentials" user=meni parent=claude
time=2026-07-24 10:16:22 level=info kind=use op="read a secret" cmd="aws s3 ls" parent=claude secrets=aws/default
time=2026-07-24 10:31:09 level=warn kind=unlock status=denied method=touchid-or-passcode cmd="node postinstall.js" parent=npm secrets=aws/default
La línea del medio es la historia que jit existe para contar: aws/default fue leído por aws s3 ls, lanzado por claude. La última es una solicitud que rechazaste: un node postinstall.js bajo npm buscando esas mismas claves, denegado. jit también registra lo que el servicio rechazó en su socket (un proceso que el kernel dice que no es tuyo, sondeando al agente) como kind=error.
Redúcelo con flags en lugar de grep: --kind, --status ok|failed|denied, --since/--until (una antigüedad como 2h/3d o una fecha), --parent claude, --secret aws, --user, --grep <regexp>. Añade --follow (-f) para transmitir nuevos eventos en vivo como tail -f, o --format json para un volcado analizable por máquina. Ambas mitades son archivos duraderos junto a la bóveda, así que responde por la semana pasada tan fácilmente como por la última hora.
Archivos .env, exports de shell, AWS y Terraform, kubeconfig, inicios de sesión de registros de Docker, ADC de GCP, tokens de .npmrc / .netrc, configuraciones de servidores MCP, archivos de tokens simples, credenciales registradas en tu historial de shell, CLIs envolubles (gh, stripe, vercel, …), y CLIs SSO que acuñan credenciales al iniciar sesión (clisso). En cada caso el archivo sigue funcionando y el valor real viene de la bóveda bajo demanda.
El catálogo completo, agrupado por exactamente qué escribir para cada herramienta, está en
Herramientas compatibles: sigue el código a medida que se añaden o eliminan herramientas. Cualquier cosa no listada aún puede envolverse con
jit wrap add.
¿Ya guardas tus secretos en 1Password? Con su CLI instalado,
jit migrate enlaza en lugar de copiar: un
valor que ya vive en 1Password se guarda en la bóveda como su referencia op://,
así que 1Password sigue siendo el sistema de registro y jit entrega el valor
just-in-time a través de cada mecanismo anterior (jit vault link hace lo mismo
para un secreto a mano).
jit nunca destruye una credencial. Migrar mueve el valor a la bóveda y deja un hook funcional donde estaba (un .env señuelo, una línea eval "$(jit export)" en tu configuración de shell, credential_process = jit … en ~/.aws/config, o un shim de PATH), así que tus herramientas siguen resolviéndolo bajo demanda. La credencial sigue existiendo, solo que cifrada en lugar de estar en texto plano.
Y cada cambio es reversible. Antes de tocar un archivo, jit hace una copia de seguridad cifrada en la bóveda, así que jit migrate undo lo restaura byte por byte:
jit migrate ~/code/myapp # aplicó la corrección, un Touch ID
# ¿cambiaste de opinión, o algo se rompió?
jit migrate undo ~/code/myapp # cada archivo tocado restaurado, byte por byte
La documentación vive bajo docs/, organizada por tarea:
git commit -s), sin CLALicencia PolyForm Perimeter 1.0.0 - gratuita solo para uso personal e interno de empresas.