Single sign-on

    Google Workspace SAML single sign-on

    Connect Google Workspace to CCTVplanner with a custom SAML app, so your people sign in with their Workspace account. When you finish, the domains are verified, the attribute mapping is in place, the connection has passed its test, and you know what to do when Google rotates its signing certificate.

    Before you start

    • Super administrator rights in the Google Admin console
    • An Enterprise plan on CCTVplanner, with an active subscription
    • Owner or administrator access to the CCTVplanner organization console at cctvplanner.io/organization
    • The ability to publish a DNS TXT record for each e-mail domain you will claim
    • A second factor enrolled on the owner account, if you intend to make single sign-on required

    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

      Verify your e-mail domains in the CCTVplanner console

      Open cctvplanner.io/organization and add every domain your people sign in with. Google Workspace secondary and alias domains count as separate domains here.

      The console lists each claimed domain together with the DNS TXT record to publish for it. Publish the record, then run the check in the console.

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

      The record shape is in the table below. The console is authoritative for the token.

      Record typeTXT
      Name_cctvplanner-challenge. followed by your domain
      Valuecctvplanner-verify= followed by the token the console shows

      If a person signs in as [email protected], alias.example needs its own record and its own verification, or that person gets SSO_EMAIL_OUTSIDE_DOMAIN.

    2. 2

      Create the custom SAML app in Google

      In the Google Admin console, go to Menu, then Apps, then Web and mobile apps.

      Choose Add app, then Add custom SAML app.

      Give it a name your people will recognize on Google's app screens, for example CCTVplanner.

      An icon is optional and changes nothing about the protocol.

    3. 3

      Take the Google identity provider metadata

      The next page is Google Identity Provider details. Option 1 is Download the IDP metadata. Option 2 is the SSO URL and Entity ID as text, with the Certificate as a separate download and a SHA-256 fingerprint alongside.

      Download the IDP metadata and keep the XML file. That one file carries the SSO URL, the issuer and the signing certificate.

      Our console accepts either a metadata URL or pasted metadata XML for a connection. Prefer the URL where you have one: re-saving the connection re-reads it, while a pasted document has to be replaced by hand. Google's documentation for a custom SAML app offers a download and does not document a metadata URL, so plan on pasting the XML.

      You do not need the SHA-256 fingerprint. It is there for service providers that ask for a fingerprint instead of a certificate.

    4. 4

      Fill in the service provider details

      Press Continue to reach Service provider details.

      Copy the ACS URL and Entity ID out of the CCTVplanner console with the copy buttons there. The console is authoritative for both. The values in the table below are so you recognize them.

      Leave Start URL empty unless you want Google's app launcher to land people somewhere specific. Start URL sets RelayState, and the redirect target has to be on our allow list.

      Set Name ID format and Name ID before you save.

      ACS URLhttps://auth.cctvplanner.io/auth/v1/sso/saml/acs
      Entity IDhttps://auth.cctvplanner.io/auth/v1/sso/saml/metadata
      Start URLleave empty
      Signed responseunchecked
      Name ID formatEMAIL
      Name IDBasic Information > Primary email

      We read the e-mail attribute names first, in the order shown in the attribute table near the end of this page, and fall back to the Name ID only when no e-mail attribute arrives. So a Name ID on a non-address value does not by itself break a connection that maps an e-mail attribute. Map the e-mail attribute in the next step either way.

    5. 5

      Map the attributes

      Press Continue to reach Attribute mapping, then use Add mapping once per row in the table below.

      On the left pick the Google Directory attribute. On the right type the App attribute exactly as written, including the capital letter in firstName and lastName, and with no spaces.

      Google's group membership mapping is a separate, optional row. We read a groups claim but do not use it to set roles, so leave it out unless you want it in the assertion for your own audit reasons. Google caps group membership mapping at 75 groups.

      Press Finish.

      Basic Information > Primary emailemail
      Basic Information > First namefirstName
      Basic Information > Last namelastName

      Use the names exactly as in the table. We match the attribute name literally.

    6. 6

      Turn the app on for the right people

      Back on the app page, open User access.

      Select On for everyone, or pick an organizational unit or group and set its service status to On.

      Press Save. Google's own wording on timing: changes can take up to 24 hours but typically happen more quickly.

      Anyone the app is off for never reaches us. Google shows its own error page and no assertion is issued.

    7. 7

      Create the connection in CCTVplanner and set the policy

      In the organization console, create the connection: a display name, the provider template, and the metadata. Paste the XML from step three, or give the metadata URL if you have one.

      A new connection starts in testing. While it is testing, ordinary sign-ins through it are refused with SSO_CONNECTION_TESTING. That is a different state from disabled, which refuses with SSO_PROVIDER_DISABLED.

      Choose whether just-in-time provisioning is on. With it on, a first successful sign-in from a verified domain creates the account at the role you pick, if a seat is free. With it off, people have to exist here first.

      Set the sign-in policy. Optional lets passwords and single sign-on coexist. Required stops password sign-in for everyone at your verified domains.

      Set the session cap if 24 hours is longer than you want. Access tokens live fifteen minutes regardless.

      Required keeps one escape hatch: the owner may still use a password, but only with a verified second factor. Enrol that factor before you switch to Required, or you will meet SSO_OWNER_MFA_REQUIRED and will have to get back in through single sign-on to change the policy.

    8. 8

      Test the connection, then switch it on

      Run the test on the connection in the organization console. The ordered flow, and what it does to your own session, is in the proof list below.

      A connection can only be switched on after its test passes.

      Switch it on, have one real person sign in, and only then move the sign-in policy to Required if you want it.

    9. 9

      Plan for the certificate rotation

      Google X.509 certificates for SAML apps have a five-year lifetime, and you can hold two at a time. They live under Menu, Security, Authentication, SSO with SAML applications, which is a page separate from the app itself.

      A daily job on our side reads the identity provider's signing certificate expiry out of the connection's metadata and e-mails the organization owner before it lapses. The metadata itself is not refreshed for you.

      When Google rotates the certificate, select the new certificate for this app in its Service provider details, then open the connection in our console and save it again, which re-reads the metadata URL. If the metadata was pasted as XML, paste the new document.

      Google's own wording on timing: after you replace a certificate, it may take up to 24 hours for the new certificate to be available for use by your SAML applications.

      Editing an active connection's metadata puts it back into testing, so sign-ins through it are refused with SSO_CONNECTION_TESTING until you run the test again and switch the connection on. Do the rotation in a window where that is acceptable.

    Name ID and attribute mapping

    Name IDBasic Information > Primary email
    Name ID formatEMAIL
    Basic Information > Primary emailemail
    Basic Information > First namefirstName
    Basic Information > Last namelastName
    Group membership (optional)groups

    Prove it works

    1. Leave the connection in testing. Until it is switched on, anyone signing in through it is refused with SSO_CONNECTION_TESTING, so nobody is caught by a half-finished mapping.
    2. In the organization console, open the connection and press the test button. Do this as the owner, in the session you already have.
    3. The console opens Google in a new browser tab. Sign in there with your own Workspace account.
    4. That sign-in creates a twin account: a second, separate CCTVplanner account at your own address, held by Google. It occupies no seat, because an SSO identity is never linked to an existing password account.
    5. The test tab confirms the result, signs that twin account out again and hands the outcome back to the console tab you started from, which restores your own session.
    6. Read the outcome in the console. If the test failed, fix it in Google or in the connection, save, and run the test again.
    7. Switch the connection on. Only a passed test allows that.
    8. Have one person at a verified domain sign in for real at cctvplanner.io and confirm their name and address are right. If just-in-time provisioning is off, add that person in the console first, or they are refused with SSO_JIT_DISABLED.
    9. Only when a real sign-in works should you move the sign-in policy to Required.

    When sign-in fails

    What you seeWhyWhat to do
    SSO_PROVIDER_UNKNOWNThe address is not at a domain attached to any connection, usually an alias domain nobody claimed, or the connection was never created.Add and verify that exact domain in the organization console with its own TXT record, then retry.
    SSO_EMAIL_OUTSIDE_DOMAINThe assertion carried an address at a Workspace secondary or alias domain that is not verified here. This is checked at sign-in and again at every token refresh.Verify that domain, or set Name ID to Basic Information > Primary email and map the primary address so that is what we see.
    SSO_CONNECTION_TESTINGThe connection is in testing. A new connection starts there, and saving the metadata of an active connection puts it back there.Run the test on the connection and switch it on once the test passes.
    SSO_PROVIDER_DISABLEDThe connection is disabled. This is a different state from testing, with a different message.Enable the connection in the organization console. If it was disabled deliberately, people sign in with passwords until it is back on.
    SSO_ACS_FAILED right after the Google account chooserThe assertion was refused at our assertion consumer service. In a Google deployment the usual cause is a signing certificate that does not match the one in the metadata we hold, or an assertion with no usable address in it.Put the current metadata into the connection again. Confirm Name ID format EMAIL and the Primary email to email mapping, then start the sign-in fresh instead of reusing the old tab.
    Google shows its own error page saying the user does not have access to this app, and CCTVplanner never loadsThe app's service status is Off for that person's organizational unit, so Google never issued an assertion.In Web and mobile apps, open the app, open User access and turn the service On for that organizational unit or group. Changes can take up to 24 hours but typically happen more quickly.
    SSO_JIT_DISABLEDJust-in-time provisioning is off and the person does not exist in the organization yet.Add the person in the console, or turn just-in-time provisioning on and pick the role new arrivals should get.
    SSO_NO_SEATSThere is no free seat, or no free seat at the role just-in-time provisioning is set to create.Free a seat, buy more, or set the default role to one you still have seats for.
    SSO_ACCOUNT_SUSPENDEDThe account was suspended by the organization, by hand or by a directory deactivation. The seat stays occupied and the projects stay with the organization.Reinstate the account in the console, or in the directory that deactivated it.
    SSO_REQUIRED on the password formThe sign-in policy is Required and this person is at a verified domain.Send them through the single sign-on button. If the identity provider is down and they need a password, the owner can move the policy back to optional.
    SSO_OWNER_MFA_REQUIRED or SSO_OWNER_MFA_INCOMPLETE for the ownerRequired lets the owner keep a password only with a verified second factor. The first token issued after a password is at the lower assurance level until the second factor is finished.Enrol a second factor on the owner account, and finish the second factor prompt in the same sign-in.
    SSO_SESSION_EXPIRED in the middle of the working day, although Google's own session is still aliveOur session cap is a separate limit. It defaults to 24 hours and your organization may have shortened it.Sign in again. If the cap is too aggressive for your people, raise it in the console, up to the 24 hour default.
    SSO_SESSION_IDLEThe session ended after inactivity.Sign in again.
    SSO_SUBSCRIPTION_INACTIVE for everyone, with no configuration changeThe organization's subscription is not active, and single sign-on is an Enterprise feature.Settle the billing issue in the console. Single sign-on works again once the subscription is active.
    Sign-in worked in testing, then everyone failed at once weeks laterA Google certificate was rotated or expired, and the metadata we hold still carries the old one.Put the current metadata into the connection, run the test again and switch the connection back on. Act on the expiry e-mail we send the owner rather than waiting for the outage.

    Worth knowing

    • Google Workspace cannot drive our SCIM endpoint. Google documents automated provisioning only for apps in its catalog, and a custom SAML app offers no provisioning settings. On Google, plan on just-in-time provisioning plus the console for joiners and leavers, or point a directory that does speak SCIM at our endpoint. Provisioning tokens are created in the organization console.
    • Identity provider initiated sign-in is accepted. What you control is the redirect target, which has to be on our allow list. Google's Start URL field is what sets that target.
    • A sign-in through Google never joins an existing password account at the same address. The identity provider holds its own account, so a person who already had a CCTVplanner password account ends up with two accounts at one address. Decide which one your people are meant to use before you switch the connection on.
    • The organization console also shows the service provider values with copy buttons, your claimed and verified domains, 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.
    • Things we do not have, so you can plan around them: no OpenID Connect, no IP allow list, no SIEM streaming, no group to role mapping, no SCIM Groups, no uptime SLA, no SOC 2 or ISO 27001, and no third-party penetration test report.

    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.