
Найдите секреты в открытом виде на вашем Mac и переместите их под защиту Touch ID, подставляя их ровно в тот момент, когда они нужны, не ломая инструменты, которые их читают. Бесплатно и полностью локально.
Учётные данные «точно в срок» для вашей машины разработчика.
Документация · Быстрый старт · Поддерживаемые инструменты · Справочник команд · Безопасность
Статус: только macOS (Apple Silicon), всё ещё в разработке.
Ваши секреты лежат в открытом виде по всей машине: файлы .env,
~/.aws/credentials, экспорты в ~/.zshrc, токены в .npmrc, конфиги MCP. Любая
программа, запущенная от вашего имени, может их прочитать. Опасный curl | sh, сомнительный npm install или один
из ИИ-агентов, которые теперь работают в вашем редакторе с вашими полными правами.
jit перемещает каждый секрет в локальное зашифрованное хранилище, защищённое Touch ID, и
переписывает файлы так, чтобы ваши инструменты продолжали работать. На диске теперь лежит приманка. Настоящее
значение появляется только в памяти конкретного процесса, который его запросил,
после биометрического запроса. Итог: вы разблокируетесь один раз, jit спрашивает перед выдачей
учётных данных инструменту (или агенту), а в остальное время на диске лежит приманка.
| запущено из Code | запущено из claude |
|---|---|
![]() | ![]() |
Чего он не делает: он не делает уже скомпрометированную учётную запись безопасной, и он не защищает секрет, оказавшийся в памяти процесса, который его запросил. Границы описаны на одной странице, сразу: осознанные ограничения.
Никаких расширений ядра, драйверов файловой системы или FUSE. Три механизма, выбранных по возможностям инструмента:
execve. Собственный образ jit
заменяется вашей командой, поэтому значение живёт в этом одном процессе, а jit
исчезает из памяти.credential_process, хелперы учётных данных docker и git, плагины kubectl exec,
хелпер учётных данных Terraform. Инструмент спрашивает, jit отвечает, без
участия файлов.Монтирование — это POSIX FIFO, созданный с помощью mkfifo(2) с режимом 0600. Программа,
вызывающая open(".env"), блокируется в ядре, пока не подключится писатель. Фоновый
сервис и есть этот писатель: он открывает путь с флагом O_WRONLY, что
освобождает читателя, записывает расшифрованные байты из памяти в буфер
канала ядра, закрывает его и возвращается к open(2) для следующего читателя. Ничего
не касается диска. Что записывается, решается при каждом чтении: приманки для фонового
читателя, настоящие значения — только внутри запуска, который вы авторизовали.
Идентификация вызывающего объясняет и аудирует, но никогда не решает. Имена процессов можно подделать, а быстро закрывающийся читатель FIFO может вообще уйти от идентификации. Человек, отвечающий на запрос, — это шлюз; имя процесса лишь подсказывает, что отвечать. Подробности — в как это работает и живые монтирования.
brew install jitpass/tap/jitpass
Это рекомендуемый путь, и для инструмента безопасности причина важна.
Релизы подписаны Apple Developer ID и нотаризованы Apple.
Homebrew помещает скачанное в карантин, поэтому Gatekeeper проверяет бинарник
по его нотаризационному билету, прежде чем разрешить запуск. Чтобы проверить
это самостоятельно, а не верить нам на слово, выполните jit doctor: его строка
jit сообщает signed CZC6BH93GJ — ту же проверку jit upgrade выполняет перед
установкой чего-либо.
curl -sL https://dl.jitpass.com/jitpass/jit/releases/latest/download/jitpass_darwin_arm64.tar.gz | tar -xz jit
shasum -a 256 jit # сравните с checksums.txt на странице релиза
codesign -dv --verify --verbose=2 ./jit # ожидайте: Developer ID, TeamIdentifier=CZC6BH93GJ
sudo mv jit /usr/local/bin/
Это для тех, у кого нет Homebrew, и это действительно более слабый
путь: curl не устанавливает бит карантина, поэтому Gatekeeper никогда не обращается к
нотаризационному билету, и то же самое верно для go install. Бинарник
по-прежнему подписан и нотаризован, поэтому две строки выше позволяют проверить и то и другое
до запуска, но их нужно реально выполнить. Если у вас есть Homebrew,
используйте Homebrew.
Только Apple Silicon. На Mac с Intel соберите из исходников с помощью
go install github.com/jitpass/jit/cmd/jit@latest.
Выберите один путь. Если вы раньше устанавливали из архива и переходите на
Homebrew, удалите старую копию после brew install (sudo rm /usr/local/bin/jit); иначе два jit окажутся в PATH и будут обновляться по отдельности, а
jit doctor на это укажет.
Обновление: brew upgrade jitpass или jit upgrade: проверенное
самообновление (подпись Developer-ID и контрольная сумма проверяются до
замены, сервис перезапускается). В любом случае ваше хранилище не затрагивается.
Homebrew устанавливает автодополнение shell вместе с бинарником, поэтому jit <TAB> дополняет
подкоманды, флаги, пути к хранилищу и имена оборачиваемых инструментов из коробки.
При установке из архива или из исходников добавьте его самостоятельно:
echo 'source <(jit completion zsh)' >> ~/.zshrc && exec zsh
В любом случае jit doctor сообщит, если автодополнение не доходит до вашего shell.
jit scan # только чтение. не меняет ни один сканируемый файл, не выводит реальных значений.
jit vault init # создать хранилище (мастер-ключ в вашей связке ключей входа)
jit migrate --dry-run # предпросмотр всего плана исправлений для всей машины
jit migrate # применить: показывает план, спрашивает [y/N], одно касание Touch ID
jit migrate ~/code/myapp # или исправить только один проект
jit run -- npm run dev # запустить ваш инструмент; реальные значения внедряются только в этот процесс
jit scan без пути сканирует весь ваш домашний каталог, так что на большом
каталоге дайте ему время. Чтобы сразу перейти к одному месту, укажите путь: jit scan ~/.aws.
В повседневной работе это в основном jit run -- <cmd>. Для CLI, которые хранят собственный
токен входа (gh, glab, stripe и другие), вы один раз выполняете jit wrap gh, а затем
продолжаете вводить gh как обычно, навсегда.
Не уверены, нужно ли чему-то jit wrap, jit migrate или ничего? Вам
не нужно этого знать. jit scan разделяет всё найденное на то, что jit
защитит (одна команда — включая обёртки), и то, что можете исправить только вы, а
голый jit migrate выполняет весь этот план:
$ jit scan
ВАШИ СЕКРЕТЫ: 7 — 0 защищено jit (0%)
▱▱▱▱▱▱▱▱▱▱ до 100%: одна команда +71% · 2 секрета можете исправить только вы +29%
jit защитит это — 5 секретов в 4 файлах, 0% → 71%
→ jit migrate
~/.zshrc STRIPE_API_KEY, DB_PASSWORD
~/.config/gh/hosts.yml токен GitHub CLI · оборачивает gh
...
защитить можете только вы — 2 секрета, 71% → 100%
[ротация, затем удалите все копии]
! Пароль продакшен-базы данных в 2 файлах
→ сначала выполните ротацию, затем удалите все копии
(jit scan --full по-прежнему даёт классическую инвентаризацию по категориям с
уровнями серьёзности, включая раздел Оборачиваемые токены CLI.)
Мигрируйте учётные данные один раз, затем продолжайте использовать инструмент как обычно.
# AWS (а также Terraform и все AWS SDK)
jit migrate ~/.aws/credentials # ключи переезжают в хранилище; файла с открытым текстом не остаётся
aws s3 ls # разрешается из хранилища по требованию. без префикса, без флага.
terraform apply # те же учётные данные, та же команда
# Учётные данные приложения по умолчанию GCP (машинные учётные данные)
jit migrate ~/.config/gcloud/application_default_credentials.json
terraform apply # провайдер google читает ADC; работает после запроса Touch ID
# Docker / docker-compose
jit migrate ~/.docker/config.json # логины реестров переезжают в хранилище
jit run -- docker compose up # jit внедряет их для этого запуска
docker login ghcr.io # по-прежнему работает; хелпер сохраняет в хранилище
# Экспорты shell, которые раньше лежали в ~/.zshrc
jit migrate ~/.zshrc # оставляет однострочный хук; новые shell просто имеют переменные
./deploy.sh # скрипты, читающие эти переменные, работают без изменений
# Токены, которые вы когда-то вводили в приглашении, теперь лежат в истории shell
jit migrate ~/.zsh_history # каждый перемещается в хранилище; ваши команды остаются, секреты — нет
jit guard history # и предотвратить запись следующего (zsh)
# (голый `jit migrate` тоже предлагает это в плане, который просит подтвердить)
# CLI, хранящий собственный токен (gh, stripe, glab)
jit wrap gh # один раз
gh pr list # токен внедряется при каждом вызове, навсегда
При первом обращении каждого инструмента к реальным учётным данным jit спрашивает один раз и
запоминает ваш ответ, пока хранилище не заблокируется. См. Два момента Touch ID
о том, как это сочетается с разблокировкой хранилища, что делает --trust и как
отключить запросы для отдельных инструментов.
Почему одним инструментам не нужна настройка, а другим требуется jit run? Одно правило: может ли
инструмент сам спросить jit о секрете? AWS (через credential_process), ваш
shell при входе и логины реестров docker (через хелпер учётных данных) — все могут,
поэтому вам не нужно вводить ничего лишнего. Инструменты, которые только читают файл во время выполнения (docker
compose, обычные SDK), спрашивать не могут, поэтому jit run передаёт им значение.
Машинные глобальные файлы учётных данных (GCP ADC, sops, npm, netrc) работают
в повседневном режиме так же: запускайте инструмент и подтверждайте запрос для процесса. Добавляйте jit run --with <name>, только когда хотите явности: для скриптов и CI, где нет
запроса, на который можно ответить, или когда нужен жёсткий шлюз, до которого конфиг проекта
никогда не дотянется. Поддерживаемые инструменты перечисляют, что именно вводить
для каждого инструмента и как каждый из них доставляется.
jit запрашивает ваш отпечаток пальца в два разных момента, выполняя две разные задачи:
jit после блокировки одно
касание Touch ID открывает хранилище на всю сессию (5 минут активности, затем оно снова
блокируется; и никогда дольше 8 часов, как бы вы ни были заняты). Вы разблокируетесь
один раз, а не при каждой команде.jit спрашивает перед выдачей и
называет, кто спрашивает. Именно это не даёт программе, которую вы не запускали, тихо
использовать ваши ключи, пока хранилище открыто.$ aws s3 ls
Touch ID -> разблокировать хранилище # шлюз 1: открывает хранилище на 5 мин
Touch ID -> aws хочет ваши учётные данные aws # шлюз 2: этот инструмент, эти учётные данные
...ваши корзины...
$ aws s3 cp ./file s3://bucket/ # тот же инструмент, та же сессия: без запроса
$ terraform apply
Touch ID -> terraform хочет ваши учётные данные aws # другой инструмент: он спрашивает сам
Шлюз 2 не даёт открытому хранилищу превратиться в «всё можно»: даже после того,
как вы сами использовали aws, сомнительный npm install, тянущийся к тем же ключам,
по-прежнему вызывает запрос с его именем, и вы можете отказать.
Не нужен второй шлюз? Отключите его; блокировка хранилища остаётся (для отключения сам по себе требуется Touch ID, поскольку он заново открывает окно, которое закрывает):
jit service consent off # инструменты разрешаются молча, пока хранилище разблокировано
jit service consent on # снова спрашивать для каждого инструмента (по умолчанию)
Запускаете что-то, что требует сразу несколько учётных данных? jit run --trust -- terraform apply одобряет инструменты всего запуска одним жестом. Подробности:
согласие для процесса.
jit grantОба шлюза предполагают, что рядом есть человек, готовый ответить. ИИ-агент, работающий ночью, долгая сборка, запланированное задание: экран блокируется, сессия завершается, и запуск застревает на запросе, который никто не увидит. Грант процесса переносит ваше решение раньше, а не отменяет его — одно касание Touch ID, сделанное, пока вы ещё здесь, которое точно называет, что вы подписываете:
$ jit grant --process claude --profile jamf --for 8h
Touch ID -> разрешить claude под iTerm2 использовать 2 секрета (jamf) без присмотра в течение 8ч
✓ выдано g-7f3a2c81 claude -> jamf до 17:42
└ покрывает claude под iTerm2: 1 запущен сейчас, любые запущенные до 17:42
В течение следующих 8 часов каждый claude под тем терминалом, в котором вы это ввели
(и всё, что он запускает), получает эти секреты без запросов — даже при заблокированном
экране, включая сессии, которые вы начнёте позже: новая вкладка, следующий claude,
скрипт, срабатывающий в 3 часа ночи. Называется ваш терминал, а не доверяется имя:
программа, называющая себя claude где-то ещё на машине,
не происходит из этого дерева и ничего не наследует. Грант заканчивается по истечении срока,
когда вы закрываете этот терминал или в момент ввода jit grant revoke (для этого не нужен отпечаток — отобрать доступ всегда бесплатно). Нужен один
точный процесс, исчезающий при выходе? --pid. Каждая выдача попадает в
журнал аудита отдельным событием, так что утром вы можете прочитать, что именно
ваш агент трогал, пока вы спали. Подробности:
гранты процессов.
Агент в вашем редакторе работает от вашего имени, с вашими правами и весь день читает
файлы за вас. В этом весь его смысл, и именно поэтому открытый текстовый
.env в вашем репозитории теперь представляет собой совсем иной риск, чем два года назад.
jit относится к агентам как к полноправным участникам по четырём направлениям:
jit migrate ~/.claude.json # конфиги MCP-серверов: ключи переезжают в хранилище,
# каждый сервер теперь запускается через `jit run`
jit wrap claude # сами ИИ-CLI: claude, codex, gemini,
# cursor-agent, copilot, cline, opencode, kiro-cli
jit grant --process claude --profile myapp --for 8h
# позволить работать ночью без запроса, на который никто не ответит
jit audit --parent claude # прочитать, что именно он трогал, пока вы спали
claude, каждый
назван. Агент, тихо читающий ~/.aws/credentials, — это запрос, а не
молчаливый успех.jit run. Мигрированный конфиг MCP хранит пути
к хранилищу, а не ключи, поэтому сам файл конфига безопасно держать на диске и безопасно
отдавать агенту, который его читает..env и читает его «на холодную», получает значения-заглушки, а само чтение
логируется.jit audit --parent claude показывает каждый секрет, который использовал агент, каждый
запрос, который он вызвал, и каждый, который вы отклонили.Подробнее в MCP / ИИ-инструменты и согласие для процесса.
Каждая команда jit и каждая разблокировка попадает в долговечный журнал, который вы читаете через
jit audit, от новых к старым, по одной строке key=value на событие, так что он грепается как
настоящий сервисный журнал. Аргументы команд маскируются, поэтому журнал доказывает, что команда выполнялась,
не сохраняя секрет, который она несла.
$ 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
Средняя строка — это история, ради которой существует jit: aws/default был прочитан командой aws s3 ls, запущенной claude. Последняя — это отклонённый вами запрос:
node postinstall.js под npm, тянущийся к тем же ключам, получил отказ. jit также логирует
то, что сервис отверг на своём сокете (процесс, который, по словам ядра, не ваш, прощупывающий
агента), как kind=error.
Сузьте выборку флагами вместо grep: --kind, --status ok|failed|denied,
--since/--until (возраст вроде 2h/3d или дата), --parent claude,
--secret aws, --user, --grep <regexp>. Добавьте --follow (-f) для потокового
просмотра новых событий в реальном времени, как tail -f, или --format json для машиночитаемого
дампа. Обе половины — это долговечные файлы рядом с хранилищем, поэтому журнал отвечает за прошлую
неделю так же легко, как за последний час.
Файлы .env, экспорты shell, AWS и Terraform, kubeconfig, логины реестров Docker,
GCP ADC, токены .npmrc / .netrc, конфиги MCP-серверов, отдельные файлы
токенов, учётные данные, записанные в истории вашего shell, оборачиваемые CLI (gh,
stripe, vercel, …) и SSO-CLI, выпускающие учётные данные при входе
(clisso). В каждом случае файл продолжает работать, а реальное значение
поступает из хранилища по требованию.
Полный каталог, сгруппированный по тому, что именно вводить для каждого инструмента, —
Поддерживаемые инструменты: он отслеживает код по мере добавления или удаления
инструментов. Всё, что не перечислено, всё равно можно обернуть с помощью
jit wrap add.
Уже храните секреты в 1Password? При установленном его CLI
jit migrate связывает, а не копирует:
значение, которое уже живёт в 1Password, помещается в хранилище как его ссылка op://,
так что 1Password остаётся системой записи, а jit доставляет значение
точно в срок через все механизмы выше (jit vault link делает то же самое
для одного секрета вручную).
jit никогда не уничтожает учётные данные. Миграция перемещает значение в хранилище и
оставляет рабочий хук на его месте (приманку .env, строку eval "$(jit export)"
в конфиге вашего shell, credential_process = jit … в ~/.aws/config или
шим PATH), так что ваши инструменты продолжают получать его по требованию. Учётные данные
по-прежнему существуют, просто зашифрованы вместо открытого текста.
И каждое изменение обратимо. Перед тем как тронуть файл, jit сохраняет его резервную копию в зашифрованном виде
в хранилище, так что jit migrate undo возвращает его байт в байт:
jit migrate ~/code/myapp # применил исправление, одно касание Touch ID
# передумали или что-то сломалось?
jit migrate undo ~/code/myapp # каждый затронутый файл восстановлен, байт в байт
Документация живёт в docs/, организована по задачам:
git commit -s), без CLAPolyForm Perimeter License 1.0.0 — бесплатно только для личного и внутреннего корпоративного использования.