Skip to content
KortixKortix
Esc
↑↓navigate↵open⌘Jpreview
On this page

Sign-in, SSO & API keys

Two-factor and MFA enforcement, session controls, SAML SSO, SCIM provisioning, API keys and service accounts, and OAuth apps.

These controls decide how people and machines sign in to a Kortix account. Every member uses them to secure their own sign-in and create keys. Owners and admins use them to set account rules, connect an identity provider, and issue keys for CI and apps. Each control also has an API route. See the REST API.

Open your own settings from the project menu → Settings. Open the account’s settings from the project menu → Switch Project → Account settings. Each control is in one of these places:

Place Who What is there
Settings → Security Each person, for themselves Two-factor authentication, signed-in devices
Settings → Personal access keys Each person, for themselves Keys that act as you, connected apps
Account settings → Settings → Security Owners and admins Require two-factor authentication, Maximum session length, Idle timeout, Active sessions, Admins can open every session (Sessions)
Account settings → API keys Owners and admins Service accounts, OAuth apps, Key rules
Account settings → Identity Owners and admins SAML SSO, Directory Sync (SCIM)

The account sections need the account.write permission, which the owner and admin roles hold. Roles, members, and groups are on Accounts & access.

Two-factor and MFA enforcement

Turn on two-factor for yourself

  1. Open Settings → Security.
  2. Select Add authenticator app.
  3. Scan the QR code with any authenticator app (TOTP), or enter the key under Can’t scan? Enter this key.
  4. Type the 6-digit code. It verifies when you type the sixth digit.

Kortix then asks for a code at sign-in and before sensitive changes: removing a factor and signing out devices. Remove a factor from the same page.

Require two-factor for the account

  1. Open Account settings → Settings → Security.
  2. Turn on Require two-factor authentication.
  3. Read the preview. It counts the members with a verified factor and lists every member who has none.
  4. Select Require it.

When the requirement is on, a browser sign-in without a verified second factor gets 403 with code: "account_mfa_required" on every protected action. The web app opens a code prompt. A member with no factor enrolls one under Settings → Security first.

  • Exempt: super-admins, personal access keys, and service account keys. A key has no second factor to prompt for.
  • Lockout guard: Kortix refuses to turn the requirement on when no super-admin exists and no member has a verified factor (409).
  • Turn it off: select Stop requiring it. Members can then sign in with a password alone.

Session controls

Session policy

Open Account settings → Settings → Security and set two limits, in minutes. Empty means no limit.

Setting Effect Limit
Maximum session length How long a browser sign-in lasts before the member signs in again 1 to 10,080 (7 days)
Idle timeout Signs a member out after this many minutes with no request 1 to 10,080 (7 days)

A sign-in past either limit gets 401 on its next request to the account. The member signs in again. Keys are exempt.

Sign a member out

Active sessions, under the policy, lists the 200 most recently active browser sign-ins in the account. Select Sign out on a row. That sign-in gets 401 on its next request, and the member can sign in again. This needs the member.remove permission.

Your own devices

Settings → Security → Devices lists every browser, desktop, and mobile sign-in of yours.

  • Sign out on one device ends that sign-in. You cannot sign out the current device from this list. Sign out normally instead.
  • Sign out other devices ends every sign-in except this browser.

Single sign-on (SAML)

SAML SSO lets members sign in with your identity provider (IdP). It needs the sso entitlement (see Enterprise features) and an organization account. A personal account gets 403 code: "sso_personal_account". The account Kortix creates at sign-up is personal. Create an organization account with the project menu → Switch Project → Create an account…, and create the team’s projects there. A project cannot move between accounts. An account has one SSO provider.

Set it up

Open the guided setup

Open Account settings → Identity. On the SAML SSO card, select Configure and pick your IdP: Microsoft Entra ID, Okta, Google Workspace, Cloudflare Access, OneLogin, JumpCloud, PingOne, Auth0, or a custom SAML provider. The wizard shows each click in that IdP’s console.

Register Kortix in your IdP

Create a SAML app in your IdP. Copy the two values from Service provider details: Identifier (Entity ID) and Reply URL (ACS). Assign the people who may sign in.

Import the IdP metadata

Paste the IdP’s metadata URL or its metadata XML. Enter the Primary email domain and the Group claim name: the SAML attribute that carries group membership.

Verify the domain

Publish the TXT record the card shows, then select Verify domain.

Map groups

Add group mappings, or turn on Auto-provision groups. See Groups from the IdP.

Enforce SSO

Turn on Enforce SSO for this domain when every member can sign in through the IdP.

From then on, a person who enters a work email on the sign-in page goes to the IdP. With Auto-create members on (the default), Kortix adds them to the account on their first SSO sign-in.

