OAuth Bridge
OAuth Bridge lets your apps call the Plane API with access tokens issued by your own identity provider (IdP), such as Microsoft Entra ID, ADFS, or Okta. Plane checks each token against your IdP's public keys, matches it to a Plane user by email, and runs the request as that user.
Use it when your internal tools already sign users in through your IdP, and you don't want to hand out Plane API keys or build a Plane OAuth app for each of them.
How it works
- Your app gets an access token (a signed JWT) from your IdP, the same way it does for your other internal APIs.
- Your app calls the Plane API with
Authorization: Bearer <token>. - Plane finds the token provider you configured for the token's issuer (
issclaim) and checks the token's signature against your IdP's public keys (JWKS), its expiry, its issuer, and its audience. - Plane reads the user claims you chose, such as
email, and finds the Plane user with that email. - If that user is an active member of the workspace, the request runs as them.
Plane fetches your IdP's public keys and caches them. Your app talks to Plane directly; there's no proxy in between.
Before you start
- Role: You need to be a workspace admin to install OAuth Bridge and manage token providers.
- Your IdP's tokens must be JWTs signed with an asymmetric algorithm: RS256, RS384, RS512, ES256, ES384, or ES512. Tokens signed with a shared secret, such as HS256, aren't accepted.
- Your IdP's JWKS endpoint must be reachable from your Plane instance over HTTPS.
- Every user who calls the API must already have a Plane account with the same email as in their token, and be an active member of the workspace. OAuth Bridge doesn't create users.
Install OAuth Bridge
- In Plane, go to Workspace settings → Integrations and open OAuth Bridge.
- Select Connect.
When OAuth Bridge shows Connected, you can add token providers.
Add a token provider
A token provider tells Plane which IdP to trust and how to read its tokens. You can add more than one, for example one for production and one for staging. Each issuer can be added once per workspace.
- Under Token Providers, select Add provider.
- Fill in the fields below.
- Leave Enable this provider on and select Add provider.
| Field | What to enter | Example |
|---|---|---|
| Name | A label for this IdP | Entra ID Production |
| Issuer | The exact value of the iss claim in your tokens | https://login.microsoftonline.com/<tenant-id>/v2.0 |
| JWKS URL | Your IdP's JSON Web Key Set endpoint. Must start with https://. | https://login.microsoftonline.com/<tenant-id>/discovery/v2.0/keys |
| Audience | The aud value in your tokens. Separate several with commas. See the note below. | api://plane-api |
| User claims | The claims that hold the user's email, in the order to try them. Separate with commas. The first claim that matches a Plane user wins. | email, preferred_username, upn |
| Allowed signing algorithms | The algorithms your IdP signs tokens with. Only asymmetric algorithms are offered. | RS256 |
| JWKS cache TTL (seconds) | How long Plane caches your IdP's public keys. At least 60. Defaults to 86400 (24 hours). | 86400 |
| Rate limit | Optional. Requests allowed per user, as count/period. Leave it blank to use the instance's default API rate limit. | 120/minute |
Set the Audience
Most IdPs put an aud claim in their access tokens. If your tokens have one, set Audience to the same value. If Audience is empty, Plane rejects any token that carries an aud claim.
Finding your issuer and JWKS URL
Your IdP publishes both in its OpenID configuration document, usually at <issuer>/.well-known/openid-configuration. Copy issuer and jwks_uri from there.
Test the provider
Select Test on the provider. Plane fetches the JWKS URL and shows JWKS Reachable with the number of keys it found, or JWKS Unreachable if it couldn't fetch them.
The test checks that Plane can reach your keys. It doesn't check a token. To check the whole setup, call the API with a real token as shown below.
Call the Plane API
Send the token from your IdP as a bearer token. It works with both versions of the Plane API.
curl https://<your-plane-host>/api/v1/workspaces/<workspace-slug>/projects/ \
-H "Authorization: Bearer $IDP_ACCESS_TOKEN"curl https://<your-plane-host>/api/v2/workspaces/<workspace-slug>/projects/ \
-H "Authorization: Bearer $IDP_ACCESS_TOKEN"OAuth Bridge tokens work only on endpoints whose path includes the workspace slug. Endpoints outside a workspace, such as /users/me/, aren't supported.
What the request can do
A request made with an OAuth Bridge token runs with the matched user's full Plane permissions, the same as their own API key. It isn't limited by OAuth scopes. Control what your apps can do through the user's workspace and project roles, and by issuing tokens only to apps you trust.
Rate limits
Each user gets one rate-limit bucket for OAuth Bridge requests. Plane uses the provider's Rate limit if you set one, or the instance's default API rate limit if you didn't. On self-hosted Plane, the default is set by DEFAULT_API_RATE_LIMIT, or API_KEY_RATE_LIMIT if that isn't set, and is 60/min unless changed.
Errors
| Status | code | Meaning |
|---|---|---|
401 | token_expired | The token has expired. Get a new one from your IdP. |
401 | token_invalid | The signature, issuer, or audience didn't match the provider. Check the Issuer, Audience, and Allowed signing algorithms. |
401 | token_validation_failed | Plane couldn't validate the token, for example because it couldn't fetch the keys. Test the provider. |
401 | missing_claim | None of the user claims held the email of an active Plane user. Check the User claims and the user's Plane email. |
403 | user_not_active | The user exists but isn't an active member of the workspace. Add them to the workspace. |
If OAuth Bridge isn't installed in the workspace, or no enabled provider matches the token's issuer, Plane doesn't treat the token as an OAuth Bridge token at all, and the request fails as unauthenticated.
Manage providers
- Turn a provider off with its toggle. Tokens from that issuer stop working until you turn it back on.
- Edit a provider to change its fields.
- Delete a provider to stop trusting that IdP for good.
- Uninstall OAuth Bridge from the same page to stop accepting IdP tokens in the workspace.
Troubleshooting
Every request returns 401
- Check that OAuth Bridge shows Connected and the provider is enabled.
- Decode your token, for example with a JWT debugger, and compare its
isswith the provider's Issuer character for character, including any trailing slash. - Check that the token's
audmatches Audience, and that itsalgheader is one of the Allowed signing algorithms.
"No Plane user found for JWT claims"
The claims you listed don't hold an email that belongs to an active Plane user. Check which claim your IdP puts the email in. Entra ID, for example, often uses preferred_username or upn rather than email. Add that claim to User claims.
JWKS Unreachable
Your Plane instance can't reach the JWKS URL. Check that the URL is correct, uses HTTPS, and is reachable from the Plane server through any firewall or proxy.
The JWKS URL must return the keys directly. Plane doesn't follow redirects, so if the URL redirects, use the final URL.

