Connect an OpenID Connect provider
Single sign-on lets the people in your team sign in to deploybase with the account they already have at your identity provider. Any provider that publishes an OpenID Connect discovery document can be connected.
Go to Settings → Single sign-on to add a connection. You need the Admin role; a few actions on the page are Owner only, and the page says which.
Provider-specific pages: Keycloak and Authentik.
What you register where
Section titled “What you register where”deploybase does not talk to your provider directly. Your provider is registered with the identity service that runs deploybase sign-in, and that service is the client your provider sees. Two things follow, and both surprise people:
- The redirect URI you register in your provider is not a deploybase address. The exact value is shown on the Settings → Single sign-on page, next to the connection. Copy it from there rather than typing one that looks right.
- The client you create in your provider is a confidential client: it has a client secret, and it authenticates with that secret at the token endpoint.
You give deploybase three things: the issuer URL, the client ID, and the client secret. Everything else is read from your provider’s discovery document.
Once a connection is saved, your team signs in at app.deploybase.eu/login/sso/example-team, where example-team is your team URL.
Issuer URL
Section titled “Issuer URL”The issuer is the base URL your provider publishes for itself. deploybase fetches {issuer}/.well-known/openid-configuration when you save the connection, and refuses the connection if that fetch does not produce a usable OpenID configuration.
An example issuer looks like this:
https://id.example.com/realms/engineeringThe .well-known path is appended to the issuer’s path, not to the host. An issuer with a path keeps it: https://id.example.com/app publishes at https://id.example.com/app/.well-known/openid-configuration. Providers that give each application its own issuer path are the usual reason a URL that “looks up” is reported as not found.
Rules the value has to follow:
- it starts with
https:// - it contains no username or password in front of an
@ - it contains no query string and no fragment
What the messages mean:
- We could not fetch the OpenID configuration. DNS, TLS, a timeout, or a provider that is not reachable from the public internet. Open
{issuer}/.well-known/openid-configurationin a browser from outside your network. A provider that only answers on your VPN cannot be used for sign-in. - Your provider answered HTTP 404 / 403 / 500. The address resolves to something, but not to an OpenID configuration. Compare it with the Issuer value your provider’s console shows.
- The response is not valid JSON. The URL usually points at a sign-in page rather than at the configuration document.
- Your provider reports its issuer as X, but you entered Y. Sign-in compares those two strings exactly, character for character, so a connection with a mismatch could never work. Enter the value your provider reports. The form offers it as a suggestion where the reported value is itself a usable issuer.
- Your provider reports its issuer with a trailing slash. A difference of only a trailing slash is not treated as a mismatch. The provider’s spelling is stored, and you are told it was adjusted. Nothing to fix.
- Your provider does not publish an authorization endpoint / token endpoint / JWKS URI. Sign-in needs all three, as absolute
httpsaddresses. A relative orhttpaddress here usually means the provider’s own public URL setting is wrong. - Your provider does not offer the authorization code flow. Enable it on the client. It is the only flow that can be used.
Signing algorithm
Section titled “Signing algorithm”Your provider signs the ID token it issues, and sign-in verifies that signature against the keys at your provider’s JWKS URI. Only RS256, ES256 and PS256 are verified.
- Your provider does not sign its ID tokens. The configuration advertises
none, or nothing at all. Select a signing key on the provider and save again. An unsigned ID token is an assertion anyone can forge, so this is refused rather than warned about. - Your provider only signs with a shared-secret algorithm (HS256 and similar). Sign-in fetches your public keys and verifies asymmetric signatures only, so it can never verify an HMAC-signed token. Select an asymmetric signing key. In Authentik this is the Signing Key setting, which ships empty.
- Your provider does not offer RS256, ES256 or PS256. Change the signing key on the provider to one of those three. Every sign-in fails at token verification until you do.
Sign-in always sends an S256 code challenge, whether or not your provider advertises PKCE.
- Your provider does not say whether it supports PKCE. Advisory. Most providers accept S256 without listing it in their configuration. Run one test sign-in before you hand the link to your team.
- Your provider advertises PKCE but not the S256 method. That is a prediction of failure, not advice: the provider has published the list and left S256 out, so it will reject the request. Enable S256 on the client. In Keycloak the setting is Proof Key for Code Exchange Code Challenge Method.
Client authentication
Section titled “Client authentication”The connection authenticates at your provider’s token endpoint with the client ID and client secret you entered.
Your provider does not accept a client secret at the token endpoint. The provider advertises only methods such as private_key_jwt, or the client is registered as a public client. Change the client to a confidential client that uses a client secret. A public client cannot be used: there would be nothing proving the token request came from us.
Rotating a secret is safe to do at any time. Set the new secret in your provider, paste it into the connection, and save. Sessions that are already open are not affected.
Userinfo and ID token
Section titled “Userinfo and ID token”After a person authenticates, their name and email address have to come from somewhere. There are two sources: your provider’s userinfo endpoint, or the ID token itself. The connection has a Read the profile from the ID token setting that picks between them.
Your provider has no userinfo endpoint. Nothing else can read the name and email, so the setting is turned on for you and the connection is saved that way. This is a correction rather than advice: a connection reading from an endpoint that does not exist cannot work at all.
Two other cases turn it on:
- A Keycloak connection created without an explicit choice. Keycloak can be configured to sign its userinfo response, which the broker cannot read, and that setting is not visible from outside. See signed userinfo. Set the option to false explicitly if you need userinfo.
- Any connection where you set it yourself.
If names or email addresses are missing after sign-in, check scopes first, then this setting.
Scopes
Section titled “Scopes”A connection requests openid, profile and email unless you enter a different list. Leave it empty to use those three.
- Your provider does not offer the profile scope. People may sign in without a name. Allow the scope on the client in your provider’s console.
- Your provider does not offer the email scope. People may sign in without an email address, and a sign-in with no address is refused: the address is how a person is matched to their membership. Allow the scope, and check that the claim is actually mapped onto the token or the userinfo response.
Both warnings are only raised when your provider publishes a scope list. A provider that lists nothing is not checked.
Email verified
Section titled “Email verified”Sign-in matches a person to their membership by email address, so it needs the address and your provider’s statement that the address is verified. Two refusals come from this.
The provider shared no address at all. Usually a missing email scope, or an email claim that is not mapped onto the token. Fix it at the provider: see scopes.
The provider shared an address without saying it was verified. The provider sent email_verified: false, or left the claim out. There are two ways forward:
- Fix it at the provider, which is the better answer. Mark the account verified, or correct the scope mapping that drops the claim. Authentik reports every user as unverified by default, and Keycloak has a per-user Email verified switch.
- Turn on Trust unverified email addresses on the connection. This is a statement that you vouch for the provider: addresses it reports are accepted as proof of identity even when it does not call them verified. Only the team Owner can turn it on, because anyone who can set an address at that provider can then sign in as the holder of that address in your team.
Not a member
Section titled “Not a member”The person authenticated at your provider correctly. Authenticating is not membership: they still have to be a member of your team.
This is what a member sees when no membership in your team carries their address, and the address cannot be used to create one either. That happens in two ways:
- The person is genuinely not in the team. Invite them from Settings → Members, or turn on automatic provisioning.
- A deploybase account with that address already exists somewhere else on the platform, such as a personal team or another customer’s team. An existing account is never absorbed into your team. Invite the address instead, and they accept the invitation with the account they already have.
Nothing about this is fixed by retrying the sign-in.
Automatic provisioning
Section titled “Automatic provisioning”A connection with automatic provisioning on creates the membership it does not find: someone who authenticates at your provider, and whose address belongs to no membership yet, becomes a member of your team on their first sign-in. It is on by default.
The role a person lands on is set per connection, and it can only be Member or Viewer. A connection can never mint an Admin or an Owner, so a misconfigured provider cannot hand out control of your team.
Sign-in was refused because automatic provisioning is off. Your team is invite-only, and the person’s address matches no membership. Either invite them from Settings → Members, or turn automatic provisioning back on and choose the role new people land on.
Turn it off when your provider’s user directory is wider than your deploybase team, which it usually is. Leave it on when everyone who can authenticate at the provider should be able to use deploybase.
Connection disabled
Section titled “Connection disabled”Sign-in through this connection is not currently possible. One message covers two situations, because the person in front of the screen cannot act on the difference:
- The connection is disabled. Re-enable it at Settings → Single sign-on.
- The team itself can no longer be signed in to, for example because it is suspended. Billing and account state are the place to look, not the connection.
Your team’s logs distinguish the two. Members can always fall back to signing in with email and password while the connection is off.
Account in another team
Section titled “Account in another team”This is the one refusal you cannot fix from the connection, so it is worth understanding before you roll SSO out.
A connection belongs to your team’s organization, and it can only be linked to accounts that live in that organization. Someone who joined your team by accepting an invitation kept the account they already had, which lives in their own organization. Their membership in your team is real and works normally; the SSO connection simply cannot be attached to their account.
What the member should do: sign in with their email address and password at app.deploybase.eu. They land in the same team with the same role. Nothing is lost, and they do not need to be re-invited.
Retrying, clearing cookies or re-adding the connection changes nothing here. This is a property of how the account was created.
Where it matters in practice: colleagues who were invited before you set SSO up keep signing in with email and password, while people who arrive through the connection from now on sign in with your provider. If you want everyone on SSO, the member has to give up the old account and be provisioned fresh through the connection, which means losing that account’s sign-in history.