# OrbitID documentation > OrbitID is a hosted identity bridge for B2B software: enterprise SSO (SAML 2.0 and OIDC) with any identity provider, and SCIM 2.0 Directory Sync, behind one OAuth 2.0 integration. --- # OrbitID documentation > Learn how to add enterprise SSO (SAML and OIDC) and SCIM Directory Sync to your app with OrbitID. OrbitID is a hosted identity bridge for B2B software. You integrate once with OrbitID's OAuth 2.0 / OIDC endpoints; OrbitID handles SAML 2.0 and OIDC single sign-on with every identity provider your customers use, and SCIM 2.0 Directory Sync for provisioning their users and groups. ## Start here - [Quickstart](https://orbitid.com/docs/quickstart.md) – from a new team to a verified user profile. - [Environments](https://orbitid.com/docs/environments.md) – Production and Sandbox, and what a product id is. - [API keys](https://orbitid.com/docs/api-keys.md) – per-environment keys and how to authenticate. - [Billing](https://orbitid.com/docs/billing.md) – what a connection costs and how it is billed. ## Single sign-on - [Admin Portal](https://orbitid.com/docs/admin-portal.md) – self-serve setup links for your customers' IT admins, with domain verification. - [SSO setup guides](https://orbitid.com/docs/sso.md) – Okta, Microsoft Entra ID, Google Workspace, Auth0, OneLogin, JumpCloud, PingOne, Rippling, Microsoft AD FS, and generic SAML or OIDC. ## Directory Sync - [Directory Sync overview](https://orbitid.com/docs/directory-sync.md) – the SCIM 2.0 endpoint, bearer tokens and events. - [Webhooks](https://orbitid.com/docs/webhooks.md) – receive user and group events and verify signatures. - Provider guides for [Okta](https://orbitid.com/docs/directory-sync/okta.md), [Microsoft Entra ID](https://orbitid.com/docs/directory-sync/azure.md) and [Google Workspace](https://orbitid.com/docs/directory-sync/google.md). ## For AI agents - Every page is also available as Markdown: add `.md` to its URL, or use **Copy page** next to the title. - [llms.txt](https://orbitid.com/llms.txt) lists every page, and [llms-full.txt](https://orbitid.com/llms-full.txt) has all of them in one file. - Guides that change code start with a prompt you can paste into Claude Code, Cursor or Codex. ## Endpoints | What | URL | | --------------- | ---------------------------------------------------------- | | Dashboard | `https://app.orbitid.com` | | REST API | `https://app.orbitid.com/api/v1` | | OAuth authorize | `https://app.orbitid.com/api/oauth/authorize` | | OAuth token | `https://app.orbitid.com/api/oauth/token` | | OAuth userinfo | `https://app.orbitid.com/api/oauth/userinfo` | | OIDC discovery | `https://app.orbitid.com/.well-known/openid-configuration` | | SAML ACS URL | `https://app.orbitid.com/api/oauth/saml` | | Sandbox ACS URL | `https://app.orbitid.com/api/oauth/sandbox/saml` | | SP metadata | `https://app.orbitid.com/.well-known/sp-metadata` | | SCIM 2.0 base | `https://app.orbitid.com/api/scim/v2.0` | Need help? Email [support@orbitid.com](mailto:support@orbitid.com). --- # Quickstart > Create a team, get a sandbox API key, connect an identity provider and complete a login through OrbitID. This guide takes you from a new OrbitID team to a verified user profile in your app. Everything below works against the free Sandbox environment. ## Prompt for your coding agent Paste this into Claude Code, Cursor or Codex in your app's repo, or follow the steps below by hand. ```text Add enterprise SSO to this app with OrbitID. Follow https://orbitid.com/docs/quickstart.md 1. Read the key from ORBITID_API_KEY and the product id from ORBITID_PRODUCT_ID. 2. Add a sign-in route that redirects to https://app.orbitid.com/api/oauth/authorize with client_id=tenant=&product=, our callback URL and a random state. 3. In the callback, check state, swap the code at /api/oauth/token, read /api/oauth/userinfo. 4. Find or create the user by email and start a session the way this app already does. 5. Test with the Sandbox key (orb_test_) and the tenant "acme". 6. Run the tests, then list the files you changed and the env vars I need to set. ``` ## Create a team Sign up at [app.orbitid.com/signup](https://app.orbitid.com/signup) and create a team. Every team gets two environments: - **Sandbox** – free, up to 5 connections, for development and testing. - **Production** – $25 per connection per month, for your customers. Each environment has its own connections, API keys, logs and a **product id**. You will need the product id when you start a login; it is shown on the environment's **Configuration** page. See [Environments](https://orbitid.com/docs/environments.md). ## Create an API key Open the environment, go to **API keys** and create a key. Sandbox keys start with `orb_test_`; production keys start with `orb_live_`. The full key is shown once, so copy it straight away. Send it as a bearer token on every request to `https://app.orbitid.com/api/v1`: ```bash curl https://app.orbitid.com/api/v1/sso \ -H "Authorization: Bearer orb_test_..." ``` A key is scoped to its environment: the `product` of every request is set from the key, so you never pass it yourself. See [API keys](https://orbitid.com/docs/api-keys.md). ## Create a connection A connection links one of your customers (a **tenant**, identified by any string you choose, such as `acme`) to their identity provider. There are three ways to create one. ### In the dashboard Open **Connections**, click **New connection**, enter the tenant and paste the IdP metadata URL or XML. The [SSO setup guides](https://orbitid.com/docs/sso.md) show where to find the metadata for each provider. ### With an Admin Portal link Let your customer's IT admin do it themselves. Create a link and send it to them: ```bash curl -X POST https://app.orbitid.com/api/v1/portal/links \ -H "Authorization: Bearer orb_test_..." \ -H "Content-Type: application/json" \ -d '{ "tenant": "acme", "tenantName": "Acme Inc.", "redirectUrl": "https://yourapp.com/settings/sso", "domains": ["acme.com"] }' ``` The response contains a `url` that the admin opens: ```json { "data": { "id": "6f1c0b2d…", "url": "https://app.orbitid.com/portal/6f1c0b2d…", "tenant": "acme", "tenantName": "Acme Inc.", "redirectUrl": "https://yourapp.com/settings/sso", "domains": ["acme.com"], "verifiedDomains": [], "expiresAt": 1727000000000 } } ``` `domains` is optional. When you pass it, the admin has to verify the domains before the connection goes live. See [Admin Portal](https://orbitid.com/docs/admin-portal.md). ### With the API If you already have the metadata, create the connection directly: ```bash curl -X POST https://app.orbitid.com/api/v1/sso \ -H "Authorization: Bearer orb_test_..." \ -H "Content-Type: application/json" \ -d '{ "name": "Acme Okta", "tenant": "acme", "defaultRedirectUrl": "https://yourapp.com/auth/callback", "redirectUrl": ["https://yourapp.com/auth/callback"], "metadataUrl": "https://acme.okta.com/app/abc123/sso/saml/metadata" }' ``` Use `rawMetadata` instead of `metadataUrl` to pass the XML inline. For an OIDC provider send `oidcDiscoveryUrl`, `oidcClientId` and `oidcClientSecret` instead of the metadata fields. `redirectUrl` lists every URL you will use as `redirect_uri` later. ## Start a login Send the user to the authorize endpoint. `client_id` is the string `tenant=&product=`, URL-encoded, where `product` is the product id from the Configuration page: ```text https://app.orbitid.com/api/oauth/authorize ?client_id=tenant%3Dacme%26product%3D &redirect_uri=https%3A%2F%2Fyourapp.com%2Fauth%2Fcallback &response_type=code &state= ``` OrbitID looks up the tenant's connection, redirects the user to their IdP, and once they have signed in redirects them back to `redirect_uri` with `code` and `state` in the query string. Check that `state` matches what you sent. ## Exchange the code Exchange the code for an access token. When `client_id` carries the tenant and product, pass `dummy` as the `client_secret`: ```bash curl -X POST https://app.orbitid.com/api/oauth/token \ -H "Content-Type: application/x-www-form-urlencoded" \ --data-urlencode "grant_type=authorization_code" \ --data-urlencode "client_id=tenant=acme&product=" \ --data-urlencode "client_secret=dummy" \ --data-urlencode "code=" \ --data-urlencode "redirect_uri=https://yourapp.com/auth/callback" ``` ```json { "access_token": "5b1a…", "token_type": "bearer", "expires_in": 300 } ``` If you prefer, use the `clientID` and `clientSecret` that the API returned when the connection was created instead of the tenant/product pair. ## Fetch the profile ```bash curl https://app.orbitid.com/api/oauth/userinfo \ -H "Authorization: Bearer " ``` ```json { "id": "00u1abc…", "email": "jane@acme.com", "firstName": "Jane", "lastName": "Doe", "requested": { "tenant": "acme", "product": "" }, "raw": { "…": "all attributes the IdP sent" } } ``` The `email` and `id` were verified by the customer's identity provider. Look the user up (or create them) in your app, start a session, and you are done. ## Next steps - Move a customer to [Production](https://orbitid.com/docs/environments.md) and set up [Billing](https://orbitid.com/docs/billing.md). - Add [Directory Sync](https://orbitid.com/docs/directory-sync.md) to provision users and groups automatically. - Read the [SSO setup guides](https://orbitid.com/docs/sso.md) for the exact steps in each identity provider. --- # Environments > Production and Sandbox environments in OrbitID: what they are for, what they cost and where to find the product id. Every OrbitID team has two environments. They are fully separate: each has its own connections, directories, API keys, portal links, logs and product id. | | Sandbox | Production | | ---------------- | ------------------------ | ---------------------------- | | Purpose | Development, testing, CI | Your customers | | Price | Free | $25 per connection per month | | Connection limit | 5 | Unlimited | | API key prefix | `orb_test_` | `orb_live_` | ## Prompt for your coding agent Paste this into Claude Code, Cursor or Codex in your app's repo, or follow the steps below by hand. ```text Use the OrbitID Sandbox in development and Production in production. Follow https://orbitid.com/docs/environments.md 1. Read ORBITID_API_KEY and ORBITID_PRODUCT_ID per environment and add both to .env.example. 2. Fail at startup if production runs with an orb_test_ key, or development with orb_live_. 3. Keep every other OrbitID setting the same across environments. 4. List the env vars I need to set in each deploy target. ``` ## Sandbox Use the Sandbox while you build. It has every feature of Production, including Admin Portal links, Directory Sync and webhooks, and is limited to 5 connections (SSO connections and directories combined). Sandbox connections work with real identity providers, so you can test against your own Okta or Entra ID tenant end to end. The Sandbox is for building and testing, not for your customers' live sign-ins. It has its own SAML ACS URL and SP Entity ID, so an identity provider set up against the Sandbox only ever talks to the Sandbox. See the [terms](https://orbitid.com/terms). ## Production Every new Production connection starts with a 7-day free trial. When the trial ends, the connection joins your subscription; without one it is switched off until you subscribe from **Billing**. Each connection is billed at $25 per month after its trial. See [Billing](https://orbitid.com/docs/billing.md). ## Product id Each environment has a **product id**. It is generated for you and shown on the environment's **Configuration** page. You use it: - as the `product` half of `client_id` when you start a login (`tenant=&product=`), - nowhere else: API requests authenticated with an environment key have their `product` set automatically. ## Configuration page The Configuration page also lists the values your customers' IT admins need when they set up their IdP: - **ACS URL**: `https://app.orbitid.com/api/oauth/saml` in Production, `https://app.orbitid.com/api/oauth/sandbox/saml` in the Sandbox - **SP Entity ID**: `https://saml.orbitid.com` in Production, `https://saml.orbitid.com/sandbox` in the Sandbox - **SP metadata**: `https://app.orbitid.com/.well-known/sp-metadata` in Production. The Sandbox URL adds its ACS URL and SP Entity ID as query parameters, so copy it from the Sandbox Configuration page. - **Signing certificate**: `https://app.orbitid.com/.well-known/saml.cer` - **OIDC callback URL**: `https://app.orbitid.com/api/oauth/oidc` - **OAuth endpoints**: authorize, token, userinfo and the OIDC discovery document - **SCIM base URL**: `https://app.orbitid.com/api/scim/v2.0` The [SSO setup guides](https://orbitid.com/docs/sso.md) refer to these values. ## Moving from Sandbox to Production Nothing changes in your code except the API key and the product id. Create the customer's connection in Production (or send them a Production Admin Portal link), then start logins with the Production product id. A SAML app set up against the Sandbox does not carry over: the customer's IT admin adds the Production ACS URL and SP Entity ID in their identity provider, which the Production Admin Portal walks them through. --- # API keys > Create, use and revoke OrbitID API keys. Keys are scoped to an environment and sent as a bearer token. API keys authenticate requests to the REST API at `https://app.orbitid.com/api/v1`. Every key belongs to one [environment](https://orbitid.com/docs/environments.md). ## Prompt for your coding agent Paste this into Claude Code, Cursor or Codex in your app's repo, or follow the steps below by hand. ```text Check how this app handles its OrbitID API key. Follow https://orbitid.com/docs/api-keys.md 1. Read the key only from ORBITID_API_KEY, on the server, so it never reaches the client bundle. 2. Search the repo for orb_live_ and orb_test_ strings and tell me where they are. 3. Call https://app.orbitid.com/api/v1 through one shared client with "Authorization: Bearer". 4. Treat a 401 as a revoked key: log it clearly instead of retrying. 5. List what you changed and any key I should rotate. ``` ## Create a key Open the environment in the dashboard, go to **API keys**, click **Create key** and give it a name (for example `backend` or `ci`). The full key is shown once; store it in your secrets manager. The dashboard only keeps the prefix, the creation date and when the key was last used. | Environment | Key looks like | | ----------- | -------------- | | Sandbox | `orb_test_…` | | Production | `orb_live_…` | ## Use a key Send the key in the `Authorization` header: ```bash curl https://app.orbitid.com/api/v1/sso \ -H "Authorization: Bearer orb_live_..." ``` A key can only see and change data in its own environment. The `product` of each request is derived from the key, so you never pass it, and a Sandbox key can never touch Production connections. ## Rotate or revoke a key Create a new key, deploy it, then revoke the old one from the same page. Revoking is immediate: requests with a revoked key get `401 Unauthorized`. ## What the API covers - `POST`, `GET`, `PATCH`, `DELETE` `/api/v1/sso` – SSO connections (SAML and OIDC). - `POST /api/v1/portal/links` – [Admin Portal](https://orbitid.com/docs/admin-portal.md) links. - `/api/v1/dsync` – directories, and the users, groups and events synced into them. - `/api/v1/sso-traces` – SSO logs. The OAuth endpoints under `/api/oauth` and the SCIM endpoints under `/api/scim/v2.0` do not use API keys: the first are called by your users' browsers and by your OAuth client, the second by your customers' directories with a per-directory bearer token. --- # Billing > How OrbitID bills production connections: $25 per SSO or Directory Sync connection per month, through Paddle, prorated, cancel any time. OrbitID charges per active connection in your **Production** environment. The Sandbox is free. | | Price | | ------------------------------------ | -------------------------- | | Sandbox | Free, up to 5 connections | | Production SSO connection | $25 per month | | Production Directory Sync connection | $25 per month | Prices are in US dollars. Tax is added where it applies. ## Free trial Every new Production connection starts with a **7-day free trial**. When the trial ends, the connection joins your subscription. Without a subscription it is switched off and waits for payment, so it cannot be used for logins or provisioning until you subscribe. ## Subscribe Go to **Billing** in the dashboard and click **Start subscription**. The checkout page shows what you pay today and what joins later: connections whose trial has ended are billed now, and connections still on trial join when their trial ends. Payment happens in Paddle's checkout, embedded on the same page. As soon as it completes, connections waiting for payment are switched back on. ## Paddle is our reseller Payments go through [Paddle](https://www.paddle.com), our reseller and Merchant of Record. Paddle works out sales tax or VAT for your country, collects it and issues the invoices. Add your company name and VAT or tax ID at checkout, or later under **Billing details**, to have them on your invoices. Card statements show `PADDLE.NET* ORBITID`. ## How the amount is calculated The subscription has one line for SSO connections and one for Directory Sync connections. Their quantities follow the number of active connections in Production: - A connection joins when its trial ends; deactivating or deleting it removes it. - Changes are **prorated** and added to your next payment, so you only pay for the part of the month a connection was active. - Deactivated connections are not billed. Sandbox connections are never billed. If you remove your last Production connection, nothing more is billed and the subscription ends at the end of the month, unless you add a connection before then. ## Update your card or cancel **Billing** shows the card on file. **Update card** opens Paddle's card form. If a payment fails, Paddle retries it for up to 30 days and **Billing** offers to pay the overdue invoice with another card; if it keeps failing, the subscription ends and Production connections switch off. To cancel, open the menu next to **Update card** and choose **Cancel subscription**. Everything keeps working until the end of the month you have paid for, then Production connections switch off and your Sandbox keeps working. Until that date you can choose **Keep subscription** to undo the cancellation. ## Invoices and receipts Paddle emails a receipt for every payment. **Billing** lists your invoices with a PDF for each, and **Open Paddle portal** gives you Paddle's own view of your payments. For refunds see our [Refund Policy](https://orbitid.com/refunds); every payment has a 30-day money-back guarantee. --- # SSO setup guides > Step-by-step guides for connecting Okta, Microsoft Entra ID, Google Workspace, Auth0, OneLogin, JumpCloud, PingOne, Rippling, AD FS and any SAML or OIDC identity provider to OrbitID. Each guide walks through creating an application in the identity provider, entering OrbitID's ACS URL and entity ID, mapping attributes and exporting the metadata. The same instructions are shown to your customers' IT admins inside an [Admin Portal](https://orbitid.com/docs/admin-portal.md) link. ## SAML 2.0 - [Okta](https://orbitid.com/docs/sso/okta.md) - [Microsoft Entra ID](https://orbitid.com/docs/sso/azure.md) - [Google Workspace](https://orbitid.com/docs/sso/google.md) - [Auth0](https://orbitid.com/docs/sso/auth0.md) - [OneLogin](https://orbitid.com/docs/sso/onelogin.md) - [JumpCloud](https://orbitid.com/docs/sso/jumpcloud.md) - [PingOne](https://orbitid.com/docs/sso/pingone.md) - [Rippling](https://orbitid.com/docs/sso/rippling.md) - [Microsoft AD FS](https://orbitid.com/docs/sso/microsoft-adfs.md) - [Generic SAML](https://orbitid.com/docs/sso/generic-saml.md) – any other SAML 2.0 identity provider ## OpenID Connect - [Generic OIDC](https://orbitid.com/docs/sso/generic-oidc.md) – any OpenID Connect provider ## Values you will need Every SAML guide asks for two values from your OrbitID **Configuration** page: | Value | Production | Sandbox | | ------------ | ---------------------------------------- | ------------------------------------------------ | | ACS URL | `https://app.orbitid.com/api/oauth/saml` | `https://app.orbitid.com/api/oauth/sandbox/saml` | | SP Entity ID | `https://saml.orbitid.com` | `https://saml.orbitid.com/sandbox` | OrbitID expects the `id`, `email`, `firstName` and `lastName` attributes in SAML assertions; each guide shows how to map them for that provider. --- # Admin Portal > Send your customers a self-serve Admin Portal link so their IT admin can connect their identity provider, with optional domain verification. The Admin Portal is a hosted setup page for your customer's IT admin. You create a link for a tenant, send it to the admin, and they: 1. pick their identity provider, 2. follow the step-by-step instructions for it (the same ones as the [SSO setup guides](https://orbitid.com/docs/sso.md), with the ACS URL and entity ID for the tenant filled in), 3. paste the IdP metadata URL or XML, 4. get sent back to your app at the `redirectUrl` you chose. The connection appears under the tenant in your dashboard as soon as they finish. The admin does not need an OrbitID account. ## Prompt for your coding agent Paste this into Claude Code, Cursor or Codex in your app's repo, or follow the steps below by hand. ```text Let our customers set up SSO themselves with the OrbitID Admin Portal. Follow https://orbitid.com/docs/admin-portal.md 1. On the organization settings page, add a "Set up SSO" button for org admins. 2. On click, POST /api/v1/portal/links from the server with tenant = the organization id, tenantName = its name, redirectUrl = this settings page, and its email domains. 3. Redirect the admin to data.url. Never send ORBITID_API_KEY to the browser. 4. Show "SSO connected" once GET /api/v1/sso?tenant= returns a connection. 5. Run the tests, then list the files you changed. ``` ## Create a link In the dashboard, open **Connections** and click **Create setup link**, or call the API: ```bash curl -X POST https://app.orbitid.com/api/v1/portal/links \ -H "Authorization: Bearer orb_live_..." \ -H "Content-Type: application/json" \ -d '{ "tenant": "acme", "tenantName": "Acme Inc.", "redirectUrl": "https://yourapp.com/settings/sso", "domains": ["acme.com"] }' ``` | Field | Required | Description | | ------------------ | -------- | ------------------------------------------------------------------------------- | | `tenant` | yes | Your identifier for the customer. Use the same value when you start logins. | | `tenantName` | yes | Shown to the admin in the portal, for example the company name. | | `redirectUrl` | yes | Absolute URL the admin is sent to when they finish. | | `domains` | no | Email domains the customer must verify before the connection goes live. | | `connectionName` | no | Name of the connection that gets created. Defaults to `tenantName`. | | `fromUrl` | no | Absolute URL of the page in your app the admin came from, used for a back link. | | `expiresInMinutes` | no | How long the link is valid. | The response is `201 Created` with the link: ```json { "data": { "id": "6f1c0b2d…", "url": "https://app.orbitid.com/portal/6f1c0b2d…", "tenant": "acme", "tenantName": "Acme Inc.", "redirectUrl": "https://yourapp.com/settings/sso", "connectionName": "Acme Inc.", "domains": ["acme.com"], "verifiedDomains": [], "createdAt": 1726900000000, "expiresAt": 1727000000000 } } ``` Send `data.url` to the admin. A link is tied to one tenant and stops working after `expiresAt`; create a new one if it expires before the admin gets to it. ## Domain verification Pass `domains` when you want proof that the customer controls the email domains their users will sign in with. This protects you from a tenant claiming another company's domain. When a link has domains, the portal asks the admin to add a DNS `TXT` record for each domain. The record name and value are shown in the portal; the value has the form `orbitid-domain-verification=:`. Once the record resolves, the admin clicks **Verify** and the domain moves from `domains` to `verifiedDomains`. The connection is only activated when every domain is verified. To send the admin straight to the verification step, create the link with `POST /api/v1/portal/verify-domain` instead. It takes the same body and additionally returns `verifyDomainUrl`. ## After the admin finishes - The connection is created under the tenant, in the environment the API key belongs to. - In Production it is billed like any other connection. See [Billing](https://orbitid.com/docs/billing.md). - You can test it immediately by starting a login for the tenant as described in the [quickstart](https://orbitid.com/docs/quickstart.md#start-a-login). --- # Okta Set up a SAML 2.0 application in Okta and connect it to OrbitID. You need admin access to the Okta org. ## Step 1: Create application From your Okta account, click **Applications** from the left navigation menu. If your application is already created, choose it from the list and move to the next step. If you haven't created a SAML application, click the **Create App Integration** button to create a new application. ![Okta applications page with Create App Integration highlighted](https://orbitid.com/_next/static/immutable/media/1.2c44969l71fxy.png) Choose **SAML 2.0** from the next screen and click **Next**. ![Create a new app integration dialog with SAML 2.0 selected](https://orbitid.com/_next/static/immutable/media/2.0zqdo55qun61f.png) Give your application an **App Name** and click **Next**. ![General settings step with the app name field](https://orbitid.com/_next/static/immutable/media/3.26zeqz31blrhu.png) ## Step 2: Configure application Enter the following values in the **SAML Settings** section on the next screen: - **Single sign on URL**: `https://app.orbitid.com/api/oauth/saml`. The ACS URL shown in your OrbitID Configuration page. Sandbox uses https://app.orbitid.com/api/oauth/sandbox/saml. - **Audience URI (SP Entity ID)**: `https://saml.orbitid.com`. The SP Entity ID shown in your OrbitID Configuration page. Sandbox uses https://saml.orbitid.com/sandbox. Select **EmailAddress** from the **Name ID format** dropdown. ![SAML settings with the single sign on URL, audience URI and Name ID format](https://orbitid.com/_next/static/immutable/media/4.07fi116094c65.png) ## Step 3: Attribute mapping Under the **Attribute Statements** section, you have to configure the following attributes: | Name | Value | | --- | --- | | id | user.id | | email | user.email | | firstName | user.firstName | | lastName | user.lastName | ![Attribute statements with id, email, firstName and lastName mapped](https://orbitid.com/_next/static/immutable/media/5.2c_aehkgfckbf.png) On the next screen select **I'm an Okta customer adding an internal app** and click **Finish**. ![Feedback step with the internal app option selected](https://orbitid.com/_next/static/immutable/media/6.3a58ninnfz1wi.png) ## Step 4: Copy the IdP metadata From your application, click the **Sign On** tab and go to the section **SAML Signing Certificates**. Click the **Actions** dropdown for the correct certificate and click **View IdP metadata**. A separate window will open with the metadata XML file. Copy the URL of that window (the metadata URL) or the XML itself to your clipboard. ![Sign On tab with the View IdP metadata action](https://orbitid.com/_next/static/immutable/media/7.3a2a6uby7f9_9.png) ## Finish in OrbitID Finish in OrbitID: paste the IdP metadata URL or XML into the connection form (or the Admin Portal link). In the dashboard, open the environment, go to **Connections**, click **New connection**, choose SAML and paste the metadata URL or the XML you downloaded. If your customer's admin is following an [Admin Portal link](https://orbitid.com/docs/admin-portal.md), they paste it into the final step of the portal instead. You can also create the connection with the API: `POST /api/v1/sso` as described in the [quickstart](https://orbitid.com/docs/quickstart.md#create-a-connection). --- # Microsoft Entra ID > Set up a SAML 2.0 enterprise application in Microsoft Entra ID (Azure AD) and connect it to OrbitID. Set up a SAML 2.0 enterprise application in Microsoft Entra ID (formerly Azure Active Directory) and connect it to OrbitID. You need an Entra ID administrator account. ## Step 1: Create application From your Azure admin console, click **Enterprise applications** from the left navigation menu. ![Entra ID overview with Enterprise applications highlighted](https://orbitid.com/_next/static/immutable/media/1.2q6zim4kikrd5.png) If your application is already created, choose it from the list and move to the next step. If you haven't created a SAML application, click **New application** from the top to create a new application. ![Enterprise applications list with New application highlighted](https://orbitid.com/_next/static/immutable/media/2.0aaor2bkiff8p.png) From the next screen, click **Create your own application**. Give your application a **Name** and click **Create**. ![Create your own application panel](https://orbitid.com/_next/static/immutable/media/3.0c7pjxnq2fw1l.png) ## Step 2: Configure application Select **Single Sign On** from the **Manage** section of your app and then **SAML**. ![Single sign-on method selection with SAML highlighted](https://orbitid.com/_next/static/immutable/media/4.2mv_zy_cf15z5.png) Click **Edit** on the **Basic SAML Configuration** section. ![SAML-based sign-on page with the Basic SAML Configuration edit button](https://orbitid.com/_next/static/immutable/media/5.1exlu6myybm-7.png) Enter the following values in the **Basic SAML Configuration** section on the next screen: - **Reply URL (Assertion Consumer Service URL)**: `https://app.orbitid.com/api/oauth/saml`. The ACS URL shown in your OrbitID Configuration page. Sandbox uses https://app.orbitid.com/api/oauth/sandbox/saml. - **Identifier (Entity ID)**: `https://saml.orbitid.com`. The SP Entity ID shown in your OrbitID Configuration page. Sandbox uses https://saml.orbitid.com/sandbox. Click **Save** to save your changes. ![Basic SAML Configuration form with the identifier and reply URL](https://orbitid.com/_next/static/immutable/media/6.0pfo9kb5_6at8.png) ## Step 3: Attribute mapping Click **Edit** on the **Attributes & Claims** section. ![Attributes & Claims section with the edit button](https://orbitid.com/_next/static/immutable/media/7.3_x59cltokc9a.png) You have to configure the following attributes under the **Attributes & Claims** section: | Name | Value | | --- | --- | | `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress` | user.mail | | `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname` | user.givenname | | `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name` | user.userprincipalname | | `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname` | user.surname | ![Attributes & Claims list with the email, given name, name and surname claims](https://orbitid.com/_next/static/immutable/media/8.0n3d9pvvbcrkx.png) ## Step 4: Download the IdP metadata Go to the **SAML Signing Certificate** section and download the **Federation Metadata XML**, or copy the **App Federation Metadata Url**. ![SAML Signing Certificate section with the Federation Metadata XML download](https://orbitid.com/_next/static/immutable/media/9.1qfenmsrgtejz.png) ## Finish in OrbitID Finish in OrbitID: paste the IdP metadata URL or XML into the connection form (or the Admin Portal link). In the dashboard, open the environment, go to **Connections**, click **New connection**, choose SAML and paste the metadata URL or the XML you downloaded. If your customer's admin is following an [Admin Portal link](https://orbitid.com/docs/admin-portal.md), they paste it into the final step of the portal instead. You can also create the connection with the API: `POST /api/v1/sso` as described in the [quickstart](https://orbitid.com/docs/quickstart.md#create-a-connection). --- # Google Workspace Set up a custom SAML application in Google Workspace and connect it to OrbitID. You need a Google Workspace admin account. ## Step 1: Create application From your Google Admin console, click **Apps** from the sidebar then click **Web and mobile apps** from the list. If your application is already created, choose it from the list and move to the next step. If you haven't created a SAML application, click **Add custom SAML app** from the **Add app** menu. ![Web and mobile apps page with Add custom SAML app highlighted](https://orbitid.com/_next/static/immutable/media/1.0kh14likby4l-.png) Give your application an **App name** and click **Continue**. ![App details step with the app name field](https://orbitid.com/_next/static/immutable/media/2.3m1xe4n_cj-p2.png) ## Step 2: Configure application From the next screen, click **DOWNLOAD METADATA** to download the metadata XML file, then click **Continue**. You will paste this file into OrbitID at the end. ![Google Identity Provider details with the download metadata button](https://orbitid.com/_next/static/immutable/media/3.0iq6cou6awlfc.png) Enter the following values in the **Service provider details** section: - **ACS URL**: `https://app.orbitid.com/api/oauth/saml`. The ACS URL shown in your OrbitID Configuration page. Sandbox uses https://app.orbitid.com/api/oauth/sandbox/saml. - **Entity ID**: `https://saml.orbitid.com`. The SP Entity ID shown in your OrbitID Configuration page. Sandbox uses https://saml.orbitid.com/sandbox. Leave **Name ID format** as **UNSPECIFIED** and **Name ID** as **Basic Information > Primary email**, then click **Continue**. ![Service provider details with the ACS URL and entity ID](https://orbitid.com/_next/static/immutable/media/4.005zw590g6su0.png) ## Step 3: Attribute mapping Under the **Attributes** section, you have to configure the following attributes: | App attributes | Google directory attributes | | --- | --- | | email | Primary email | | firstName | First name | | lastName | Last name | After you have configured the attributes, click **Finish** to save the configuration. ![Attribute mapping with email, firstName and lastName](https://orbitid.com/_next/static/immutable/media/5.2zg8ol4qdogjp.png) From the next screen, click **User access** to configure the application to allow users to log in. ![App overview with the User access card](https://orbitid.com/_next/static/immutable/media/6.2jdfzk4x_44m1.png) Check the **ON for everyone** option and click **Save**. ![Service status set to ON for everyone](https://orbitid.com/_next/static/immutable/media/7.1q6tk6fn_xibo.png) ## Step 4: Use the IdP metadata Use the metadata XML file you downloaded in **Configure application**. ## Finish in OrbitID Finish in OrbitID: paste the IdP metadata URL or XML into the connection form (or the Admin Portal link). In the dashboard, open the environment, go to **Connections**, click **New connection**, choose SAML and paste the metadata URL or the XML you downloaded. If your customer's admin is following an [Admin Portal link](https://orbitid.com/docs/admin-portal.md), they paste it into the final step of the portal instead. You can also create the connection with the API: `POST /api/v1/sso` as described in the [quickstart](https://orbitid.com/docs/quickstart.md#create-a-connection). --- # Auth0 > Enable the SAML2 Web App addon on an Auth0 application and connect it to OrbitID. Use Auth0 as a SAML identity provider for OrbitID by enabling the SAML2 Web App addon on an Auth0 application. You need access to the Auth0 dashboard. ## Step 1: Create application From your Auth0 dashboard, click **Applications** from the left navigation menu. If your application is already created, choose it from the list and move to the next step. ![Auth0 applications list](https://orbitid.com/_next/static/immutable/media/1.0586dmekxjd3j.png) If you haven't created a SAML application, click the **Create Application** button to create a new application. Give your application a **Name** and click **Create**. ![Create application dialog with the name field](https://orbitid.com/_next/static/immutable/media/5.2d0am7c88v9q4.png) ## Step 2: Configure application Click the tab **Addons** and enable the **SAML2 WEB APP** addon. ![Addons tab with SAML2 Web App](https://orbitid.com/_next/static/immutable/media/2.3olof40_o5d-z.png) Enter your **Application Callback URL** on the next screen and click **Enable**. - **Application Callback URL**: `https://app.orbitid.com/api/oauth/saml`. The ACS URL shown in your OrbitID Configuration page. Sandbox uses https://app.orbitid.com/api/oauth/sandbox/saml. ![SAML2 Web App addon settings with the application callback URL](https://orbitid.com/_next/static/immutable/media/3.0q1pe07jsuhz5.png) In the addon **Settings**, set `"audience"` to the SP Entity ID below and click **Save**. Without it, sign-ins that start from Auth0 carry an audience OrbitID rejects. - **Audience (SP Entity ID)**: `https://saml.orbitid.com`. The SP Entity ID shown in your OrbitID Configuration page. Sandbox uses https://saml.orbitid.com/sandbox. Auth0 sends `email`, `given_name` and `family_name` claims by default, which OrbitID maps to `email`, `firstName` and `lastName`; no extra attribute mapping is needed. ## Step 3: Download the IdP metadata Click the tab **Usage** and download the **Identity Provider Metadata**, or copy its URL. ![Usage tab with the identity provider metadata download link](https://orbitid.com/_next/static/immutable/media/4.2txkwmqibz9s_.png) ## Finish in OrbitID Finish in OrbitID: paste the IdP metadata URL or XML into the connection form (or the Admin Portal link). In the dashboard, open the environment, go to **Connections**, click **New connection**, choose SAML and paste the metadata URL or the XML you downloaded. If your customer's admin is following an [Admin Portal link](https://orbitid.com/docs/admin-portal.md), they paste it into the final step of the portal instead. You can also create the connection with the API: `POST /api/v1/sso` as described in the [quickstart](https://orbitid.com/docs/quickstart.md#create-a-connection). --- # OneLogin > Set up a SAML Custom Connector (Advanced) application in OneLogin and connect it to OrbitID. Set up a SAML application in OneLogin and connect it to OrbitID. You need a OneLogin administrator account. ## Step 1: Create application From your OneLogin account, click **Applications** from the top navigation menu. If your application is already created, choose it from the list and move to the next step. If you haven't created a SAML application, click the **Add App** button to create a new application. Search for **SAML Custom Connector** in the **Find Applications** section. Select **SAML Custom Connector (Advanced)** from the search results. Give your application a **Display Name** and click **Save**. ## Step 2: Configure application From your application, click the **Configuration** tab on the left to configure the application. You have to enter the following values in the **Application details** section: - **Audience (Entity ID)**: `https://saml.orbitid.com`. The SP Entity ID shown in your OrbitID Configuration page. Sandbox uses https://saml.orbitid.com/sandbox. - **ACS (Consumer) URL Validator**: `https://app.orbitid.com/api/oauth/saml`. The ACS URL shown in your OrbitID Configuration page. Sandbox uses https://app.orbitid.com/api/oauth/sandbox/saml. - **ACS (Consumer) URL**: `https://app.orbitid.com/api/oauth/saml`. The ACS URL shown in your OrbitID Configuration page. Sandbox uses https://app.orbitid.com/api/oauth/sandbox/saml. Select **Service Provider** from the **SAML initiator** dropdown. Click **Save** to save the configuration. ## Step 3: Attribute mapping From your application, click the **Parameters** tab on the left. You have to configure the following attributes: | SAML Custom Connector Field | Value | | --- | --- | | id | UUID | | email | Email | | firstName | First Name | | lastName | Last Name | To add the **id** attribute, click the plus button, enter **id** in the **Field name** input and check the **Include in SAML assertion** checkbox. Click **Save** to continue. On the next screen, select **UUID** from the **Value** dropdown and click **Save**. Do the same for the other attributes (email, firstName, lastName). ## Step 4: Download the IdP metadata Click the dropdown menu **More Actions** from the top right corner and click **SAML Metadata** to download the metadata XML file. ## Finish in OrbitID Finish in OrbitID: paste the IdP metadata URL or XML into the connection form (or the Admin Portal link). In the dashboard, open the environment, go to **Connections**, click **New connection**, choose SAML and paste the metadata URL or the XML you downloaded. If your customer's admin is following an [Admin Portal link](https://orbitid.com/docs/admin-portal.md), they paste it into the final step of the portal instead. You can also create the connection with the API: `POST /api/v1/sso` as described in the [quickstart](https://orbitid.com/docs/quickstart.md#create-a-connection). --- # JumpCloud Set up a custom SAML application in JumpCloud and connect it to OrbitID. You need a JumpCloud administrator account. ## Step 1: Create application From your JumpCloud Admin console, click **SSO** from the left navigation menu. If your application is already created, choose it from the list and move to the next step. If you haven't created a SAML application, click the plus icon and then **Custom SAML App** to create a new application. Give your application a **Display Label**. ## Step 2: Configure application Next click on the **SSO** tab and enter the following values: - **IdP Entity ID**: `https://saml.orbitid.com/`. The IdP Entity ID for this organization, shown when you connect JumpCloud for it in the OrbitID dashboard. - **SP Entity ID**: `https://saml.orbitid.com`. The SP Entity ID shown in your OrbitID Configuration page. Sandbox uses https://saml.orbitid.com/sandbox. - **ACS URL**: `https://app.orbitid.com/api/oauth/saml`. The ACS URL shown in your OrbitID Configuration page. Sandbox uses https://app.orbitid.com/api/oauth/sandbox/saml. ## Step 3: Attribute mapping Under the **Attributes** section, you have to configure the following attributes: | Service Provider Attribute Name | JumpCloud Attribute Name | | --- | --- | | email | email | | firstName | firstname | | lastName | lastname | Make sure you have checked the **Declare Redirect Endpoint** checkbox. Finally, click **Activate** to save the application configuration. ## Step 4: Download the IdP metadata Now go back to the SAML app you just created, click the tab **SSO**, and click the button **Export Metadata** to download the metadata XML file. ## Finish in OrbitID Finish in OrbitID: paste the IdP metadata URL or XML into the connection form (or the Admin Portal link). In the dashboard, open the environment, go to **Connections**, click **New connection**, choose SAML and paste the metadata URL or the XML you downloaded. If your customer's admin is following an [Admin Portal link](https://orbitid.com/docs/admin-portal.md), they paste it into the final step of the portal instead. You can also create the connection with the API: `POST /api/v1/sso` as described in the [quickstart](https://orbitid.com/docs/quickstart.md#create-a-connection). --- # PingOne Set up a SAML application in PingOne and connect it to OrbitID. You need a PingOne administrator account. ## Step 1: Create application From your PingOne account, click **Connections** > **Applications** from the left navigation menu. If your application is already created, choose it from the list and move to the next step. If you haven't created a SAML application, click the plus button to create a new application. Give your application an **Application Name**, choose **SAML Application** from the **Application Type** and click **Configure**. ## Step 2: Configure application From the next screen, you have to enter the following values in the **SAML Configuration** section: - **ACS URLs**: `https://app.orbitid.com/api/oauth/saml`. The ACS URL shown in your OrbitID Configuration page. Sandbox uses https://app.orbitid.com/api/oauth/sandbox/saml. - **Entity ID**: `https://saml.orbitid.com`. The SP Entity ID shown in your OrbitID Configuration page. Sandbox uses https://saml.orbitid.com/sandbox. Click **Save** to save the configuration. ## Step 3: Attribute mapping Click the **Attribute Mappings** tab from the top and configure the following attributes: | SAML App | PingOne | | --- | --- | | id | User ID | | email | Email Address | | firstName | Given Name | | lastName | Family Name | Make sure you have enabled your app so that it can be used by the users. You can do this by clicking the **Toggle** button next to your app. ## Step 4: Download the IdP metadata Click the **Configuration** tab from the top and click **Download Metadata** to download the metadata XML file. The same tab shows the **IDP Metadata URL**, which you can use instead of the file. ## Finish in OrbitID Finish in OrbitID: paste the IdP metadata URL or XML into the connection form (or the Admin Portal link). In the dashboard, open the environment, go to **Connections**, click **New connection**, choose SAML and paste the metadata URL or the XML you downloaded. If your customer's admin is following an [Admin Portal link](https://orbitid.com/docs/admin-portal.md), they paste it into the final step of the portal instead. You can also create the connection with the API: `POST /api/v1/sso` as described in the [quickstart](https://orbitid.com/docs/quickstart.md#create-a-connection). --- # Rippling Create a custom SAML app in Rippling and connect it to OrbitID. You need a Rippling administrator account. ## Step 1: Create application You'll need to create a new **Custom App** from your Rippling account if the app is not already in the Rippling app directory. Go to **IT Management** > **Custom App** from the left navigation menu. Click the **Create New App** button to create a new application. From the next screen, fill in the following fields: - **App Name** - **Select Categories** - **Upload Logo** - **What type of app would you like to create?** – make sure you select **Single Sign-On (SAML)** from the list. ## Step 2: Configure application Copy the **IdP Metadata URL** or **IdP Metadata XML** from the next screen. You'll need this value to finish the connection in OrbitID. You'll need to enter the **ACS URL** and **Service Provider Entity ID**: - **ACS URL**: `https://app.orbitid.com/api/oauth/saml`. The ACS URL shown in your OrbitID Configuration page. Sandbox uses https://app.orbitid.com/api/oauth/sandbox/saml. - **Service Provider Entity ID**: `https://saml.orbitid.com`. The SP Entity ID shown in your OrbitID Configuration page. Sandbox uses https://saml.orbitid.com/sandbox. From the **Settings** tab of the custom app you just created, go to the **Advanced SAML Settings** section and check the box for **Disable InResponseTo field in assertions for IdP initiated SSO**. This is because Rippling sends dummy values for the **InResponseTo** field and OrbitID validates the **InResponseTo** field when it is present. Rippling sends the user's email and name attributes by default; OrbitID maps them to `email`, `firstName` and `lastName`. ## Step 3: Use the IdP metadata Use the **IdP Metadata URL** or **IdP Metadata XML** you copied in **Configure application**. ## Finish in OrbitID Finish in OrbitID: paste the IdP metadata URL or XML into the connection form (or the Admin Portal link). In the dashboard, open the environment, go to **Connections**, click **New connection**, choose SAML and paste the metadata URL or the XML you downloaded. If your customer's admin is following an [Admin Portal link](https://orbitid.com/docs/admin-portal.md), they paste it into the final step of the portal instead. You can also create the connection with the API: `POST /api/v1/sso` as described in the [quickstart](https://orbitid.com/docs/quickstart.md#create-a-connection). --- # Microsoft AD FS > Create a claims-aware relying party trust in Microsoft AD FS and connect it to OrbitID. Connect an on-premises Microsoft Active Directory Federation Services (AD FS) server to OrbitID as a SAML identity provider. You need administrator access to the AD FS server. ## Step 1: Create a claims-aware Relying Party Trust using federation metadata In AD FS, a relying party (RP) trust needs to be set up. You can supply OrbitID's SP metadata URL and let AD FS pick up the configuration automatically. - **Federation metadata URL**: `https://app.orbitid.com/.well-known/sp-metadata`. The OrbitID SP metadata URL. For Sandbox, copy it from your Sandbox Configuration page. The public certificate is needed for signature verification. You can download the certificate from the following URL: - **Public certificate**: `https://app.orbitid.com/.well-known/saml.cer`. The OrbitID public signing certificate. In **Server Manager**, click **Tools**, and then select **AD FS Management**. Under **Actions**, click **Add Relying Party Trust**. On the Welcome page, choose **Claims aware** and click **Start**. On the **Select Data Source** page, click **Import data about the relying party published online or on a local network**. In **Federation metadata address (host name or URL)**, type the federation metadata URL above, and then click **Next**. On the **Specify Display Name** page type a name in **Display name**, under **Notes** type a description for this relying party trust, and then click **Next**. On the **Choose Issuance Authorization Rules** page, select either **Permit all users to access this relying party** or **Deny all users access to this relying party**, and then click **Next**. On the **Ready to Add Trust** page, review the settings, and then click **Next** to save your relying party trust information. On the **Finish** page, click **Close**. This action automatically displays the **Edit Claim Rules** dialog box. ## Step 2: Attribute mapping On the **Configure Claim Rule** screen, enter a **Claim Rule Name** of your choice, select **Active Directory** as the **Attribute Store**, then add the following mapping: | LDAP Attribute | Outgoing Claim Type | | --- | --- | | E-Mail-Addresses | E-Mail Address | | Given-Name | Given Name | | Surname | Surname | | User-Principal-Name | Name ID | ## Step 3: Transform rule Create a transform rule mapping the incoming **E-Mail Address** to the outgoing **Name ID** (of type **Email**). AD FS by default sends **Name ID** as **Unspecified**, which results in an **InvalidNameIDPolicy** error if this step is missed. If you'd rather use the claim rule language, the following rule can be applied: ```text c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"] => issue(Type = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer, Value = c.Value, ValueType = c.ValueType, Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/format"] = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"); ``` Finally open Windows PowerShell as an administrator, then run the following command so that both the response and the assertion are signed: ```powershell Set-ADFSRelyingPartyTrust -TargetName -SamlResponseSignature "MessageAndAssertion" ``` ## Step 4: Copy the IdP metadata AD FS publishes its metadata at `https:///FederationMetadata/2007-06/FederationMetadata.xml`. Use that URL, or download the file, when you finish the connection in OrbitID. ## Finish in OrbitID Finish in OrbitID: paste the IdP metadata URL or XML into the connection form (or the Admin Portal link). In the dashboard, open the environment, go to **Connections**, click **New connection**, choose SAML and paste the metadata URL or the XML you downloaded. If your customer's admin is following an [Admin Portal link](https://orbitid.com/docs/admin-portal.md), they paste it into the final step of the portal instead. You can also create the connection with the API: `POST /api/v1/sso` as described in the [quickstart](https://orbitid.com/docs/quickstart.md#create-a-connection). --- # Generic SAML > Connect any SAML 2.0 identity provider to OrbitID: service provider values, signing settings and attribute mapping. Use this guide for any SAML 2.0 identity provider that does not have its own guide. ## Step 1: Configure the SAML application Your Identity Provider (IdP) will ask for the following information while configuring the SAML application. Please do not add a trailing slash at the end of the URLs. Create them exactly as shown below: - **Reply URL (Assertion Consumer Service URL)**: `https://app.orbitid.com/api/oauth/saml`. The ACS URL shown in your OrbitID Configuration page. Sandbox uses https://app.orbitid.com/api/oauth/sandbox/saml. - **Identifier (Entity ID)**: `https://saml.orbitid.com`. The SP Entity ID shown in your OrbitID Configuration page. Sandbox uses https://saml.orbitid.com/sandbox. Use these signing settings: - Response: `Signed` - Assertion Signature: `Signed` - Signature Algorithm: `RSA-SHA256` - Assertion Encryption: `Unencrypted` OrbitID exposes the same values as SP metadata at `https://app.orbitid.com/.well-known/sp-metadata`; many identity providers can import it directly. The signing certificate is at `https://app.orbitid.com/.well-known/saml.cer`. ## Step 2: SAML profile, claims and attribute mapping OrbitID reads four attributes from the SAML assertion: - **id** - **email** - **firstName** - **lastName** This is how the common SAML attributes map over for most providers, but some providers have custom mappings. Please refer to the documentation of the identity provider to understand the exact mapping. | SAML Attribute | OrbitID mapping | | --- | --- | | `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier` | id | | `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress` | email | | `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname` | firstName | | `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname` | lastName | Plain attribute names (`id`, `email`, `firstName`, `lastName`) work as well. ## Step 3: Copy the IdP metadata Download the IdP metadata XML from your identity provider, or copy its metadata URL. ## Finish in OrbitID Finish in OrbitID: paste the IdP metadata URL or XML into the connection form (or the Admin Portal link). In the dashboard, open the environment, go to **Connections**, click **New connection**, choose SAML and paste the metadata URL or the XML you downloaded. If your customer's admin is following an [Admin Portal link](https://orbitid.com/docs/admin-portal.md), they paste it into the final step of the portal instead. You can also create the connection with the API: `POST /api/v1/sso` as described in the [quickstart](https://orbitid.com/docs/quickstart.md#create-a-connection). --- # Generic OIDC > Connect any OpenID Connect identity provider to OrbitID: callback URL, client ID and client secret. Use this guide for any OpenID Connect identity provider. ## Step 1: Create application Register a new application (sometimes called a client or an app registration) in your identity provider and set its redirect or callback URL: - **Callback URL**: `https://app.orbitid.com/api/oauth/oidc`. The OIDC callback URL shown in your OrbitID Configuration page. Since OrbitID acts as a proxy between your app and the OIDC identity provider, the application or client registered here is OrbitID. ## Step 2: Scopes and claims Make sure the application can request the `openid`, `email` and `profile` scopes. OrbitID maps the `sub`, `email`, `given_name` and `family_name` claims to `id`, `email`, `firstName` and `lastName`. ## Step 3: Copy the client details **Client / Application ID** The OIDC identity provider normally generates a unique identifier for the registered app. Make a note of this to be used later when creating the SSO connection in OrbitID. **Client Secret** Along with the Client ID, the IdP also generates a client secret which is used to authenticate the client while issuing tokens. Make a note of this to be used later when creating the SSO connection in OrbitID. **Discovery URL** Most providers publish an OpenID Connect discovery document at `https:///.well-known/openid-configuration`. OrbitID uses it to find the authorization, token, userinfo and JWKS endpoints, so note the URL as well. ## Finish in OrbitID Finish in OrbitID: paste the Client ID, Client Secret and discovery URL into the connection form (or the Admin Portal link). In the dashboard, open the environment, go to **Connections**, click **New connection** and choose OIDC. If your customer's admin is following an [Admin Portal link](https://orbitid.com/docs/admin-portal.md), they enter the values in the final step of the portal instead. You can also create the connection with the API: `POST /api/v1/sso` as described in the [quickstart](https://orbitid.com/docs/quickstart.md#create-a-connection). --- # Directory Sync > Sync users and groups from your customers’ directories into your app with SCIM 2.0 or Google Workspace, and receive webhook events. Directory Sync keeps your app's users and groups in step with your customer's directory. When their IT admin adds, updates or removes someone, OrbitID receives the change and forwards it to you as a [webhook](https://orbitid.com/docs/webhooks.md). You can also query the synced users and groups with the API. ## Prompt for your coding agent Paste this into Claude Code, Cursor or Codex in your app's repo, or follow the steps below by hand. ```text Sync our customers' directories into this app with OrbitID. Follow https://orbitid.com/docs/directory-sync.md 1. Add POST /webhooks/orbitid and verify OrbitID-Signature with ORBITID_WEBHOOK_SECRET. 2. Map each event's tenant to our organization. Create users on user.created, update them on user.updated, deactivate them on user.deleted or active: false. Never hard-delete. 3. If this app has teams or roles, mirror groups and memberships from the group.* events. 4. Make every handler idempotent and return 200 fast; the body can be an array of events. 5. Run the tests, then list what you changed and which events you ignore. ``` ## Supported directories | Directory | How it connects | | ------------------------------------------------ | ---------------------------------------------- | | [Okta](https://orbitid.com/docs/directory-sync/okta.md) | SCIM 2.0 | | [Microsoft Entra ID](https://orbitid.com/docs/directory-sync/azure.md) | SCIM 2.0 | | OneLogin | SCIM 2.0 | | JumpCloud | SCIM 2.0 | | Any SCIM 2.0 directory | SCIM 2.0 | | [Google Workspace](https://orbitid.com/docs/directory-sync/google.md) | OAuth (OrbitID polls the Google Directory API) | ## Create a directory In the dashboard open the environment, go to **Directory Sync** and click **New directory**. Choose the provider, enter the tenant it belongs to and, optionally, a webhook URL and secret. For SCIM providers the dashboard then shows: - the **SCIM endpoint**: `https://app.orbitid.com/api/scim/v2.0/` - a **bearer token** that the directory uses to authenticate. It is shown once, so copy it into the identity provider straight away. Give both values to your customer's IT admin, or follow the provider guide together. For Google Workspace there is no SCIM endpoint: click **Connect** and sign in with a Google Workspace admin account instead. One directory counts as one connection for [billing](https://orbitid.com/docs/billing.md). ## Events OrbitID emits these events as the directory changes: | Event | When | | -------------------- | ------------------------------------------------------------------ | | `user.created` | A user was provisioned | | `user.updated` | A user's attributes changed, including activation and deactivation | | `user.deleted` | A user was removed | | `group.created` | A group was pushed | | `group.updated` | A group was renamed or changed | | `group.deleted` | A group was removed | | `group.user_added` | A user was added to a group | | `group.user_removed` | A user was removed from a group | Each event is delivered to the directory's webhook, signed with the directory's secret in the `OrbitID-Signature` header. Payloads and verification are described in [Webhooks](https://orbitid.com/docs/webhooks.md). Turn on **Log webhook events** on the directory to see every delivery and its response in the dashboard. ## Query synced data Use an [API key](https://orbitid.com/docs/api-keys.md) to read what has been synced: ```bash curl "https://app.orbitid.com/api/v1/dsync/users?tenant=acme&directoryId=" \ -H "Authorization: Bearer orb_live_..." ``` - `GET /api/v1/dsync` – list directories; `GET /api/v1/dsync/` – one directory. - `GET /api/v1/dsync/users` and `GET /api/v1/dsync/users/` – synced users. - `GET /api/v1/dsync/groups`, `GET /api/v1/dsync/groups/` and `.../members` – synced groups. - `GET /api/v1/dsync/events` and `GET /api/v1/dsync/events/` – webhook event log. --- # Webhooks > Receive Directory Sync user and group events on your endpoint and verify the OrbitID-Signature header. Every [directory](https://orbitid.com/docs/directory-sync.md) can have a webhook. OrbitID sends an HTTP `POST` to it whenever a user or group changes in your customer's directory. ## Prompt for your coding agent Paste this into Claude Code, Cursor or Codex in your app's repo, or follow the steps below by hand. ```text Add a verified OrbitID webhook endpoint to this app. Follow https://orbitid.com/docs/webhooks.md 1. Add POST /webhooks/orbitid and read the raw body before any JSON parsing. 2. Verify OrbitID-Signature (t=…,s=…): HMAC-SHA256 of "." with ORBITID_WEBHOOK_SECRET, compared in constant time. Reject timestamps older than 5 minutes. 3. Accept one event or an array, queue each one, and return 200 straight away. 4. Add a test with a signed sample payload and one with a bad signature. 5. Run the tests, then list the files you changed. ``` ## Configure Set the **Webhook URL** and **Webhook secret** when you create the directory, or later from the directory's settings. Use a different secret per directory if you want to tell them apart; the secret is never sent, only used to sign requests. Turn on **Log webhook events** to keep a record of every delivery, with the payload and your endpoint's response, in the dashboard and at `GET /api/v1/dsync/events`. ## Events | Event | `data` | | ------------------------------------------------- | ------------------------------------------- | | `user.created`, `user.updated`, `user.deleted` | The user | | `group.created`, `group.updated`, `group.deleted` | The group | | `group.user_added`, `group.user_removed` | The user, with the group under `data.group` | ## Payload ```json { "event": "user.created", "tenant": "acme", "product": "", "directory_id": "58b5cd9dfaa39d47eb8f5f88631f9a629a232016", "data": { "id": "00u1abc…", "first_name": "Jane", "last_name": "Doe", "email": "jane@acme.com", "active": true, "raw": { "…": "the SCIM resource as the directory sent it" } } } ``` Group events carry `{ "id", "name", "raw" }` in `data`; membership events carry the user plus a `group` object with the same shape. When several changes arrive at once, the body may be a JSON array of events instead of a single object. ## Verify the signature Each request has an `OrbitID-Signature` header of the form `t=,s=`. The signature is an HMAC-SHA256 of `.` using the webhook secret, hex encoded. Verify it before you trust the payload: ```ts import crypto from 'node:crypto' export const verifyWebhook = ( header: string, rawBody: string, secret: string ) => { const parts = Object.fromEntries( header.split(',').map((part) => part.split('=')) ) const expected = crypto .createHmac('sha256', secret) .update(`${parts.t}.${rawBody}`) .digest('hex') return ( expected.length === parts.s.length && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.s)) ) } ``` Use the raw request body, not a re-serialised version of it. Reject requests whose timestamp is older than a few minutes to protect against replay. ## Respond Return a `2xx` status quickly and process the event asynchronously. Events are delivered in the order they happen; treat them as idempotent, since the same change can be sent again if your endpoint fails. --- # Okta Directory Sync > Provision users and groups from Okta into OrbitID with SCIM 2.0. Connect an Okta directory to OrbitID with SCIM 2.0. You need an Okta admin account, and the **SCIM endpoint** and **bearer token** from the directory you created in OrbitID (see [Directory Sync](https://orbitid.com/docs/directory-sync.md#create-a-directory)). ## Step 1: Create application In the Okta admin console open **Applications → Applications** and click **Browse App Catalog**. ![Okta applications page with Browse App Catalog highlighted](https://orbitid.com/docs/dsync/okta/1.png) Search for **SCIM 2.0 Test App (OAuth Bearer Token)** and open it. ![Searching the app catalog for SCIM 2.0 Test App (OAuth Bearer Token)](https://orbitid.com/docs/dsync/okta/2.png) Click **Add Integration**. ![The SCIM 2.0 Test App catalog page with Add Integration highlighted](https://orbitid.com/docs/dsync/okta/3.png) Give it an **Application label** your admins will recognise, click **Next**, leave the sign-on options as they are and click **Done**. ![General settings step with the application label and Next button highlighted](https://orbitid.com/docs/dsync/okta/4.png) ## Step 2: Configure provisioning Open the **Provisioning** tab and click **Configure API Integration**. ![Provisioning tab with Configure API Integration highlighted](https://orbitid.com/docs/dsync/okta/5.png) Check **Enable API integration** and enter: - **SCIM 2.0 Base Url**: the SCIM endpoint from OrbitID, `https://app.orbitid.com/api/scim/v2.0/` - **OAuth Bearer Token**: the bearer token from OrbitID Click **Test API Credentials**, then **Save**. ![API integration form with the base URL, bearer token, test and save controls highlighted](https://orbitid.com/docs/dsync/okta/6.png) Under **Provisioning → To App**, click **Edit** and enable **Create Users**, **Update User Attributes** and **Deactivate Users**, then save. ![Provisioning to App settings with Create Users, Update User Attributes and Deactivate Users enabled](https://orbitid.com/docs/dsync/okta/7.png) ## Step 3: Assign users and groups Open the **Assignments** tab, click **Assign** and choose **Assign to People** or **Assign to Groups**. ![Assignments tab with the Assign dropdown open](https://orbitid.com/docs/dsync/okta/8.png) Pick the people or groups that should be provisioned and click **Assign**. ![Assign to People dialog with a user selected](https://orbitid.com/docs/dsync/okta/9.png) Review the attributes, click **Save and Go Back**, then **Done**. Okta provisions each assigned user and OrbitID emits a `user.created` event. ![Attribute review with Save and Go Back highlighted](https://orbitid.com/docs/dsync/okta/10.png) To sync group memberships, open the **Push Groups** tab, click **Push Groups** and choose **Find groups by name**. ![Push Groups tab with Find groups by name highlighted](https://orbitid.com/docs/dsync/okta/11.png) Type the group name, keep **Push group memberships immediately** checked and click **Save**. OrbitID emits `group.created` and `group.user_added` events for the group and its members. ![Push groups by name with a group entered and Save highlighted](https://orbitid.com/docs/dsync/okta/12.png) Assigning a group under **Assignments** provisions its members as users; pushing it under **Push Groups** also creates the group itself in OrbitID. Do both if you want group memberships in your app. --- # Microsoft Entra ID Directory Sync > Provision users and groups from Microsoft Entra ID (Azure AD) into OrbitID with SCIM 2.0. Connect a Microsoft Entra ID (formerly Azure Active Directory) tenant to OrbitID with SCIM 2.0. You need an Entra ID administrator account, and the **SCIM endpoint** and **bearer token** from the directory you created in OrbitID (see [Directory Sync](https://orbitid.com/docs/directory-sync.md#create-a-directory)). ## Step 1: Create application In the Azure portal open **Microsoft Entra ID** (shown as **Azure Active Directory** in older portals). ![Azure portal home with Azure Active Directory highlighted](https://orbitid.com/docs/dsync/azure/1.png) Click **Enterprise applications** in the left menu. ![Entra ID overview with Enterprise applications highlighted](https://orbitid.com/docs/dsync/azure/2.png) Click **New application**. ![Enterprise applications list with New application highlighted](https://orbitid.com/docs/dsync/azure/3.png) Click **Create your own application**, enter a name, select **Integrate any other application you don't find in the gallery (Non-gallery)** and click **Create**. ![Create your own application panel with the name, non-gallery option and Create button highlighted](https://orbitid.com/docs/dsync/azure/4.png) ## Step 2: Configure provisioning In the new application open **Provisioning** and click **Get started**. ![Provisioning page with Get started highlighted](https://orbitid.com/docs/dsync/azure/5.png) Set **Provisioning Mode** to **Automatic**. Under **Admin Credentials** enter: - **Tenant URL**: the SCIM endpoint from OrbitID. For Entra ID it ends with `?aadOptscim062020`, which makes Entra send standards-compliant SCIM PATCH requests; paste it exactly as shown. - **Secret Token**: the bearer token from OrbitID Click **Test Connection**, then **Save**. ![Provisioning settings with Automatic mode and the admin credentials highlighted](https://orbitid.com/docs/dsync/azure/6.png) Expand **Mappings** and make sure both **Provision Azure Active Directory Users** and **Provision Azure Active Directory Groups** are enabled. Then switch **Provisioning Status** to **On** and save. ![Mappings section with user and group provisioning enabled and the provisioning status toggle](https://orbitid.com/docs/dsync/azure/7.png) Entra ID runs an initial cycle within a few minutes and then syncs changes roughly every 40 minutes. ## Step 3: Assign users and groups Open **Users and groups** and click **Add user/group**. ![Users and groups page with Add user/group highlighted](https://orbitid.com/docs/dsync/azure/8.png) Select the users or groups that should be provisioned, click **Select**, then **Assign**. OrbitID emits `user.created` events as they are provisioned, and `group.created` and `group.user_added` events for assigned groups. ![Add Assignment panel with a user selected and the Assign button highlighted](https://orbitid.com/docs/dsync/azure/9.png) Assigning groups requires an Entra ID P1 or P2 licence; on the free tier you can only assign individual users. --- # Google Workspace Directory Sync > Sync users and groups from Google Workspace into OrbitID by connecting a Google admin account with read-only access. Google Workspace does not provide SCIM, so OrbitID connects to the Google Directory API instead and polls it for changes. Setup takes a minute and needs a Google Workspace **super admin** account. ## Step 1: Create the directory In the OrbitID dashboard open the environment, go to **Directory Sync**, click **New directory** and choose **Google Workspace** as the provider. Enter the tenant it belongs to and, optionally, a webhook URL and secret, then save. ## Step 2: Connect Google Open the directory's settings and click **Connect**. You are sent to Google's consent screen. Sign in with a Google Workspace super admin of the customer's domain and grant the requested access. OrbitID asks for read-only scopes only: - `admin.directory.user.readonly` - `admin.directory.group.readonly` - `admin.directory.group.member.readonly` After you accept, Google sends you back to OrbitID and the directory shows as connected. If your customer's admin should authorise instead of you, send them the directory's authorization link from the same settings page. ## Step 3: Wait for the first sync OrbitID imports all users and groups on the first run and emits `user.created`, `group.created` and `group.user_added` events for them. After that it polls Google on a schedule and emits `user.updated`, `user.deleted`, `group.updated`, `group.deleted` and `group.user_removed` events as the directory changes. See [Webhooks](https://orbitid.com/docs/webhooks.md) for payloads. ## Disconnect Deactivate or delete the directory in OrbitID to stop syncing. The customer can also revoke OrbitID's access from their Google Admin console under **Security → API controls**.