The OAuth dance, handled here once.
Connect any OAuth-capable provider — GitHub, Linear, Stripe, Slack, Notion, your own OIDC — once from the admin UI. PromptGate stores the encrypted tokens, refreshes them before they expire, and injects the right Authorization header on every proxied request.
Tokens belong in one place — not in every app that talks to the API.
The default pattern is brutal: every service that talks to GitHub needs the GitHub PAT, every service that talks to Stripe gets the secret key. Tokens spread, rotation becomes a coordination problem, leaks have a wide blast radius.
OAuth Connections invert the pattern. The token lives on the gateway. Apps authenticate to PromptGate with their own short-lived token; the gateway adds the upstream credential as it forwards the request. Apps never see, log, or accidentally leak the upstream secret.
- One credential, one location, one rotation
- App-side leak ≠ provider-side leak
- Audit log records which app called which upstream when
— Before — service-a/.env: GITHUB_PAT=ghp_xxx... service-b/.env: GITHUB_PAT=ghp_xxx... # same token everywhere service-c/.env: GITHUB_PAT=ghp_xxx... # rotate? touch all three — After — service-a/.env: PROMPTGATE_TOKEN=pg_live_a... service-b/.env: PROMPTGATE_TOKEN=pg_live_b... service-c/.env: PROMPTGATE_TOKEN=pg_live_c... # GitHub PAT lives only inside PromptGate. # Apps call /api/<uuid>/proxy/<endpoint>/... # PromptGate injects Authorization: Bearer ghp_... server-side.
# Define the connection once in the admin UI name: GitHub Issues authorize_url: https://github.com/login/oauth/authorize token_url: https://github.com/login/oauth/access_token client_id: Iv1.abc123… client_secret: "********" # encrypted at rest with APP_KEY scopes: [repo, read:user] # Admin clicks "Connect" → consents on GitHub → PromptGate # stores access_token + refresh_token + expires_at, all encrypted. # Bind any API Gateway endpoint to this connection: endpoint: upstream_url: https://api.github.com oauth_connection_id: 7 expose_as: gh-issues # Apps now just call: # curl https://promptgate.your.co/api/<uuid>/proxy/gh-issues/... # -H "Authorization: Bearer pg_live_..." # PromptGate refreshes the GitHub token before it expires.
Three moving parts.
- Connection — the credential pair (client_id + client_secret) plus authorize / token URLs and scopes. Defined once.
- Authorisation — admin clicks "Connect", PromptGate runs the OAuth flow with the upstream, stores the resulting access + refresh tokens encrypted.
- Injection — at request time, PromptGate fetches the (auto-refreshed) access token and adds
Authorization: Bearer …to the upstream call.
Refreshes happen pre-emptively before expires_at. If the upstream rotates the refresh token along the way, PromptGate stores the new one and continues without operator intervention.
Built-in presets + any OIDC provider.
Hand-tuned configurations for the most common providers, plus a fully generic OIDC form for anything else.
- GitHub — repo, issue, gist scopes
- Linear — read/write workspace
- Stripe — connected accounts
- Slack — bot-token + user-token flows
- Notion — workspace integration
- Google Workspace — Gmail, Drive, Calendar
- Microsoft Graph — Office 365
- Custom OIDC — anything spec-compliant
Stop scattering API tokens.
Self-hosted, source-available, one container. Apps call the gateway with their own token; the upstream credential never leaves your perimeter.