Wiring Claude Code to GitHub, Linear, and Stripe with one local broker

Authenticate once per service, then let Claude Code reach all three without holding raw tokens. A literal walk-through with the real authsome commands.

April 28, 20269 min read

Wiring Claude Code to GitHub, Linear, and Stripe with one local broker.

Most Claude Code setups end up the same way: a GitHub PAT pasted into ~/.zshrc, a Linear API key in a .env, a Stripe restricted key somewhere in a config file you forget about. Six months later half of them are stale, none of them refresh, and you're not sure which token belongs to which account.

This post replaces that pile with authsome. The pitch is that you log into each provider once, the broker keeps the tokens fresh, and Claude Code makes its normal API calls without ever holding the raw secret.

I'm not going to pretend the setup is one command. The first time you go through it, the GitHub OAuth-app bit takes a few minutes and the mitmproxy CA cert needs to be trusted. After that, day two is a single authsome login per service and Claude Code just works.

What we're building

Loading diagram…

Claude Code makes a request to api.github.com. The local proxy intercepts it, looks up the right token, slots it into the Authorization header, and forwards. Claude Code's process never sees the real token. Your shell never sees it either.

Install authsome

Python 3.13+ required. Pick whichever fits how you manage Python tools:

bash
pip install authsome

Or run without installing:

bash
uvx authsome --version

Then sanity-check:

bash
authsome init
authsome doctor

init creates ~/.authsome/, generates a master key, and registers your local profile. doctor runs health checks on the directory layout, encryption availability, and bundled provider parsing. All checks should pass before you do anything else.

Connect GitHub

GitHub doesn't support Dynamic Client Registration, so the first time around you have to register your own OAuth app. It's a four-minute one-time thing:

  1. Open github.com/settings/developersNew OAuth App.
  2. Name: anything. authsome (local) is what I use.
  3. Homepage URL: any URL. http://localhost:3000 works.
  4. Authorization callback URL: http://127.0.0.1:7998/auth/callback/oauth · this one matters. Any other value fails with redirect_uri_mismatch at login time.
  5. Check Enable Device Flow if you'll ever log in from an SSH session.
  6. Register the app. Copy the Client ID. Click Generate a new client secret and copy that too.

Now from the terminal:

bash
authsome login github

Authsome opens a local form at http://127.0.0.1:7998 asking for the Client ID and Client Secret. Paste them. They're stored encrypted under your profile. A second tab opens to GitHub's authorization page. Approve. The terminal prints Successfully logged in to github (default).

Verify:

bash
authsome list

GitHub should show as connected. From now on, every subsequent login or refresh reuses the stored client credentials. You won't see the form again unless you authsome revoke github.

Connect Linear

Linear's MCP endpoint supports DCR, but the API-key path is the one most people start with. Same login command:

bash
authsome login linear

A local form opens asking for the API key. Get one from linear.app/settings/api and paste. The key is stored encrypted.

The reason the prompt is in the browser and not the terminal: a terminal-pasted key ends up in ~/.zsh_history and shows up in any process listing while you're typing. The local form posts straight to the daemon over loopback and the value never touches your shell.

Connect Stripe

Same pattern:

bash
authsome login stripe

For Claude Code workloads I strongly recommend a restricted key (rk_test_... or rk_live_...) scoped to the minimum the agent needs. Read access to customers and payments is enough for most read-only flows. Avoid the unrestricted sk_live_* unless the agent actually needs to charge cards.

Sanity check all three

bash
authsome list

You should see three rows, each connected. For more detail (per-provider config, scopes, expiry, default connection name):

bash
authsome inspect github
authsome inspect linear
authsome inspect stripe

Point Claude Code at the broker

Two viable patterns. Proxy is the secure default. Export is the fallback for environments where the proxy doesn't work cleanly.

Launch Claude Code under authsome run:

bash
authsome run -- claude

This sets HTTP_PROXY / HTTPS_PROXY to authsome's local proxy in Claude Code's environment. Claude Code's HTTP client (and any subprocess it spawns) honors the proxy variables. Outbound calls to api.github.com, api.linear.app, api.stripe.com get the right Authorization header injected at the proxy boundary.

In the child process, the placeholder env var is what's set:

bash
authsome run -- env | grep -E 'OPENAI|GITHUB|PROXY'
# HTTP_PROXY=http://127.0.0.1:<port>
# HTTPS_PROXY=http://127.0.0.1:<port>
# OPENAI_API_KEY=authsome-proxy-managed

