Console
Authentication

Single sign-on

Console sign-in through your identity provider.

With single sign-on (SSO), your members sign in to the RouterPlus console through your identity provider. RouterPlus supports OpenID Connect (OIDC) and SAML 2.0, with Okta, Microsoft Entra ID and Google Workspace.

An organization can have several connections. Each connection signs in the emails of its domains. For example, acme.com signs in through Okta and acme.co.uk through Entra ID.

  • Members sign in at https://demo.routerplus.com/sso with their work email. RouterPlus sends them to the connection for that domain.
  • The sign-in link for one connection is https://demo.routerplus.com/sso/start?connection=<connection id>.
  • Email links and the normal sign-in page continue to work.

In the console, open Team > Single sign-on.

Set up a connection

  1. 01
    Create the application in your identity provider. See the sections below.
  2. 02
    Create the connection with a management key: POST https://demo-api.routerplus.com/v1/sso/connections.
  3. 03
    Add the DNS TXT record that the answer shows for each domain.
  4. 04
    Verify the domains: POST https://demo-api.routerplus.com/v1/sso/connections/<id>/verify-domains.
  5. 05
    Add your members to the organization, or turn on just-in-time provisioning.

A connection signs in no one until you verify its domain.

The URLs your identity provider needs

UseURL
OIDC redirect URI (sign-in redirect URI)https://demo.routerplus.com/sso/oidc/callback
SAML assertion consumer service (ACS, reply URL)https://demo.routerplus.com/sso/saml/acs
SAML audience (entity id of RouterPlus)the connection's sp_entity_id
SAML metadata of RouterPlushttps://demo.routerplus.com/sso/saml/metadata?connection=<connection id>

Create a connection

OIDC:

bash
curl https://dev2-api.routerplus.com/v1/sso/connections \
  -H "Authorization: Bearer $ROUTERPLUS_MANAGEMENT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "oidc",
    "name": "Okta",
    "email_domains": ["acme.com"],
    "issuer": "https://acme.okta.com",
    "client_id": "0oa1b2c3d4",
    "client_secret": "...",
    "default_role": "viewer",
    "jit_provisioning": false
  }'

SAML:

bash
curl https://dev2-api.routerplus.com/v1/sso/connections \
  -H "Authorization: Bearer $ROUTERPLUS_MANAGEMENT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "saml",
    "name": "Entra ID",
    "email_domains": ["acme.com"],
    "idp_entity_id": "https://sts.windows.net/<tenant id>/",
    "idp_sso_url": "https://login.microsoftonline.com/<tenant id>/saml2",
    "idp_certificate": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
  }'

The response is 201, with the connection in data.

Fields

FieldKindMeaning
kindbothoidc or saml. You cannot change it later.
namebothA label, 1 to 100 characters.
email_domainsboth1 to 50 domains. The connection signs in only emails at these domains.
enabledbothfalse stops all sign-ins through the connection. Default true.
default_rolebothviewer or admin. The role a member gets from just-in-time provisioning. Default viewer.
jit_provisioningbothtrue adds a new email to the organization at its first sign-in. Default false.
issuerOIDCThe issuer URL of your identity provider, https only. RouterPlus reads <issuer>/.well-known/openid-configuration.
client_idOIDCThe client id of the application.
client_secretOIDCThe client secret. Leave it out for a public client with PKCE only.
allowed_tenant_idsOIDCUp to 50 Entra ID tenant ids that can sign in. See Tenant filtering.
idp_entity_idSAMLThe issuer (entity id) of your identity provider.
idp_sso_urlSAMLThe single sign-on URL of your identity provider, https only.
idp_certificateSAMLThe signing certificate of your identity provider, in PEM or as bare base64. RSA keys only.
sp_entity_idSAMLThe audience that your identity provider puts in the assertion. Default urn:routerplus:sso:<connection id>.

RouterPlus stores the client secret encrypted and never returns it. A connection with a secret shows "client_secret": "__secret__".

Routes

All routes take a management key. They also work under /api/v1.

RouteWhat it does
GET /v1/sso/connectionsLists your organization's connections.
POST /v1/sso/connectionsCreates a connection.
GET /v1/sso/connections/<id>Shows one connection.
PATCH /v1/sso/connections/<id>Changes the fields you send. Send "client_secret": null to remove the secret.
DELETE /v1/sso/connections/<id>Deletes the connection.
POST /v1/sso/connections/<id>/verify-domainsLooks up the DNS records and marks the domains verified.

RouterPlus writes every change to the audit log (GET /v1/audit).

Verify your domains

Each domain in the response has a verification object:

json
{
  "domain": "acme.com",
  "verified": false,
  "verification": { "type": "TXT", "name": "_routerplus-sso.acme.com", "value": "routerplus-sso=4f1c..." }
}
  1. 01
    At your DNS provider, add a TXT record with that name and value.
  2. 02
    Call verify-domains. The response lists each domain with verified. A domain that fails also has a reason.
  3. 03
    If a domain fails, call verify-domains again after your DNS change propagates.
  • In your organization, a domain belongs to one connection.
  • A verified domain belongs to one organization. No other organization can verify or add it.
  • A domain stays verified when you change the connection's other fields. A domain that you remove loses its verification.

Okta

OIDC:

  1. 01
    In the Okta admin console, open Applications, then Create App Integration.
  2. 02
    Select OIDC - OpenID Connect and Web Application.
  3. 03
    Set the sign-in redirect URI to https://demo.routerplus.com/sso/oidc/callback.
  4. 04
    Assign the application to your people or groups.
  5. 05
    Copy the client id and client secret. The issuer is your Okta domain, for example https://acme.okta.com. With a custom authorization server, the issuer is that server's URL, for example https://acme.okta.com/oauth2/default.

