SSO & SCIM

Sign in through your identity provider, and let your directory decide who is in the workspace. OIDC or SAML for login, SCIM 2.0 for membership.

Both are configured by the workspace owner, not an admin. Whoever points a workspace at an identity provider decides who becomes a member of it, and the blast radius of that is the whole workspace. SSO is on Business and above; SCIM is on Enterprise.

OIDC

Give Rezee the issuer URL and a client id and secret. The endpoints are discovered from the issuer, so there is nothing else to copy across.

The redirect URI to register with your provider:

https://api.rezee.app/api/auth/sso/callback

The client secret is sealed at rest and never returned - not by the API, not by the settings page. To change it, set a new one.

SAML

Give Rezee the provider's entity ID, its sign-on URL and its signing certificate. Give your provider these two, which are per workspace:

Entity ID (audience):  https://api.rezee.app/api/auth/sso/<workspace>
ACS URL:               https://api.rezee.app/api/auth/sso/saml/callback

Signing in

The login page asks the workspace whether it federates and which protocol, and offers the button if it does. That check says nothing about who is in the workspace - an unauthenticated caller asked.

A person arriving from the provider is matched to an existing account, or one is created for them and added to the workspace. Every failure lands back on the login page with the reason on it, rather than as a status code on a blank page: these endpoints are reached by a browser following redirects, and a 400 with a sentence in the body is a dead-end with no way back.

SCIM provisioning

SCIM manages memberships, not accounts. Usernames and email addresses are unique across all of Rezee, so a directory that could create and delete accounts would be one workspace's identity provider holding a veto over everybody's. What a workspace's directory legitimately controls is who is in that workspace.

Generate a token in SSO settings; it is shown once:

Base URL:  https://api.rezee.app/scim/v2
Auth:      Bearer reze_scim_...
VerbWhat it does
POST /Usersfind or create the account, add the membership, record the identity
PATCH /Users/{id}active: false removes the membership; active: true puts it back
DELETE /Users/{id}the same as deactivating - the strongest thing SCIM can ask for here, and it means "they have left the team"
GET /Userslist, with the filter directories actually send
GET /Users/{id}read one

Deprovisioning removes the membership and stamps the identity. The account itself survives, along with everything the person wrote - issues, reviews, commits and messages keep their author. A deprovisioned person signing in is told their organisation's directory removed the access and to ask their IdP administrator - they cannot fix it here, and sending them to a workspace owner who also cannot fix it wastes both afternoons.

Errors come back in SCIM's own shape - schemas, status, detail - because a directory shows its operator the detail and logs a plain-text 403 as a transport failure.

What ends up in the audit log

Every SCIM write is recorded with no actor and source: "scim", because the thing that acted was a directory rather than a person. SSO logins record the person and source: "sso". Rotating or revoking the SCIM token is audited too, and whether a rotation replaced an existing token is part of the record - issuing a first one and quietly replacing a live one are not the same event.

Turning it off

Deleting the connection stops the login button appearing and stops SCIM answering. Members already in the workspace stay members - removing federation is not a way to empty a workspace by accident. Take the SCIM token separately if you want provisioning to stop before login does.