> ## Documentation Index
> Fetch the complete documentation index at: https://docs.knoxcall.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SAML SSO with Okta

> Connect Okta to KnoxCall over SAML 2.0 — the SAML app integration, attribute and group statements, assertion encryption, Single Logout and certificate rotation, with the exact values to paste.

# SAML SSO with Okta

Okta's **SAML 2.0 app integration** is the object that does this. There is no KnoxCall entry in the Okta Integration Network, so you create your own — which is fine, because everything KnoxCall needs is four URLs and a certificate.

**Before you start**

* KnoxCall: an **Enterprise** plan, the **owner or admin** role, and at least one [domain verified for single sign-on](/sso/domains) — a domain you verified for *sending mail* is a different proof and does not admit a login.
* Okta: an administrator who can create app integrations (Super Admin, or Application Administrator).

<Warning>
  **Configured KnoxCall before 8 September 2026?** Re-upload our SP metadata, or re-enter the values below, before you go further. KnoxCall now **signs AuthnRequests** (RSA-SHA256), publishes an **encryption** key, and publishes a **Single Logout** endpoint. An Okta app built from the older document has no signature certificate on file for us, cannot offer **Encrypted assertion**, and has no SLO endpoint of ours to call. None of that is visible from KnoxCall's side. See [the call-out on the overview page](/sso/overview) for the whole story.
</Warning>

## 1. Create the app integration

**Applications → Applications → Create App Integration → SAML 2.0 → Next.**

Name it (for example `KnoxCall`), optionally add a logo, and continue to **Configure SAML**.

## 2. Configure SAML

Replace `acme` with your workspace slug throughout. The authoritative copy of every value below is your own metadata document at `https://acme.knoxcall.com/saml/acme/metadata` — it is public, so fetch it in a browser and read the values off it.

| Okta field                                         | Value                                                                                                                                                    |
| -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Single sign-on URL**                             | `https://acme.knoxcall.com/saml/acme/acs`                                                                                                                |
| **Use this for Recipient URL and Destination URL** | checked                                                                                                                                                  |
| **Audience URI (SP Entity ID)**                    | `https://acme.knoxcall.com/saml/acme/metadata`                                                                                                           |
| **Default RelayState**                             | leave empty                                                                                                                                              |
| **Name ID format**                                 | the email-address format — KnoxCall's sign-in request names `urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress`, and Okta requires the two to match |
| **Application username**                           | **Custom**, with the expression `user.getInternalProperty("id")` — the Okta user ID, a stable identifier                                                 |
| **Response** / **Assertion Signature**             | Signed                                                                                                                                                   |
| **Signature Algorithm**                            | `RSA-SHA256`                                                                                                                                             |

KnoxCall's SP entity ID *is* its metadata URL. That is deliberate and it is what the metadata document says; do not shorten it to the origin.

