Credential issuance for AI agents
Connect GitHub once. After that, your agent mints its own scoped tokens that expire in one hour — bound to your account, down-scoped per request, attributed to a bot identity in every audit log. Expiry replaces rotation.
https://gitauth.klappy.dev/mcp
Live demonstration at 60× speed — a real token lives one hour.
The problem, on the record
How it works
Add the MCP server to your client and log in with GitHub. The connection binds to your installation of the app — you choose which repos it covers. Then your agent calls github_token at need.
Your Cloudflare Worker signs a 10-minute JWT with your App's private key — which lives in worker secrets and never transits chat, disk, or transcript.
GitHub exchanges the JWT for a one-hour installation token, scoped exactly as requested. The agent uses it, and the clock does the rest.
Read this before you trust it
Most credential tools bury their threat model. This one leads with it — because the people who should deploy this are exactly the people who will ask.
The MCP endpoint's bearer token is the entire security boundary. Anyone holding it can mint write tokens for every installed repo. The worker fails closed — no bearer configured, nothing served. Guard MCP_AUTH_TOKEN like the private key itself.
The recommended grant excludes Administration — but Workflows write means a token holder can modify CI, and CI runs with the repo's own credentials. That path is accepted, not eliminated: every CI change lands in PRs and audit logs under the bot identity. Don't want the trade? Drop the Workflows permission.
You never hand over a key — connecting means installing a GitHub App on repos you choose. If this bridge were compromised, exposure is minting over installed scopes, within the app's ceiling — never your account or credentials. Your kill switch is unilateral: uninstall the app and minting ends instantly. Want zero shared trust? Self-host the same code.
$ Reversal is two clicks. The riskiest credential in this system is the one it replaces.
Setup
Use it: add https://gitauth.klappy.dev/mcp to your MCP client and follow the GitHub login. Operate it: the script here is the self-host runbook — same code, your app, your worker. Details in the README.
Keep your existing PAT until github_token mints its first real token. Retiring the fallback before validating the replacement is how lockouts happen — the README sequences this for you.
# 1 — Create the GitHub App (Contents RW, PRs RW, Metadata R. # Workflows RW optional — see security model. No Administration.) # 2 — GitHub ships PKCS#1; Workers WebCrypto wants PKCS#8: openssl pkcs8 -topk8 -inform PEM \ -in your-app.private-key.pem -nocrypt -out app-pkcs8.pem # 3 — Enable user OAuth on the app: callback = # https://<worker>/callback, generate a client secret. # 4 — Secrets (never committed, never pasted in chat): wrangler secret put GH_APP_ID wrangler secret put GH_APP_PRIVATE_KEY wrangler secret put GITHUB_CLIENT_ID wrangler secret put GITHUB_CLIENT_SECRET # 5 — Ship it: npm install && npm run deploy # 6 — Point any MCP client at https://<worker>/mcp — # OAuth + GitHub login happen in the browser.