Base 3:16
Guides

Directory sync (SCIM)

Letting a customer's Okta or Entra be the authority on who exists — and, more to the point, on who has stopped.

An enterprise customer runs Okta or Entra and will not maintain a second list of people by hand. SCIM lets their directory create and update users in your product automatically.

The half that matters

Provisioning is the convenience. Deprovisioning is the product.

The reason SCIM appears in procurement is that somebody offboarded in HR has to lose access to your product because their record closed there — not because an administrator remembered to go and remove them. That is the control an enterprise security review is actually asking about.

Setting one up

One directory manages one tenant. Each of your customers gets their own endpoint and token, so revoking one cannot disturb another.

  1. In Authentication → Directory sync, choose Connect a directory.
  2. Pick the tenant its people should land in, and a default role.
  3. Copy the endpoint and the token.

The token is shown once. Only a digest is stored, so it cannot be shown again — if it is lost, revoke it and issue another.

In Okta, that is Provisioning → Integration → SCIM 2.0 Base URL and API Token. In Entra, Provisioning → Admin Credentials → Tenant URL and Secret Token.

Endpoint  https://api.base316.com/scim/v2/env_1a2b3c
Token     b316_scim_…

Groups are roles

A SCIM Group is a Base316 role. Not a separate thing mapped to one — the group is the role, its members are the people holding it, and there is therefore no mapping to drift out of date.

A group pushed from a directory that matches no existing role creates one with no permissions. That is deliberate: a group says who is together, never what they may do, and inventing permissions for it would grant access nobody asked for. Fill it in under Roles.

Because a membership holds one role, somebody in two groups ends up with whichever the directory applied last. That is the directory's own ordering, not a rule invented here — if a person needs the union of two groups' permissions, make a role that says so and put them in it.

What each operation does

The directory doesBase316 does
Creates a userCreates the person and puts them in the tenant on the default role
Sets active: falseRevokes every session and refresh token; see below
Sets active: trueRestores it
DELETEs a userThe same as active: false
Adds someone to a groupGives them that group's role
Removes them from a groupReturns them to the default role — they stay in the tenant
Deletes a groupRemoves the role; its people stay, on the default role

Three of these are worth dwelling on.

A directory reaches its own tenant and no further. An address that already belongs to somebody in the environment — including somebody in one of your other tenants — comes back 409, with nothing about them in the body. The same goes for adding a stranger to a group: it is a miss, not an invitation to enrol them. If a person genuinely belongs to two of your tenants, add the second membership yourself; that is a decision you can see both sides of and one customer's IT department cannot.

For the same reason, active: false revokes sessions but only marks the account disabled when that tenant was the person's last one here. A disabled account is locked out everywhere in the environment, which is not something one of your customers gets to impose on another's staff. Sessions go either way, so offboarding still takes effect immediately.

A delete deactivates rather than erases. Usage, invoices and the audit trail stay attributable — an offboarded employee is a record an enterprise still needs — and the user remains readable with active: false, which is what the next sync expects to find. Actually removing somebody is a privacy request, which is a person's right rather than a directory's routine.

Removing somebody from a group does not remove them from your product. "No longer an engineer" is a different sentence from "no longer works here", and the directory says the second one separately.

What is supported

  • Users and Groups, with GET, POST, PUT, PATCH and DELETE.
  • ServiceProviderConfig and ResourceTypes, which Okta reads before its first sync.
  • Filters of the form attribute eq "value" — userName, emails.value, externalId and displayName. This is what directories send when they look a person up before creating them. Compound filters with and, or, co and sw are refused rather than half-answered, because a filter that quietly matches the wrong people is worse than one that fails.
  • Pagination with startIndex and count, up to 200 per page.

Not supported: bulk operations, sorting, and ETags. No directory needs them for provisioning.

When a sync appears to have stopped

The connection list shows last sync for each directory. If it is older than you expect:

  • Check the token has not been revoked — a revoked one is marked as such.
  • Check the directory is pointed at the right environment. The URL names one, and a token issued for another environment is refused even if it is valid.

On this page