Single sign-on
Connect your OpenID Connect identity provider, limit it to your email domains, test it, and then require it for everyone in the workspace.
On this page
Single sign-on (SSO) lets people sign in to your SteadyLink workspace with your organization's identity provider, such as Okta, Microsoft Entra ID, or Google Workspace, instead of a separate password. Once it works, you can require it, so access follows your directory: when someone is removed there, they can no longer sign in here. This page is for the workspace owner or admin setting it up.
SSO is available on the Business and Enterprise plans. On other plans, saving a connection returns 403 with the code business_plan_required.
How it works#
SteadyLink connects to one OpenID Connect (OIDC) provider per workspace using the authorization code flow with PKCE. When someone signs in:
- They open the workspace's SSO login URL and are sent to your provider.
- Your provider signs them in, including any multi-factor checks you require there.
- SteadyLink checks the returned identity: it must be signed by your provider, meant for your client ID, include an email address, and mark that email as verified.
- The email's domain must be one of your allowed domains, or sign-in is refused with
sso_domain_not_allowed. - SteadyLink signs the person in. Someone signing in for the first time gets an account and joins the workspace as a member. Someone who already has a SteadyLink account with that email is matched to it.
SSO sign-ins do not ask for a SteadyLink two-step verification code. Your provider owns the second factor for those sign-ins.
Before you start#
You need:
- A workspace on Business or Enterprise, and the owner or admin role.
- Permission to create an application (also called a client or app registration) in your identity provider.
- A provider that publishes OIDC discovery at
{issuer}/.well-known/openid-configurationover HTTPS, and signs ID tokens with RS256 or ES256. - Seats for the people who will join. A first-time SSO user cannot join a workspace that has no free seats.
Set it up#
Create an OIDC application in your provider
Create a web application that uses the authorization code flow. Set its redirect URI (sometimes called a callback or reply URL) to exactly:
Redirect URI https://api.steadylink.io/api/platform/sso/callbackAllow the
openid,email, andprofilescopes, and make sure the ID token includesemailandemail_verified. Note the issuer URL, client ID, and client secret.Save the connection in SteadyLink
Send the configuration with a signed-in owner or admin session, or an API key with
workspace:admin. Leaveenabledon andenforceoff for now.Save the SSO connection curl -X PUT https://api.steadylink.io/api/platform/sso \ -H "X-API-Key: $STEADYLINK_ADMIN_KEY" \ -H "Content-Type: application/json" \ -d '{ "issuer": "https://id.example.com", "clientId": "steadylink-prod", "clientSecret": "'"$OIDC_CLIENT_SECRET"'", "emailDomains": ["example.com", "staff.example.com"], "enabled": true, "enforce": false }'The response includes
startPath, the login path for your workspace, andtestedAt, which isnulluntil the first successful sign-in.Test a sign-in
Open the login URL in a private browser window and sign in with an account from an allowed domain:
SSO login URL https://api.steadylink.io/api/platform/sso/9d1c7e40-2b6a-4f3e-8a15-6c0e2f9b4d71/startThe ID in the path is your workspace ID. A successful sign-in lands on the SteadyLink sign-in page, completes, and records the time as
testedAt.Require SSO
Once
testedAtis set, save the same configuration again with"enforce": true. Share the login URL with your team, for example as a tile in your identity provider's app launcher.
Field rules#
| Field | Rules |
|---|---|
issuer | Must start with https://. No query string, fragment, or credentials. A trailing slash is removed. Must match the issuer in the provider's discovery document. |
clientId | Up to 512 characters. |
clientSecret | 8 to 4,096 characters. Required the first time; omit it later to keep the stored secret. It is stored encrypted and never returned. |
emailDomains | 1 to 25 domains, such as example.com. Lower-cased; no @, and no leading or trailing dot. Subdomains must be listed separately. |
enabled | Turns the connection on or off. Turning it off also turns enforcement off. |
enforce | Requires SSO for the workspace. Allowed only after a successful test. |
GET /api/platform/sso returns the current configuration (without the secret), whether SSO is available on your plan, and testedAt.
Test before you enforce#
SteadyLink will not let you require SSO until a sign-in through the connection has succeeded. Saving "enforce": true before that returns 409 with the code sso_test_required.
Changing the issuer, client ID, client secret, or allowed domains clears testedAt, because the old test no longer proves the new settings work. To change a connection that is already enforced, save the change with "enforce": false, test again, then turn enforcement back on.
What enforcement does#
With enforcement on, members who signed in with a password, Google, or GitHub are refused when they open the workspace's files, with 403 and the code sso_required. The error includes ssoUrl, the login path to use instead. Signing in through SSO clears it.
Enforcement applies to people, not to keys. Workspace API keys and S3 app keys keep working. When you turn enforcement on, review the keys in the workspace and revoke any that belong to integrations you no longer trust. See API key safety.
Removing someone from your identity provider stops new SSO sign-ins, but it does not end sessions they already have in SteadyLink or remove them from the workspace. To cut access at once, also remove them under Settings > Members.
Troubleshooting#
| Error | Cause |
|---|---|
invalid_sso_configuration | The issuer is not HTTPS or is malformed, or an email domain is not valid. |
oidc_discovery_failed | SteadyLink could not read {issuer}/.well-known/openid-configuration, its issuer did not match, or an endpoint was not HTTPS. |
sso_exchange_failed | The provider rejected the code exchange, or the ID token was invalid: wrong audience or issuer, missing email, or email_verified not true. Check the redirect URI and client secret first. |
sso_domain_not_allowed | The person's email domain is not in emailDomains. |
invalid_sso_state | The sign-in took longer than 10 minutes or the link was reused. Start again from the login URL. |
seat_limit_reached | The workspace has no free seat for a first-time user. Pending invitations count as used seats. |
Encrypted originals#
Admins of workspaces with sensitive files often turn on SteadyLink's own encryption at the same time. In Settings > Security, Encrypt original files makes SteadyLink encrypt each new revision with the workspace's own key before storing it, in addition to the storage platform's encryption at rest. Delivery and conversions decrypt files inside the service, so links and integrations do not change. It applies to files uploaded after you turn it on. See the Security overview.