Single sign-on

    SCIM provisioning

    Connect your directory to CCTVplanner over SCIM 2.0. When you finish, Microsoft Entra ID or Okta creates, updates and deactivates CCTVplanner accounts for people at your verified domains.

    Before you start

    • Enterprise plan, with an active subscription
    • At least one verified domain in the CCTVplanner organization console
    • A sign-on connection that has passed its test and is switched on, so the accounts your directory creates can be used
    • Owner or administrator access to cctvplanner.io/organization
    • Application Administrator in Microsoft Entra ID, or Super Administrator in Okta
    • A password manager or vault, the provisioning token is shown once

    Values to paste

    Copy these from your organization console rather than from this page. The console is the authority; the shapes below are only so you recognise the right field.

    Entity ID, Identifier, Audience URIhttps://auth.cctvplanner.io/auth/v1/sso/saml/metadata
    Assertion Consumer Service, Reply URLhttps://auth.cctvplanner.io/auth/v1/sso/saml/acs
    Service provider metadatahttps://auth.cctvplanner.io/auth/v1/sso/saml/metadata?download=true
    NameID formaturn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress

    Steps

    1. 1

      Check the sign-on connection before you start

      A connection is in one of four states: draft, testing, active or disabled. Provisioned accounts are of no use until the connection is active, so settle this first.

      Open the connection in the organization console and run its test. The console opens your identity provider in a new browser tab and you sign in there. That sign-in creates a twin account: a second, separate CCTVplanner account at your own address, held by the identity provider and occupying no seat, because an SSO identity is never linked to an existing password account. The test tab confirms the result, signs that twin account out again and hands the outcome back to the original console tab, which restores your own session.

      Only after the test passes can you switch the connection on.

      Editing an active connection's metadata puts it back into testing. Plan metadata edits accordingly: while a connection is testing, the people who depend on it cannot sign in.

      The states and what a sign-in through them does are in the table below.

      DraftNot yet tested, not usable for sign-in
      TestingOrdinary sign-ins are refused with SSO_CONNECTION_TESTING
      ActiveSign-in works for addresses at your verified domains
      DisabledSign-ins are refused with SSO_PROVIDER_DISABLED

      A connection is bound to your verified domains. An assertion carrying an address outside them is refused with SSO_EMAIL_OUTSIDE_DOMAIN, at sign-in and again at every token refresh.

    2. 2

      Create the provisioning token

      Open cctvplanner.io/organization and find the provisioning tokens.

      Create a bearer token. It is shown once, then stored only as a SHA-256 hash, so paste it into your vault before you close the dialog.

      Two tokens can be live at a time. That second slot exists so you can rotate without an outage: create the new token, paste it into the directory, test, then revoke the old one.

      Tokens expire after one year.

      Token lifetimeOne year from creation
      Live tokens per organisationTwo
      StorageSHA-256 hash, the token itself is never shown again

      If you lose the token there is no recovery. Create a new one and revoke the lost one.

    3. 3

      Copy the SCIM base URL

      The console shows the SCIM base URL for your project with a copy button. Copy it from there rather than typing it from this page.

      Its shape is https://<project>.supabase.co/functions/v1/scim/v2, where the project host is yours.

      Paste the value exactly as the console gives it to you. Do not add or remove a trailing slash on your own.

      Seats: an account created by the directory occupies a seat, and deactivating that account in the directory does not release it.

      SCIM base URL (shape)https://<project>.supabase.co/functions/v1/scim/v2
      AuthenticationBearer token in the Authorization header
      ResourcesUsers. Groups is read-only and always returns an empty list.
      Filteringeq only, on userName, externalId, id and emails[type eq "work"].value
    4. 4

      Microsoft Entra ID: add the provisioning configuration

      In the Microsoft Entra admin center, go to Entra ID, then Enterprise apps, and open the application you already use for SAML sign-in.

      Select Provisioning in the left panel, then + New configuration.

      Put the base URL in Tenant URL and the token from the previous step in Secret Token.

      Select Test Connection, then Create. Older tenants show the previous screen instead, where you set Provisioning Mode to Automatic and open Admin Credentials to reach the same two fields.

      Tenant URLThe SCIM base URL copied from the console
      Secret TokenThe bearer token created in the previous step

      Do not leave Secret Token blank. Entra then sends a token it issued itself, which we do not accept. Test Connection queries the endpoint for a user that does not exist, using a random GUID as the matching property, so it only proves the connection when the matching property is one we can filter on.

    5. 5

      Microsoft Entra ID: fix the mappings you keep, delete the rest

      Select Attribute mapping in the left panel, then the user mapping.

      Entra maps userName from userPrincipalName by default. If your people sign in with a UPN on an onmicrosoft.com domain, change the source so userName carries the corporate address at a verified domain.

      Set Matching precedence 1 on userName. We support eq filtering on userName, externalId, id and the work e-mail, so matching on userName is safe and it is the value a person signs in with.

      Entra's default mapping for externalId is mailNickname. Change it to objectId, which survives a rename.

      Keep userName, active, name.givenName, name.familyName, emails[type eq "work"].value and externalId. Delete the rest, including the telephony, address, manager and locale rows, and disable the group mapping.

      Attributes we do not read are accepted and ignored, not rejected. Delete their mappings to keep your provisioning log readable, not to prevent an error.

      Filtering supports eq only. A mapping that makes Entra match on anything else will fail on every cycle.

    6. 6

      Microsoft Entra ID: set the scope, then start provisioning

      In the provisioning configuration you created two steps ago, set Scope to Sync only assigned users and groups. Syncing the whole directory pushes every account at every domain, including the ones outside your verified domains.

      On the Users and groups tab, assign the group that should have CCTVplanner. Nothing is provisioned until you do.

      Select Provision on-demand in the left panel and run a single person first, then read the result.

      Select Overview, then Properties, then the pencil to edit. Enable notification emails, give an address for quarantine mail, and select Apply.

      Select Start provisioning.

      The first cycle runs long, and later cycles run approximately every 40 minutes. Provision on-demand is the only fast feedback loop.

    7. 7

      Okta: enable the API integration

      In the Okta admin console, open Applications, open your SAML app, and select the Provisioning tab.

      Select Configure API Integration, then tick Enable API Integration.

      Put the base URL in SCIM connector base URL and userName in the unique identifier field for users.

      Under Supported provisioning actions, tick Push New Users and Push Profile Updates. Leave Import New Users and Profile Updates off: we do not support directory-driven import. Leave Push Groups off.

      For Authentication Mode select HTTP Header and paste the bearer token into the Authorization field. Okta sends it as Authorization: Bearer followed by your token, so paste the token on its own.

      Select Test API Credentials, then Save.

      SCIM connector base URLThe SCIM base URL copied from the console
      Unique identifier field for usersuserName
      Supported provisioning actionsPush New Users and Push Profile Updates only
      Authentication ModeHTTP Header
      AuthorizationThe bearer token created earlier, on its own
    8. 8

      Okta: turn on the provisioning actions and check the mappings

      Still on the Provisioning tab, open To App and select Edit.

      Enable Create Users, Update User Attributes and Deactivate Users. Without Deactivate Users an offboarding in Okta leaves the CCTVplanner account live.

      Scroll to the attribute mappings and confirm that userName carries the corporate address. If your Okta usernames are not e-mail addresses, for example accounts at "@yourorg.okta.com", map userName from user.email.

      We read the user name, the active flag, the given and family names, the work e-mail and the external id. Okta fills externalId with the Okta user id by itself, so there is nothing to map for it.

      Remove mappings you do not need. Anything else you send is accepted and ignored.

      Do not push groups. Groups is read-only here and always returns an empty list, and roles are set in CCTVplanner.

    9. 9

      Okta: assign the app to the right people

      Open the Assignments tab and assign the group that should have CCTVplanner.

      Assign a group rather than individuals, so an offboarding in the directory removes the assignment and triggers the deactivation.

      An Okta group assignment governs who gets an account. It does not set anyone's role. Roles are set in the CCTVplanner console.

    10. 10

      Deactivate one person and confirm the behaviour

      Deactivate your test account in the directory and watch what happens here.

      Deactivating suspends the account, ends the sessions and bans the login. It does not delete anything.

      Access tokens live fifteen minutes, so an open browser stops working within fifteen minutes at the latest and then shows SSO_ACCOUNT_SUSPENDED. There is no shorter cut-off: the ban applies at once, the token already in the browser has to expire.

      The seat stays occupied and the projects, offers and price lists stay with the organisation. That is deliberate: an offboarding must never take the work with it.

    11. 11

      Work inside the limits

      Users only. Groups is read-only and always returns an empty list, because roles are set in CCTVplanner and not in your directory.

      There is no group to role mapping. Set the role in the console after the account appears.

      Filtering supports eq only, on userName, externalId, id and emails[type eq "work"].value. PATCH is supported. Bulk and sort are not.

      The directory may only create people at your verified domains. Contractors on a foreign address have to be invited by hand.

    Attribute mapping

    userNameEntra: user.mail, or user.userPrincipalName only when the UPN is at a verified domain. Okta: user.userName, or user.email when Okta usernames are not e-mail addresses. Matching precedence 1.
    activeEntra: the default Switch([IsSoftDeleted], , "False", "True", "True", "False") mapping. Okta: driven by Deactivate Users.
    name.givenNameuser.givenName (Entra) / user.firstName (Okta). Optional.
    name.familyNameuser.surname (Entra) / user.lastName (Okta). Optional.
    emails[type eq "work"].valueuser.mail (Entra) / user.email (Okta). Optional, and filterable.
    externalIdEntra: change the default mapping from mailNickname to objectId, which survives a rename. Okta: sent automatically as the Okta user id, nothing to map. Filterable.

    Prove it works

    1. In the organization console, run the test on the sign-on connection. Sign in at your identity provider in the tab the console opens, and wait for the console to report the outcome and restore your own session.
    2. Confirm the console reports that the test passed, then switch the connection on.
    3. Run Test Connection in Entra ID, or Test API Credentials in Okta, and confirm the directory reports success.
    4. Provision one person: Provision on-demand in Entra, or assign one test user in Okta.
    5. Open cctvplanner.io/organization, confirm the person appears, and set their role there.
    6. Have that person sign in through single sign-on and reach a project.
    7. Change their surname in the directory and confirm the change reaches the console, on demand or on the next cycle.
    8. Deactivate them in the directory, then confirm the console shows them suspended and their open session stops working within fifteen minutes, with SSO_ACCOUNT_SUSPENDED.

    Troubleshooting

    SymptomCauseFix
    The directory logs a refusal saying the address is outside the allowed domains, and no account is created. People at that domain who try to sign in see SSO_EMAIL_OUTSIDE_DOMAIN.userName or the work e-mail carries a domain you have not verified, most often an onmicrosoft.com UPN in Entra or a non-corporate Okta username. A connection is bound to verified domains, at sign-in and again at every token refresh.Map userName to the corporate address. If the domain should be allowed, claim it in the organization console and publish the DNS TXT record the console shows for it, then wait for the console to show it as verified.
    The directory reports a duplicate user, or a create that should have been an update.The person already exists here, added by hand, by an earlier SCIM run or by JIT provisioning on first sign-in, and the matching attribute the directory uses does not match the value we hold.Set matching on userName with precedence 1 and make the directory value byte-identical to the address in the console. Fix the address on one side, then re-run the provisioning on demand. Filtering supports eq only, so a near match is a miss.
    Test Connection or Test API Credentials fails, and Entra ID quarantines the provisioning job.The token expired after its year, was revoked in the console, was pasted into the wrong field, or a rotation removed the one still in use.Create a new token in the console and paste it into Secret Token (Entra) or the Authorization field (Okta). Test, save, then restart provisioning to clear quarantine. Two tokens live at a time, so rotate by adding the new one first and revoking the old one after the test passes.
    People see SSO_SUBSCRIPTION_INACTIVE at sign-in.The organisation's subscription is not active. A failed card or a paused plan stops sign-in.Settle billing, then sign in again.
    A new person sees SSO_NO_SEATS when they sign in.No free seat for that person.Buy seats, or free them. A person deactivated in the directory still occupies a seat.
    Group changes in the directory do not reach us.Groups is read-only here and always returns an empty list, on purpose. Roles are set in CCTVplanner, not by your directory.Disable the group mapping in Entra and leave Push Groups off in Okta. Set roles in the console. Keep using a directory group to decide who is assigned the app, that part works.
    Provisioning is on, the configuration tests fine, and nobody is created.The scope is Sync only assigned users and groups and nobody is assigned, or the first cycle has not finished. Cycles run approximately every 40 minutes.Assign the group on the Users and groups tab in Entra, or on the Assignments tab in Okta, then use Provision on-demand to prove one person immediately instead of waiting for the cycle.
    Someone you deactivated in the directory is still working in the app.Access tokens live fifteen minutes. The ban applies at once, the token already in their browser has to run out.Wait out the fifteen minutes. After that they see SSO_ACCOUNT_SUSPENDED. There is no cut-off shorter than that.
    The directory reports errors on filter, sort or bulk requests.We support eq filters only, on userName, externalId, id and emails[type eq "work"].value. PATCH is supported. Bulk and sort are not.Leave the matching attribute on userName or externalId and do not enable any bulk, sorted or import option the directory offers. There is no setting on our side to change this.
    Provisioning works, and then sign-ins start being refused with SSO_CONNECTION_TESTING.Someone edited the sign-on connection's metadata, which puts an active connection back into testing.Run the connection test again in the console and switch the connection back on once it passes.

    Worth knowing

    • Provisioning and sign-in are separate switches. A person created by SCIM still cannot sign in while the connection is disabled, and they see SSO_PROVIDER_DISABLED; while it is testing, they see SSO_CONNECTION_TESTING.
    • An SSO identity is never linked to an existing password account at the same address. Somebody who already has a password account here and then signs in through your identity provider ends up with a second, separate account. SCIM does not change that.
    • A connection takes either a metadata URL or pasted metadata XML. Prefer the URL: re-saving the connection re-reads it, while a pasted document has to be replaced by hand.
    • We do not refresh provider metadata on a schedule. A daily job reads the identity provider's signing certificate expiry from the metadata and e-mails the organization's owner before it lapses. After your provider rotates the certificate, open the connection in the console and save it again, which re-reads the metadata URL. If the metadata was pasted as XML, paste the new document.
    • A sign-in redirect target has to be on our allow list.
    • The console shows the owner the service provider values with copy buttons, the claimed and verified domains with the DNS TXT record to publish, the connection with its display name, provider template, entity id and certificate expiry, the sign-in policy, the provisioning tokens, and an audit list with an export button.
    • There is no SIEM streaming. The audit list exports from the console, and that is where provisioning activity on our side can be reviewed.
    • The e-mail attribute names are tried first, in the order documented on the sign-on page. The NameID is the fallback, used only when no e-mail attribute arrives, so a wrong NameID on its own does not break a connection that maps an e-mail attribute.

    Stuck on something this page does not cover? Write to [email protected] and quote the error text on screen. Enterprise is the plan that carries single sign-on.

    Screens and field names belong to the identity provider and change without telling us. Where this page and their own documentation disagree, theirs is right, and we would like to hear about it.