SAML:

  1. 01
    Create an app integration and select SAML 2.0.
  2. 02
    Set Single sign-on URL to https://demo.routerplus.com/sso/saml/acs.
  3. 03
    Set Audience URI (SP Entity ID) to the connection's sp_entity_id.
  4. 04
    Set Name ID format to EmailAddress and Application username to Email.
  5. 05
    Open View SAML setup instructions. Copy the identity provider issuer, the single sign-on URL and the X.509 certificate.

To use the default sp_entity_id, create the connection first. Then add the Okta fields with PATCH.

Microsoft Entra ID

OIDC:

  1. 01
    In the Entra admin center, open App registrations, then New registration.
  2. 02
    Add a Web redirect URI: https://demo.routerplus.com/sso/oidc/callback.
  3. 03
    Under Certificates & secrets, create a client secret.
  4. 04
    Under Token configuration, add the optional claim email to the ID token.
  5. 05
    The issuer for a single-tenant app is https://login.microsoftonline.com/<tenant id>/v2.0.

Entra ID does not send email_verified. Make sure that each user's email attribute holds their real work email.

SAML:

  1. 01
    Open Enterprise applications, then New application, then Create your own application.
  2. 02
    Under Single sign-on, select SAML.
  3. 03
    Set Identifier (Entity ID) to the connection's sp_entity_id.
  4. 04
    Set Reply URL (Assertion Consumer Service URL) to https://demo.routerplus.com/sso/saml/acs.
  5. 05
    Download Certificate (Base64). Copy Login URL (the idp_sso_url) and Microsoft Entra Identifier (the idp_entity_id).

RouterPlus reads the email from the NameID when it is an email. Otherwise it reads the emailaddress claim.

Google Workspace

OIDC:

  1. 01
    In Google Cloud console, open APIs & Services, then Credentials.
  2. 02
    Create an OAuth client ID of type Web application.
  3. 03
    Add the authorized redirect URI https://demo.routerplus.com/sso/oidc/callback.
  4. 04
    The issuer is https://accounts.google.com.

Set the OAuth consent screen to Internal. Then only your Workspace accounts can sign in.

SAML:

  1. 01
    In the Google Admin console, open Apps, then Web and mobile apps, then Add custom SAML app.
  2. 02
    Copy the SSO URL, the entity id and the certificate.
  3. 03
    Set ACS URL to https://demo.routerplus.com/sso/saml/acs and Entity ID to the connection's sp_entity_id.
  4. 04
    Set Name ID format to EMAIL and Name ID to Primary email.
  5. 05
    Turn the app on for your organizational units.

Tenant filtering

A connection signs in a person only when both conditions are true:

  • The email's domain is one of the connection's verified email_domains.
  • For Entra ID with allowed_tenant_ids set, the tid claim is in that list.

A multi-tenant Entra ID app uses the issuer https://login.microsoftonline.com/organizations/v2.0 or /common/v2.0. Any Entra tenant can sign in to such an app, and a tenant admin can set any email on a user. Thus a connection with a multi-tenant issuer needs allowed_tenant_ids. Without the list, the connection refuses every sign-in.

Just-in-time provisioning

  • jit_provisioning off: only existing members sign in. Add members in the console or with SCIM.
  • jit_provisioning on: a person with an email at a verified domain joins the organization at the first sign-in, with default_role (viewer or admin).

SSO never makes an owner. A member that an admin turned off stays off.

What a sign-in checks

OIDC:

  • Authorization code flow with PKCE (S256), state and nonce.
  • The ID token signature, against the identity provider's published keys.
  • iss, aud (your client_id), exp, nbf, iat and nonce.
  • email_verified must be true when the claim is present.

SAML:

  • RouterPlus sends an AuthnRequest with the HTTP-Redirect binding. It reads the response with the HTTP-POST binding.
  • The response or the assertion must be signed with RSA-SHA256 and exclusive canonicalization. Every signature in the response must verify with idp_certificate.
  • Destination, Recipient, Audience, InResponseTo, NotBefore and NotOnOrAfter must match.
  • RouterPlus accepts an assertion one time.
  • RouterPlus refuses encrypted assertions, and XML with a DOCTYPE or entity declarations.

The sign-in must finish in the browser that started it, within 10 minutes. Sign-ins start only from RouterPlus. RouterPlus refuses an unsolicited (IdP-initiated) SAML response.

Errors

The sign-in page shows the reason.

MessageFix
Single sign-on is not set up for this email domainAdd the domain to a connection, verify it and set enabled to true.
This connection does not sign in emails at <domain>Add the domain to the connection and verify it.
You are not a member of this organizationAdd the person as a member, or turn on jit_provisioning.
Your account in this organization is turned offAn admin turned the member off. Turn the member on again.
The ID token has no email claimAdd the email scope or the email optional claim.
Your identity provider has not verified this email addressVerify the email in the identity provider.
Your Entra ID tenant is not allowedAdd the tenant id to allowed_tenant_ids.
Set allowed tenant ids on the connectionA multi-tenant Entra ID issuer needs allowed_tenant_ids.
The identity provider did not complete the sign-inCheck client_id, client_secret and the redirect URI.
The SAML response was refused: ... audience ...Set the audience in the identity provider to sp_entity_id.
The SAML response was refused: ... signature ...Upload the identity provider's current signing certificate.
The SAML response was refused: ... encrypted assertions ...Turn assertion encryption off.
This sign-in request has expired or was already usedStart the sign-in again.
This sign-in was started in another browserStart the sign-in again in this browser.

For agents: /docs/sso.md and /llms.txt