Skip to content

Commit dc48018

Browse files
authored
docs: warn about refresh token rotation in oauth_token (#60)
1 parent 80d1b30 commit dc48018

1 file changed

Lines changed: 15 additions & 0 deletions

File tree

docs/pages/credential-proxying/oauth-token.mdx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ Each entry under `tokens` declares one OAuth2 flow:
4646

4747
The proxy holds a long-lived refresh token and trades it for a short-lived access token on each call or on expiry.
4848

49+
:::warning
50+
iron-proxy never writes rotated refresh tokens back to the secret store. With providers that rotate (Google, Okta, Auth0), run a single instance per refresh token. See [Refresh token rotation](#refresh-token-rotation) below.
51+
:::
52+
4953
```yaml
5054
- grant: refresh_token
5155
refresh_token:
@@ -69,6 +73,17 @@ The proxy holds a long-lived refresh token and trades it for a short-lived acces
6973

7074
Omit `client_secret` for public PKCE clients. `json_key` pulls each field out of one JSON secret in Secrets Manager.
7175

76+
#### Refresh Token Rotation
77+
78+
Some providers issue a new refresh token on every exchange and invalidate the old one. Google with rotation enabled, Auth0, and Okta with one-time-use refresh tokens all behave this way. iron-proxy keeps the rotated token in memory for the lifetime of the process and does not write it back to the secret source.
79+
80+
In practice, the flow works until the secret source is re-read with the original token. The next exchange after that fails with `invalid_grant`, which iron-proxy classifies as unrecoverable, and a human has to seed a fresh refresh token in the secret store.
81+
82+
Two implications:
83+
84+
- Run a single iron-proxy instance per refresh token. A second instance reading the same secret holds the original value and will fail on its next exchange. For high availability, prefer `client_credentials` or `jwt_bearer`, which carry no per-call rotation state.
85+
- Avoid short `ttl` values on the refresh-token secret source. A re-read overwrites the in-memory rotated token with the stale store value.
86+
7287
### `client_credentials`
7388

7489
Machine-to-machine flow. Use it when the API issues a client ID and secret for service auth and the workload doesn't have a user identity of its own.

0 commit comments

Comments
 (0)