Setting Default Effect
Group claim name groups The SAML attribute Kortix reads groups from. Okta sends group names on groups. Entra sends group object IDs by default. The Entra guide names the claim memberOf, so set Group claim name to memberOf for Entra.
Auto-create members On Adds every person who signs in through the IdP as a member. Off: SSO adds only existing members and people your SCIM directory provisioned.
Auto-provision groups Off Creates a Kortix group for every group the IdP sends, and adds the person to it.
Enforce SSO for this domain Off Refuses every other way to sign in for the primary domain.

Verify the domain

The IdP asserts each person’s email address. Kortix trusts that address only for a domain your account verified with DNS.

Record Name Value
TXT _kortix-verification.<your-domain> kortix-verification=<token>

DNS changes can take a few minutes to appear.

  • One domain belongs to one account. A domain that another account verified returns 409 code: "sso_domain_claimed".
  • A new primary domain starts a new, unverified claim with a new token.
  • Until the domain is verified, members still join through SSO and get their groups. Their SSO identity matches no invitation from another account, no existing identity merges into it, and Enforce SSO has no effect.
  • With a verified domain, an existing member with the same email merges into the SSO identity and keeps their roles. Kortix never merges an owner or a super-admin. Their SSO sign-in joins as a separate member.

Enforce SSO

With a verified domain and Enforce SSO for this domain on, every identity in that domain that did not come from your IdP is refused with 403:

  • password sign-in, magic links, and email codes, in the web app and on the headless sign-in routes (/v1/auth/signup, /v1/auth/sign-in/password, /v1/auth/sign-in/magic-link, /v1/auth/verify-otp). There the body is error: "sso_required".
  • the existing sessions and keys of those identities, owners and super-admins included. Their account and project requests get code: "sso_required".

Groups from the IdP

Kortix syncs groups on every SSO sign-in:

  • It adds the person to each group a claim value maps to.
  • It removes the person from a mapped group when the IdP stops sending its claim value.
  • It keeps groups an admin added by hand. Only mapped groups change.

Add a mapping on the SAML SSO card under Group mappings: a Claim value and an IAM group. The match ignores case and surrounding spaces. Map Entra object IDs, or Okta group names, exactly as the IdP sends them. Give each group its project roles under Groups.

Remove SSO

Select Remove SSO provider on the SAML SSO card. Existing members keep their access. New SSO sign-ins stop joining the account, and group sync stops.

SCIM provisioning

SCIM lets your IdP create, update, and remove members and groups without a sign-in. It needs the scim entitlement. Connect SAML SSO first: SCIM creates members, and SSO is how they sign in.

Connect your IdP

  1. Open Account settings → Identity. On the Directory Sync card, select Guided setup and pick your IdP: Microsoft Entra ID, Okta, OneLogin, JumpCloud, PingOne, or any SCIM 2.0 provider.
  2. Mint a token. Kortix shows the secret (kortix_scim_…) once.
  3. In the IdP, enter the SCIM base URL and the token as a bearer token.
  4. Start provisioning in the IdP.
Value What to enter
SCIM base URL https://api.kortix.com/scim/v2/accounts/<account_id>. It has no /v1. A self-hosted instance uses its own API origin.
Auth Authorization: Bearer kortix_scim_…
User identifier userName = the person’s email

The guided setup shows each step in the IdP console. Check these settings:

  • Okta: set Unique identifier field for users to userName and Authentication Mode to HTTP Header. Okta pushes changes as they happen.
  • Microsoft Entra ID: automatic provisioning needs Entra ID P1 or P2. Keep userName → user.userprincipalname. Entra syncs about every 40 minutes. Provision on demand pushes one person at once.

Kortix checks the scim entitlement on every SCIM request, so a token stops working when the account loses it.

What the endpoints do

Endpoint Supports
/ServiceProviderConfig, /ResourceTypes, /Schemas Discovery
/Users GET (list, one), POST, PUT, PATCH, DELETE
/Groups GET (list, one), POST, PUT, PATCH (add and remove members), DELETE
  • Filters: one attribute eq "value" clause. /Users matches userName, id, and externalId. /Groups matches displayName, id, and externalId. A filter in any other form returns 400. A filter on another attribute returns an empty list.
  • New person: a POST /Users for an email with no Kortix sign-in creates a pending invitation with the member role, valid for 14 days. SCIM lists it as an active user. A person who already has a Kortix sign-in joins as a member.
  • Groups: a SCIM group is an ordinary Kortix group. Give it project roles like any other.
  • Remove a person: active: false or DELETE removes the membership, its roles and groups, and revokes the person’s keys and live session tokens.
  • Last owner: deactivating the account’s last owner returns 409.

API keys and tokens

Every Kortix credential starts with a prefix that names its kind.

