Token-Mint Integrations
Some vendors don't take an API key on every request — they want an OAuth-style token dance: present a durable credential at a token endpoint, get back a short-lived access token, use that. The token-mint integrations run that dance for you: exe.dev vaults the durable credential (a client secret, a service account key, a refresh token) and your VM exchanges it for the short-lived token without ever seeing it.
The catalog services with this shape today: googlesa, keycloak, twitch,
and reddit-ads. (Container registries use a GET-based cousin of this flow —
see Container Registry Integrations.)
How it works
-
POSTto the vendor's documented token path on the integration hostname. Any body you send is ignored — the proxy discards it and synthesizes the real token request from the vaulted credential:curl -X POST http://<name>.int.exe.xyz/oauth2/token -
The vendor's response comes back to you verbatim: a short-lived
access_token(typically ~1 hour) withexpires_in. -
Use it as
Authorization: Bearer <token>— depending on the service, either through the integration or directly against the vendor (see each section below). -
When the token expires (the vendor answers 401), mint a fresh one. React to the 401 rather than tracking TTLs.
The durable credential never reaches the VM; only the scoped, expiring token does. If a vendor echoes a durable secret back in the token response (Reddit does), the proxy strips that field.
Google service account (googlesa)
- Credential: a service-account JSON key (create one).
- Mint:
POST /tokenwith an empty body. The proxy signs the JWT assertion with the private key server-side and exchanges it at Google's token endpoint. - Use the ~1h access token directly against the Google API (e.g.
Authorization: Bearer <token>tosheets.googleapis.com) — those calls do not go through the integration. - Consumer-style use: share the target resource (e.g. a Sheet) with the
service account's
client_email. - Domain-wide delegation: pass
--subjectwith the user to impersonate.
Keycloak (keycloak)
- Credential: a confidential client's id + secret.
- Self-hosted: point
--base-urlat your Keycloak install. - Mint:
POST /realms/<realm>/protocol/openid-connect/token— the client-credentials grant. The integration is path-gated to/realms/, so the secret can only ever be presented to a token endpoint. - Use the bearer token directly against your own API.
- Verify runs a client-credentials mint against
--realm(defaultmaster); the id/secret ride HTTP Basic, so the body carries onlygrant_type.
Twitch (twitch)
- Credential: an application's client_id + client_secret (register an app, then "New Secret" on its Manage page).
- Mint:
POST /oauth2/token— Twitch's client-credentials grant. Twitch only accepts the credentials as form-body fields (HTTP Basic is rejected withmissing client id), which is exactly why the body is synthesized server-side. - Use the app access token on
/helix/...requests through the integration — the proxy adds the requiredClient-Idheader for you. - App access tokens are server-to-server and carry no scopes. Endpoints that need a user context (e.g. a user's email) require a user access token, which this integration does not mint.
Reddit Ads (reddit-ads)
- Credential: your app's client credentials plus a refresh token.
- Getting the refresh token: authorize your app once at
https://www.reddit.com/api/v1/authorize?client_id=...&response_type=code&state=...&redirect_uri=...&duration=permanent&scope=adsread(addadsedit/adsconversionsas needed), then exchange the code at Reddit's token endpoint; the response'srefresh_tokenis what you paste into the integration. - Scopes:
adsreadcovers reporting and read endpoints; campaign writes needadsedit; conversion uploads needadsconversions. - Mint:
POST /api/v1/access_token(any body ignored). The proxy performs the refresh-token grant server-side and returns the ~1haccess_token. Reddit echoes the permanent refresh token back in refresh responses — the proxy strips that field. - Use the token on
/api/v3/...requests, through the integration or directly againstads-api.reddit.com. - Reddit requires a descriptive User-Agent; the proxy sets one on proxied requests.