**Why the application username is the Okta user ID, not the email.** The application username is what Okta puts in the NameID (its SAML field reference describes the Name ID format as "The username format to send in the SAML Response"), and KnoxCall recognises a person by their NameID. An email-based username changes when the person is renamed — Okta's own documentation notes that it can update an app username automatically "when the email address changes" — and a NameID that changes gives the renamed person a second KnoxCall account. The Okta user ID is an identifier Okta assigns, not one made from the person's name or address, so a rename leaves it alone; Okta's Expression Language reference documents `user.getInternalProperty("id")` as returning the user's ID. The whole argument is in [choosing the NameID](/sso/overview#choosing-the-nameid).

**Then check what Okta actually sends.** Okta documents that when a sign-in request includes a NameID policy, the application's Name ID format "must match it", which is why the format stays on the email-address format above. It does not document what it does with a username that is not an address under that format. So once step 4 is done, run a sign-in from the connection's **Test** tab in KnoxCall and read the **NameID** in the verdict: an id like `00u…` means you are done; an address means the connection will keep showing its NameID notice, and it will be right to.

These are the `default` connection's values — the connection every workspace starts with, and the one the `/saml/<workspace>/…` alias resolves to. If Okta is a *second* identity provider for this workspace, it gets its own connection with its own handle, and its values are `/sso/<workspace>/<handle>/{metadata,acs,login,slo}` — for a handle of `okta`, `https://acme.knoxcall.com/sso/acme/okta/acs` and its three siblings. Open that connection under **Settings → Single sign-on** and its **Certificates** tab lists all five, each with a copy button. See [more than one identity provider](/sso/overview#more-than-one-identity-provider).

### Attribute statements

KnoxCall reads a plain email and display name and nothing else. Two statements are enough:

| Name          | Name format | Value              |
| ------------- | ----------- | ------------------ |
| `email`       | Basic       | `user.email`       |
| `displayName` | Basic       | `user.displayName` |

Both names are on KnoxCall's default list, so no configuration is needed on the KnoxCall side to read them. If your Okta profile carries the address somewhere other than `user.email`, keep the statement named `email` and change the value — that is easier than naming an attribute on the KnoxCall connection.

**The `email` statement is required.** With the NameID set to the Okta user ID, it is the only place KnoxCall finds the person's address — without it nobody can be admitted, because admission is decided by the address's domain.

### Group attribute statements (optional)

Only needed if you want group membership to decide whether a new person lands as **member** or **readonly**.

| Name     | Name format | Filter                                              |
| -------- | ----------- | --------------------------------------------------- |
| `groups` | Basic       | `Matches regex` · `.*`, or `Starts with` · a prefix |

`groups` is one of the attribute names KnoxCall checks without being told to. Prefer a narrow filter to `.*`: Okta emits every matching group name on every assertion, and an assertion is a POST body a browser has to carry.

Whatever Okta emits — group **names**, here — is what you type as the keys of the group map on the KnoxCall connection. The map's values are bounded: a group mapped to anything but `member` or `readonly` is refused at save time, because *"…an IdP group may only map to `member or readonly`…"* — those two and no others. Owner and admin are granted by a human on the team page and by nothing else.

## 3. Advanced settings (optional, and both worth doing)

**Assertion Encryption.** Set **Assertion Encryption** to `Encrypted`, then upload KnoxCall's **encryption** certificate. Take it from the `use="encryption"` KeyDescriptor in our metadata document — it is the same certificate as the signing one, published twice on purpose, because an IdP reads one descriptor for each job. KnoxCall accepts encrypted and plain assertions alike, so this is your call.

**Signature Certificate.** Upload the certificate from the `use="signing"` KeyDescriptor so Okta can verify the AuthnRequests KnoxCall signs. KnoxCall signs every one; Okta simply ignores the signature until you give it the key to check it against.

**Single Logout.** Tick **Enable Single Logout**, then:

| Okta field                | Value                                          |
| ------------------------- | ---------------------------------------------- |
| **Single Logout URL**     | `https://acme.knoxcall.com/saml/acme/slo`      |
| **SP Issuer**             | `https://acme.knoxcall.com/saml/acme/metadata` |
| **Signature Certificate** | KnoxCall's signing certificate, as above       |

That is the IdP→SP direction. For the other direction — signing out of KnoxCall also signing out of Okta — put Okta's own SLO endpoint (`https://<your-org>.okta.com/app/<app-label>/<app-id>/slo/saml`, shown in Okta's SAML setup instructions) into the KnoxCall connection's **IdP single-logout URL**. It must be https; KnoxCall refuses anything else at save time, because a `LogoutRequest` carries the person's email address as its NameID and the browser is redirected to that URL.

## 4. Take the Okta values back to KnoxCall

Two routes: import Okta's federation metadata, or type the values by hand. The import is the one that cannot be mis-transcribed.

### Import the federation metadata

