Skip to content
HN On Hacker News ↗

GitHub - jitpass/jit: Find the plaintext secrets on your Mac and move them behind Touch ID, injected just in time without breaking the tools that read them. Free and local-first.

▲ 55 points 79 comments by bukershok 1w ago HN discussion ↗

Pangram verdict · v3.3

We believe this text is mainly AI, with some human-written content.

91 %

AI likelihood · overall

AI
3% human-written 97% AI-generated
SEGMENTS · HUMAN 1 of 3
SEGMENTS · AI 1 of 3
WORD COUNT 1,268
PEAK AI % 96% · §2
Analyzed
Aug 16
backend: pangram/v3.3
Segments scanned
3 windows
avg 423 words each
Distribution
3 / 97%
human / AI fraction
Verdict
AI
Pangram v3.3

Article text · 1,268 words · 3 segments analyzed

Human AI-generated
§1 Human · 17%

jitpass - just-in-time passwords Just-in-time credentials for your dev machine. Documentation · Quickstart · Supported tools · Command reference · Security Status: macOS-only (Apple Silicon), and still in development.

§2 AI · 96%

What jit is (30 seconds) Your secrets live in plaintext all over your machine: .env files, ~/.aws/credentials, ~/.zshrc exports, .npmrc tokens, MCP configs. Anything running as you can read them. A bad curl | sh, a sketchy npm install, or one of the AI agents now running in your editor with your full permissions. jit moves each secret into a local encrypted vault gated by Touch ID, and rewrites the files so your tools keep working. On disk there's now a decoy. The real value only appears, in memory, for the specific process that asked for it, after a biometric prompt. The result: you unlock once, jit asks before handing a credential to a tool (or an agent), and there's a decoy on disk the rest of the time. launched by Code launched by claude Install brew install jitpass/tap/jitpass Or without Homebrew: curl -sL https://dl.jitpass.com/jitpass/jit/releases/latest/download/jitpass_darwin_arm64.tar.gz | tar -xz jit sudo mv jit /usr/local/bin/ Apple Silicon only — on an Intel Mac, build from source with go install github.com/jitpass/jit/cmd/jit@latest. Pick one route. If you installed from the tarball before and are switching to Homebrew, remove the old copy after the brew install (sudo rm /usr/local/bin/jit); otherwise two jits sit on PATH upgrading separately, and jit doctor will flag it. Releases are signed with a Developer ID and notarized by Apple, so both paths run without a Gatekeeper prompt: Homebrew quarantines its downloads and Gatekeeper clears them against the notarization ticket, while curl (and go install) set no quarantine flag at all. To check what you got rather than take our word for it, run jit doctor — its jit line reports signed CZC6BH93GJ, using the same check jit upgrade runs before it will install anything. Upgrading: brew upgrade jitpass, or jit upgrade — a verified self-update (Developer-ID signature and checksum both checked before the swap, restarts the service). Either way your vault is untouched. Homebrew installs shell completion with the binary, so jit <TAB> completes subcommands, flags, vault paths, and wrappable tool names out of the box. Installed from the tarball or from source, add it yourself: echo 'source <(jit completion zsh)' >> ~/.zshrc && exec zsh Either way, jit doctor tells you if completion isn't reaching your shell. How you actually use it jit scan # read-only. changes no file it scans, prints no real value. jit vault init # make the vault (master key in your login keychain) jit migrate --dry-run # preview the whole machine-wide fix plan jit migrate # apply it: shows plan, asks [y/N], one Touch ID jit migrate ~/code/myapp # or fix just one project jit run -- npm run dev # run your tool; real values injected into that process only jit scan with no path sweeps your whole home directory, so give it a moment on a large one. To go straight at one place, point it at a path: jit scan ~/.aws. Day to day it's mostly jit run -- <cmd>. For CLIs that carry their own login token (gh, glab, stripe, and more) you jit wrap gh once and then keep typing gh as normal forever. Not sure whether something needs jit wrap, jit migrate, or nothing? You don't have to know. jit scan splits everything it finds into what jit will protect (one command - the wraps included) and what only you can fix, and bare jit migrate runs that whole plan: $ jit scan YOUR SECRETS: 7 — 0 protected by jit (0%) ▱▱▱▱▱▱▱▱▱▱ to 100%: one command +71% · 2 secrets only you can fix +29% jit will protect these — 5 secrets in 4 files, 0% → 71% → jit migrate ~/.zshrc STRIPE_API_KEY, DB_PASSWORD ~/.config/gh/hosts.yml GitHub CLI token · wraps gh ... only you can protect these — 2 secrets, 71% → 100% [rotate, then delete every copy] ! A production database password in 2 files → rotate it now, then delete every copy (jit scan --full still gives the classic per-category inventory with severities, including the Wrappable CLI Tokens section.) Your everyday tools Migrate the credential once, then keep using the tool the way you always have. # AWS (and Terraform, and every AWS SDK) jit migrate ~/.aws/credentials # keys move to the vault; no plaintext file left aws s3 ls # resolves from the vault on demand. no prefix, no flag. terraform apply # same creds, same command # GCP application-default credentials (a machine-wide credential) jit migrate ~/.config/gcloud/application_default_credentials.json terraform apply # google provider reads ADC; works after a Touch ID prompt # Docker / docker-compose jit migrate ~/.docker/config.json # registry logins move to the vault jit run -- docker compose up # jit injects them for this run docker login ghcr.io # still works; the helper stores to the vault # Shell exports that used to sit in ~/.zshrc jit migrate ~/.zshrc # leaves a one-line hook; new shells just have the vars ./deploy.sh # scripts that read those vars work unchanged # Tokens you once typed at the prompt, now sitting in your shell history jit migrate ~/.zsh_history # each one moves to the vault; your commands stay, the secrets don't jit guard history # and stop the next one being recorded at all (zsh) # (bare `jit migrate` offers this too, in the plan it asks you to confirm) # A CLI that carries its own token (gh, stripe, glab) jit wrap gh # one time gh pr list # token injected per call, forever The first time each tool reaches for a real credential, jit asks once and remembers your answer until the vault locks. See Two Touch ID moments for how that sits on top of the vault unlock, what --trust does, and how to turn the per-tool prompts off. Why do some tools need no setup while others take a jit run? One rule: can the tool ask jit for the secret itself? AWS (via credential_process), your shell at login, and docker's registry logins (via a credential helper) all can, so you type nothing extra. Tools that only read a file at runtime (docker compose, plain SDKs) can't ask, so jit run hands them the value. The machine-global credential files (GCP ADC, sops, npm, netrc) work the same everyday way: run your tool and approve the per-process prompt. Add jit run --with <name> only when you want it explicit: for scripts and CI where there's no prompt to answer, or when you want a hard gate a project's own config can never reach. Supported tools lists exactly what to type for every tool, and how each is delivered. Two Touch ID moments, not one jit asks for your fingerprint at two different moments, doing two different jobs: Unlocking your vault. The first time you use jit after it locks, one Touch ID opens the vault for the whole session (5 minutes of activity, then it re-locks; and never longer than 8 hours, however busy you are). You unlock once, not once per command. Handing a credential to a tool. On top of that, the first time a given tool reaches for a real credential, jit asks before handing it over and names what's asking. This is what stops a program you didn't run from quietly using your keys while the vault is open.

§3 Mixed · 48%

$ aws s3 ls Touch ID -> unlock your vault # gate 1: opens the vault for 5 min Touch ID -> aws wants your aws credential # gate 2: this tool, this credential ...your buckets...