Integrations · OIDC
Portainer SSO
Configure Portainer Business Edition (BE) or Community Edition (CE) with the OAuth plugin to authenticate via Clavex using OpenID Connect. Automatic team assignment from Clavex group claims is supported in Portainer BE.
Edition differences: OAuth SSO is built-in in Portainer BE (≥ 2.0).
Community Edition requires the third-party OAuth proxy or a reverse proxy with authentication.
This guide covers Portainer BE. For CE, use oauth2-proxy in front of Portainer.
Prerequisites
- Portainer Business Edition ≥ 2.0 or CE with OAuth proxy
- Portainer admin access
- Clavex at
https://id.acme.eu, org slugacme
Step 1 — Register OIDC Client in Clavex
$ curl -X POST https://id.acme.eu/api/v1/organizations/acme/clients \
-H 'Authorization: Bearer $ADMIN_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"client_id": "portainer",
"client_name": "Portainer",
"grant_types": ["authorization_code"],
"redirect_uris": ["https://portainer.acme.eu"],
"scopes": ["openid", "profile", "email"],
"token_endpoint_auth_method": "client_secret_post"
}'
Step 2 — Configure Portainer OAuth
- Settings → Authentication → select OAuth
- Select Custom as the OAuth provider
- Fill in:
Field Value Client ID portainerClient secret cs_xxxxxxxxxxxxxxxxAuthorization URL https://id.acme.eu/acme/authorizeAccess token URL https://id.acme.eu/acme/tokenResource URL https://id.acme.eu/acme/userinfoRedirect URL https://portainer.acme.euUser identifier emailScopes openid profile email - Optionally enable Automatic team membership and set the claim to
groups - Click Save settings
Step 3 — Configure via Portainer API (automation)
# Get admin JWT from Portainer
$ JWT=$(curl -sX POST https://portainer.acme.eu/api/auth \
-d '{"username":"admin","password":"$PORTAINER_ADMIN_PW"}' | jq -r .jwt)
# Apply OAuth settings $ curl -X PUT https://portainer.acme.eu/api/settings \ -H "Authorization: Bearer $JWT" \ -H 'Content-Type: application/json' \ -d '{ "AuthenticationMethod": 3, "OAuthSettings": { "ClientID": "portainer", "ClientSecret": "cs_xxxxxxxxxxxxxxxx", "AuthorizationURI": "https://id.acme.eu/acme/authorize", "AccessTokenURI": "https://id.acme.eu/acme/token", "ResourceURI": "https://id.acme.eu/acme/userinfo", "RedirectURI": "https://portainer.acme.eu", "UserIdentifier": "email", "Scopes": "openid profile email" } }'
# Apply OAuth settings $ curl -X PUT https://portainer.acme.eu/api/settings \ -H "Authorization: Bearer $JWT" \ -H 'Content-Type: application/json' \ -d '{ "AuthenticationMethod": 3, "OAuthSettings": { "ClientID": "portainer", "ClientSecret": "cs_xxxxxxxxxxxxxxxx", "AuthorizationURI": "https://id.acme.eu/acme/authorize", "AccessTokenURI": "https://id.acme.eu/acme/token", "ResourceURI": "https://id.acme.eu/acme/userinfo", "RedirectURI": "https://portainer.acme.eu", "UserIdentifier": "email", "Scopes": "openid profile email" } }'
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| OAuth login button not shown | Authentication method not set to OAuth | Set AuthenticationMethod: 3 in settings API or UI |
invalid_redirect_uri |
Portainer base URL not registered | Ensure Clavex has the exact redirect_uris matching Portainer's URL |
| Cannot log in as Portainer admin after enabling OAuth | Admin account not linked to SSO user | Keep a local admin account; log in at /#!/auth?method=internal |
| User logs in but sees no environments | No team membership assigned | Assign the user or their SSO team to an environment in Portainer |