Documentation Index
Fetch the complete documentation index at: https://jacobpevans-docs-automation-surface.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Two databases, three GitHub-token tiers. Unlock posture decides who can read what.
Two databases, one rule
The split is the entire access-control model: anything an AI can read non-interactively lives inautomation; anything that requires a human at the keyboard lives in elevate-access.
| Database | Unlock posture | Holds | AI can read? |
|---|---|---|---|
automation.keychain-db | Unlocked at login | GH_PAT_RESTRICTED, HF_TOKEN, BWS_ACCESS_TOKEN, Claude Code credentials | Yes — via the launcher subshell |
elevate-access.keychain-db | Locked, GUI unlock prompt | GH_PAT_PRIVATE, GH_PAT_ADMIN, GH_PAT_ORG_ADMIN | No — the prompt blocks any non-interactive read |
GitHub PAT tiers
| Tier | Service name | Database | Scope | Who uses it |
|---|---|---|---|---|
RESTRICTED | GH_PAT_RESTRICTED | automation | Public repos | gh-restricted, gh-claude-restricted, CI smoke jobs |
PRIVATE | GH_PAT_PRIVATE | elevate-access | + private repos | gh-private, gh-claude-private (human only) |
ADMIN | GH_PAT_ADMIN | elevate-access | JPE repo admin | gh-admin, gh-claude-admin (human only) |
ORG_ADMIN | GH_PAT_ORG_ADMIN | elevate-access | dryvist org admin | .github-tofu apply (human only) |
gh-restricted / gh-private / gh-admin) export GITHUB_TOKEN into the current shell. The AI-launcher variants (gh-claude-*) wrap the export in a subshell so the token never leaks to the parent — see Local AI isolation.
Reading a keychain entry the right way
The last positional argument is the keychain path. Omit it andsecurity searches the login keychain only — which does not contain these entries. Always pass the path explicitly so the lookup hits the right database:
automation keychain entries, swap the path to ~/Library/Keychains/automation.keychain-db. Each security find-generic-password call against elevate-access triggers an unlock prompt; inlining the read on every command would prompt every time. Fetch once, inject the variable across the session — and unset it when done.
Adding a new keychain entry
automation.keychain-db with elevate-access.keychain-db for human-only entries. The -U flag updates if the entry already exists.
Best practices
- One account name for AI-readable entries:
ai-cli-coder. The-aflag is the discriminator the launchers use. - Never put a value in
automationthat should require human approval. The unlock posture is the whole point. - Cap the auto-lock timeout on
elevate-access(~5 minutes idle) so an abandoned session re-locks. - Touch ID for sudo (
security.pam.enableSudoTouchIdAuth = truein nix-darwin) ensures even the human path requires biometric confirmation.
See also
- Local AI isolation — the subshell scoping that pairs with the keychain split.
- BWS — uses
automationfor its access token to remain AI-reachable. nix-darwin/hosts/macbook-m4/gh-token-switching.zsh— the literal switching helpers.