The real key isn't anywhere in the process environment. Substitution happens at the proxy.

The CA cert thing (do this once)

authsome run uses mitmproxy under the hood to do HTTPS interception. mitmproxy needs its CA certificate trusted on your machine, otherwise every HTTPS call from Claude Code fails with CERTIFICATE_VERIFY_FAILED.

mitmproxy ships a built-in installer. While authsome run is alive, open a browser on the same machine and go to http://mitm.it. The page detects your OS and gives you a one-click installer for macOS, Windows, Linux, iOS, and Android. This is the path mitmproxy's own docs recommend.

If you can't use the browser installer (headless box, automated provisioning), install the CA manually:

bash
sudo security add-trusted-cert \
  -d -r trustRoot \
  -k /Library/Keychains/System.keychain \
  ~/.mitmproxy/mitmproxy-ca-cert.pem

System-wide trust. Confirm in Keychain Access → System → Certificates.

Warning

The mitmproxy CA can sign certs for any domain Claude Code talks to. Don't share ~/.mitmproxy/mitmproxy-ca-cert.pem or copy it onto someone else's machine. Anyone with the cert can MITM you the same way the proxy does.

If you're using Python tooling under authsome run and still seeing TLS errors after installing the CA, the request library is checking its own bundled CA store. The fix is to point it at the system store with REQUESTS_CA_BUNDLE or SSL_CERT_FILE. The Proxy networking troubleshooting page has the per-language snippets.

Multiple accounts on the same provider

Two GitHub accounts (personal and work) is the case that breaks the env-var model entirely. With authsome, each account is a named connection within the same provider:

bash
authsome login github --connection personal
authsome login github --connection work

Each login runs its own browser flow, against the right account, with its own access token. The OAuth client_id and client_secret are shared (it's the same OAuth app), but each connection has an independent token bound to its own scopes.

Read from a specific connection:

bash
authsome get github --connection work --field status
authsome export github --connection work --format env

The proxy uses the default connection for each provider on every request. Per-request connection selection inside authsome run is on the roadmap; today, if you need the agent to use a different connection, you change which one is default first:

bash
authsome set-default github work
authsome run -- claude

Or, the older form that the docs still document:

bash
authsome login github --connection work --force

--force overwrites the existing default. Both achieve the same result.

If you want total isolation between two credential sets (not just "two accounts on the same provider", but "personal Slack should never see work tooling"), look at profiles instead of connections. Profiles are a separate identity handle with its own KV store; switching the active profile switches the entire credential set. The Profiles vs connections page explains the rule of thumb in detail.

When it breaks

A small fix list for the things that bit me in week one:

TLS errors on every HTTPS call. You skipped the mitmproxy CA install. Open http://mitm.it and run the installer, or use the per-OS commands above.

"Authentication failed" from one provider. Token expired or got revoked. Re-run authsome login <provider>; the stored client credentials are reused so it's a single command.

Claude Code makes calls but the broker logs are empty. Claude Code didn't honor HTTP_PROXY. You probably launched it from outside the authsome run wrapper. Re-launch via authsome run -- claude, or fall back to the env-export pattern.

Claude Code is using the wrong GitHub account. The default connection isn't the one you want. Either authsome set-default github work to flip the default, or use authsome export github --connection work --format env + eval to inject the specific one into the env.

Want to see what the broker is doing. authsome log shows the structured audit entries (every login, every refresh, every credential read). authsome log --raw shows the raw client debug log. authsome ui opens the daemon dashboard in your browser if you'd rather click than grep.

What you've built

bash
$ authsome list
github       connected     oauth2
linear       connected     api_key
stripe       connected     api_key

$ authsome run -- claude
# Claude Code is now talking to all three services
# without holding a single real credential.

Zero tokens in ~/.zshrc. Refresh handled automatically by the daemon. Multi-account modeled explicitly via --connection. Visibility into every credential read via authsome log.

Same pattern works for the rest of authsome's bundled providers (44 at the time of writing, including OpenAI, Anthropic, Slack, Notion, Resend, Vercel, Cloudflare). The flow is always authsome login <name>, browser opens, approve, done. The full list is at authsome.ai/docs/reference/bundled-providers.

Priyansh Khodiyar

Priyansh Khodiyar

Maintainer

Works on authsome and the agentr.dev tooling.