**Applications → your app → Sign On → SAML Setup Instructions** publishes Okta's own **Identity Provider metadata** — one document carrying the issuer, the sign-on endpoint and every signing certificate. Hand KnoxCall that link, or the document itself:

```http theme={"dark"}
POST /admin/saml/connections/<id>/metadata
{ "url": "<the Identity Provider metadata link on that page>" }
```

```http theme={"dark"}
POST /admin/saml/connections/<id>/metadata
{ "xml": "<EntityDescriptor …>" }
```

The call **previews by default** and writes nothing until you send it again with `"apply": true`. What the preview reports, what an import never touches, and every refusal it can answer with are on the [overview](/sso/overview#importing-your-idps-metadata). Like the metadata you handed Okta, it is a **snapshot**: nothing re-reads that URL on a schedule, so run the import again when Okta rolls the app's signing certificate.

### Or type the values

**Applications → your app → Sign On → SAML Setup Instructions** (or **View SAML setup instructions**) gives you three things.

In KnoxCall, **Settings → Single sign-on** → your connection:

| KnoxCall field                                     | Where it is                            | Okta value                                                                                         |
| -------------------------------------------------- | -------------------------------------- | -------------------------------------------------------------------------------------------------- |
| **IdP sign-in URL**                                | Connection tab                         | **Identity Provider Single Sign-On URL** (`https://<your-org>.okta.com/app/<app>/<id>/sso/saml`)   |
| **IdP entity ID (optional)**                       | Connection tab                         | **Identity Provider Issuer** (`http://www.okta.com/<id>`)                                          |
| **Only admit specific domains**                    | Connection tab                         | leave it off to admit every domain you have proven for single sign-on; tick it to narrow to a list |
| **Create accounts automatically on first sign-in** | Connection tab                         | on, unless you invite everyone by hand                                                             |
| **Default role**                                   | Attributes & groups tab                | `member` or `readonly`                                                                             |
| **IdP signing certificate**                        | Certificates tab → *Add a certificate* | the **X.509 Certificate** shown there, with or without the BEGIN/END lines                         |

<Note>
  Okta's issuer really does begin `http://www.okta.com/`. That is a SAML **entity ID** — a name, not an address; nothing dereferences it, and KnoxCall stores it as given. The two fields that *are* dereferenced, the sign-in URL and the single-logout URL, must both be https and are refused otherwise.
</Note>

Saving needs a re-authentication in the last five minutes; that is expected, and it is the same bar as changing a password.

## 5. Assign people, then test

**Assignments → Assign** — to people, or to Okta groups. Okta refuses sign-in to anyone unassigned before KnoxCall ever sees a request.

Test with one account: open `https://acme.knoxcall.com/saml/acme/login`, sign in, and check the person lands in the workspace with the role you expected. If it fails, the login page names the cause — every message and code is in [troubleshooting](/sso/troubleshooting).

## The Okta dashboard tile

Clicking KnoxCall in the Okta End-User Dashboard is an **IdP-initiated** sign-in, and it is off unless you turn it on. With it off the person is bounced back to the login page with `saml_idp_initiated_disabled`. See [IdP-initiated sign-in](/sso/overview#idp-initiated-sign-in) for how to switch it on and what it costs.

## Rotating the Okta certificate

Okta's app signing certificate expires, and Okta lets you generate the next one before the current one goes. Rotate **add-first**:

1. In Okta, **Sign On → SAML Signing Certificates → Generate new certificate**. Leave the current one active.
2. Copy the new certificate into the KnoxCall connection. Pasting a certificate **adds** it — a connection can hold several active certificates and an assertion signed by any of them verifies.
3. Activate the new certificate in Okta.
4. Retire the old certificate in KnoxCall.

Doing it in that order means there is no instant at which the certificate Okta is signing with is not one KnoxCall trusts. Retiring the only active certificate is refused outright: *"This is the connection's only active IdP certificate. Add the new certificate first, then retire this one."*