Prefix Credential Acts as Get one
kortix_pat_ Personal access key You, with your roles. Optionally one project only. Settings → Personal access keys, kortix tokens new, kortix login
kortix_pat_ Project CLI token You, on one project only kortix projects cli-tokens new
kortix_sa_ Service account key The service account. It has no access until a role is assigned. Account settings → API keys, kortix tokens service-accounts new
kortix_oat_, kortix_ort_ OAuth access token (1 hour), refresh token (30 days) The person who approved the app Sign in with Kortix
kortix_gw_ Gateway key Model calls through one project’s LLM gateway kortix gateway keys new (Models)
kortix_scim_ SCIM token Directory sync for one account Account settings → Identity
kortix_pat_ Session token, in KORTIX_TOKEN The agent of one session Kortix sets it in the sandbox. It ends with the session.

Kortix shows a secret once, when you create it, and stores only its hash. Connected apps (kortix_oat_) cannot create keys, service accounts, SCIM tokens, or OAuth apps (403).

Personal access keys

A personal access key acts as the member who created it. It holds exactly that member’s roles and stops working when the membership ends. Every member can create and revoke their own keys. Revoking someone else’s key needs token.revoke.

kortix tokens new ci-deploy --expires 90d          # print the secret once
kortix tokens new laptop --project <project_id>    # this project only
kortix tokens ls --mine
kortix tokens rm <token_id>

--expires takes an ISO-8601 instant or a span: 30d, 12h, 6w, 1y. A key bound to one project gets 403 on every other project and on account actions. For a key bound to the current project, use kortix projects cli-tokens new [--expires-at <iso>].

Service accounts

A service account is its own principal, for CI and automations that must not act as a person. It starts with no access.

kortix tokens service-accounts new nightly-reporter --description "Cron"
kortix access grant --service-account <id> --role member --project <project_id>
kortix tokens service-accounts disable <id>   # stops it authorizing
kortix tokens service-accounts rm <id>        # deletes it

A disabled service account cannot be enabled again. Create a new one. Each agent also has a service account. Bind its ceiling role in Account settings → Projects → the project → Grant access → Agents, not here. See What an agent may do.

Key rules

Account settings → API keys → Key rules governs the personal access keys and project CLI tokens people create in the account. Keys Kortix creates for a running session follow the session instead.

Rule Field Limit Effect
Require an end date require_expiry On or off A key without an expiry is refused: 400 code: "expiry_required".
Longest a key can last max_lifetime_days 1 to 730 days A later expiry is refused: 400 code: "expiry_too_far".
Turn off unused keys idle_revoke_days 1 to 365 days A key unused for this long is revoked on its next use. Keys bound to one project are exempt.

The first two rules apply when a key is created. Turn off unused keys also applies to existing keys.

OAuth apps and connected apps

Register an OAuth app

An OAuth app signs Kortix members in on your own site (“Sign in with Kortix”).

  1. Open Account settings → API keys → OAuth apps and select Register app.
  2. Enter a name, the type, the redirect URIs, and the scopes.
  3. Copy the client id and, for a confidential app, the client secret. The secret is shown once.
Field Values
Type Confidential: a server-side app with a client secret. Public: a browser or native app with PKCE and no secret. Fixed at registration.
Redirect URIs Matched byte for byte. https, except localhost.
Scopes profile (who the person is), email, kortix (act as the person on the Kortix API). Default: all three.
Active Off stops new sign-ins without deleting the app.

Rotate secret issues a new secret, and the old one stops working at once. Delete app ends every token the app holds. In code, use kortix.iam.oauthClients (list, get, create, update, rotateSecret, remove). The sign-in flow is in Sign in with Kortix.

Connected apps

A connected app is an app you approved with Sign in with Kortix, for example an MCP client such as Claude Code or Cursor. It acts as you, in every account you belong to, until you revoke it. See Kortix MCP server.

  • Web: Settings → Personal access keys → Connected apps → Revoke access.
  • CLI: kortix tokens apps ls and kortix tokens apps rm <client-id>.

Revoking deletes your approval, and the app’s tokens stop working on their next request. The app must ask you again.

Enterprise features

An entitlement decides whether a feature exists for the account. The role still decides who may use it. The Enterprise plan holds all five.

Entitlement Unlocks
sso SAML SSO, domain verification, Enforce SSO
scim SCIM provisioning and SCIM tokens
rbac Custom roles; creating, editing, and adding members to groups
auditAccess Reading and exporting the audit log, audit webhooks
branding Branding

Without the entitlement, the gated route returns 402 with code: "entitlement_required" and entitlement set to its key. A SCIM request (/scim/v2/...) from an account without scim gets 403. Removing a configuration (an SSO provider, a SCIM token) never needs the entitlement. Plans are on Plans & credits.

On a self-hosted instance, a Kortix Enterprise license unlocks all five for every account: set ENTERPRISE_LICENSE_AVAILABLE=true, or install with kortix self-host init --enterprise-license. See Self-hosting.

Was this page helpful?