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

# SSO using OIDC

> Configure Google Workspace as your identity provider for Vikat Enterprise using OAuth 2.0 / OIDC.

## Prerequisites

* A Google Workspace domain with **Super Admin** access to the Admin console
* A Google Cloud project where you can create OAuth clients and service accounts
* Vikat Enterprise deployed and accessible
* Your Vikat callback URL: `https://<your-vikat-domain>/login`
* Vikat [roles](../rbac) created for the roles you plan to map

***

## Step 1: Configure the OAuth consent screen

<Steps>
  <Step title="Open the OAuth consent screen">
    In the Google Cloud Console, go to **APIs & Services → OAuth consent screen**.

    <Frame caption="OAuth consent screen - choose Internal for Workspace-only access or External for all Google accounts.">
      <img src="https://mintcdn.com/vikat-ai/Ui4AlBSF379KQPi5/media/user-provisioning/gws-apis-and-services.png?fit=max&auto=format&n=Ui4AlBSF379KQPi5&q=85&s=19ec47860efd213f075a4239591ddb50" alt="Google Cloud Console APIs and Services section with OAuth consent screen option highlighted" width="3774" height="1484" data-path="media/user-provisioning/gws-apis-and-services.png" />
    </Frame>

    Choose **Internal** if you only want Workspace users, or **External** otherwise.

    Fill in the **App name**, **support email**, and **developer contact information**.
  </Step>

  <Step title="Add the required scopes">
    Add the following scopes:

    * `openid`
    * `profile`
    * `email`

    Click **Save and Continue**.
  </Step>
</Steps>

***

## Step 2: Create an OAuth client ID

<Steps>
  <Step title="Create a new credential">
    Go to **APIs & Services → Credentials** and click **Create credentials → OAuth client ID**.

    <Frame caption="Create credentials - select OAuth client ID to generate a client for Vikat.">
      <img src="https://mintcdn.com/vikat-ai/Ui4AlBSF379KQPi5/media/user-provisioning/gws-auth-client-creation.png?fit=max&auto=format&n=Ui4AlBSF379KQPi5&q=85&s=c2ae6a9e6c7fef13e43534d09d76b879" alt="Google Cloud Console Create credentials dropdown with OAuth client ID option" width="4368" height="2753" data-path="media/user-provisioning/gws-auth-client-creation.png" />
    </Frame>
  </Step>

  <Step title="Configure the OAuth client">
    Set the following values:

    | Field                             | Value                               |
    | --------------------------------- | ----------------------------------- |
    | **Application type**              | Web application                     |
    | **Name**                          | `Vikat Enterprise`                  |
    | **Authorized JavaScript origins** | `https://<your-vikat-domain>`       |
    | **Authorized redirect URIs**      | `https://<your-vikat-domain>/login` |

    Click **Create**.
  </Step>

  <Step title="Copy your credentials">
    Copy the **Client ID** and **Client Secret** - you will need them in [Step 5](#step-5-configure-vikat).
  </Step>
</Steps>

***

## Step 3: Create a service account for Directory API access (optional)

<Note>
  Skip this section if you only need SSO login and do not want directory-based user import or team sync.
</Note>

<Steps>
  <Step title="Create the service account">
    Go to **IAM & Admin → Service Accounts** and click **Create service account**.

    <Frame caption="Create a service account - the account is used to call the Admin Directory API on behalf of Vikat.">
      <img src="https://mintcdn.com/vikat-ai/Ui4AlBSF379KQPi5/media/user-provisioning/gws-service-account-id.png?fit=max&auto=format&n=Ui4AlBSF379KQPi5&q=85&s=868d1dc7f319fed5a4bdacb4f385d115" alt="Google Cloud Console Service Accounts page with Create service account button" width="3488" height="2090" data-path="media/user-provisioning/gws-service-account-id.png" />
    </Frame>

    Give it a name (e.g. `vikat-provisioning`). Skip the **Grant this service account access to project** step - no GCP IAM roles are required; access is granted via domain-wide delegation in Step 4.
  </Step>

  <Step title="Generate a JSON key">
    Open the service account, go to **Keys → Add Key → Create new key**, and select **JSON**.

    <Frame caption="Create a new JSON key - download and store the file securely. This is the only time you can download it.">
      <img src="https://mintcdn.com/vikat-ai/Ui4AlBSF379KQPi5/media/user-provisioning/gws-service-key-creation.png?fit=max&auto=format&n=Ui4AlBSF379KQPi5&q=85&s=f3c74a9cef91c2b099755e5a4f54a016" alt="Service account Keys tab with Add Key dropdown and Create new key option selected" width="5418" height="2492" data-path="media/user-provisioning/gws-service-key-creation.png" />
    </Frame>

    Download and store the JSON key file securely.
  </Step>

  <Step title="Copy the Unique ID">
    From the service account **Details** tab, copy the **Unique ID** - a numeric value, **not** the email or the OAuth Client ID.
  </Step>
</Steps>

***

## Step 4: Enable the Admin SDK and set up domain-wide delegation (optional)

<Note>
  Required only if you created a service account in Step 3.
</Note>

<Steps>
  <Step title="Enable the Admin SDK API">
    Go to **APIs & Services → Library**, search for **Admin SDK API**, and click **Enable**.
  </Step>

  <Step title="Configure domain-wide delegation">
    In the [Google Admin Console](https://admin.google.com), go to **Security → Access and data control → API controls → Manage Domain Wide Delegation**.

    <Frame caption="Domain-wide delegation - authorize the service account to call the Directory API on behalf of an admin user.">
      <img src="https://mintcdn.com/vikat-ai/Ui4AlBSF379KQPi5/media/user-provisioning/gws-domain-wide-delegation.png?fit=max&auto=format&n=Ui4AlBSF379KQPi5&q=85&s=1863cdcfda221f32b73d1909309ebcd4" alt="Google Admin Console Domain-Wide Delegation page with Add new entry button" width="3868" height="2314" data-path="media/user-provisioning/gws-domain-wide-delegation.png" />
    </Frame>

    Click **Add new** and enter:

    * **Client ID**: the service account Unique ID from Step 3
    * **OAuth scopes** (copy all three, comma-separated):

    ```
    https://www.googleapis.com/auth/admin.directory.user.readonly,
    https://www.googleapis.com/auth/admin.directory.group.readonly,
    https://www.googleapis.com/auth/admin.directory.group.member.readonly
    ```

    Click **Authorize**.

    <Note>
      Domain-wide delegation requires impersonating an admin user. Choose an admin email that will persist (e.g. a dedicated `sso-admin@company.com`) - Vikat uses this as the **Admin Email** in Step 5.
    </Note>
  </Step>
</Steps>

***

## Step 5: Configure Vikat

<Steps>
  <Step title="Open User Provisioning and choose Google Workspace">
    In your Vikat dashboard, go to **Governance** → **User Provisioning**.

    Select **Google Workspace** as the identity provider and click **Next**.
  </Step>

  <Step title="Fill in the provider configuration">
    <Frame caption="Provider Configuration - enter your Google OAuth credentials and optional service account details.">
      <img src="https://mintcdn.com/vikat-ai/Ui4AlBSF379KQPi5/media/user-provisioning/gws-form.png?fit=max&auto=format&n=Ui4AlBSF379KQPi5&q=85&s=9f518a53e880c26ac6339202df142cb1" alt="Vikat Provider Configuration form for Google Workspace showing Domain, Client ID, Client Secret, and service account fields" width="2868" height="4702" data-path="media/user-provisioning/gws-form.png" />
    </Frame>

    | Field                      | Value                                                     |
    | -------------------------- | --------------------------------------------------------- |
    | **Domain**                 | Your Google Workspace primary domain (e.g. `company.com`) |
    | **Client ID**              | OAuth Client ID from Step 2                               |
    | **Client Secret**          | OAuth Client Secret from Step 2                           |
    | **Audience**               | Optional override - defaults to Client ID                 |
    | **Admin Email**            | Admin user to impersonate for Directory API (Step 4)      |
    | **Service Account Source** | Paste JSON / Environment variable / File path             |

    Click **Verify & Next** to confirm the connection.
  </Step>

  <Step title="Discover claims">
    On the Attribute Mapping screen, click **Discover Claims**.

    Vikat opens a sign-in popup - no session is created.

    Once you authenticate, it returns the exact claims your Google tenant is sending in the JWT.

    Use this to confirm which attributes (e.g. `hd` for hosted domain, `email`, `groups`) are present before building your mappings.
  </Step>

  <Step title="Set up attribute mappings">
    Use the sections below the claim list to map Google claim values to Vikat roles, teams, and business units.

    **Attribute-to-Role Mappings**

    Map a claim value to a Vikat role.

    * All matching rules are evaluated - if multiple rules match, the role with the highest permissions is assigned
    * If no rule matches, the user is not assigned a role and login is denied

    **Attribute-to-Team Mappings**

    Map a claim value to a Vikat team. All matching rules apply.

    * Use a specific value (e.g. `engineering`) to map that exact claim value to a named Vikat team
    * Use `*` as the value to sync the claim value directly as the team name
    * Use `${*}` to extract part of the string - e.g. `Vikat Playground: ${*} Team` matches `Vikat Playground: Alpha Team` and creates team **Alpha**

    **Attribute-to-Business Unit Mappings**

    Same wildcard support as team mappings.

    * Use a specific value (e.g. `platform`) to map that exact claim value to a named Vikat business unit
    * Use `${*}` to extract a substring as the business unit name - e.g. `Vikat Playground: ${*} BU` matches `Vikat Playground: Alpha BU` and creates business unit **Alpha**
    * When a rule matches, the resolved business unit is assigned to all of that user's teams
    * Manually assigned teams are left unchanged

    <Frame caption="Attribute Mapping - configure role, team, and business unit rules based on the claims Google sends.">
      <img src="https://mintcdn.com/vikat-ai/vhQZJbki-34ggGhE/media/user-provisioning/attribute-to-entity-mapping.png?fit=max&auto=format&n=vhQZJbki-34ggGhE&q=85&s=71dff3b2ebb7eb10dfc699c7d521385b" alt="Vikat Attribute Mapping screen showing role, team, and business unit mapping rules" width="1444" height="2524" data-path="media/user-provisioning/attribute-to-entity-mapping.png" />
    </Frame>

    <Frame caption="Custom attribute mapping - map any custom claim from Google to a Vikat role, team, or business unit.">
      <img src="https://mintcdn.com/vikat-ai/vhQZJbki-34ggGhE/media/user-provisioning/custom-attribute-mapping.png?fit=max&auto=format&n=vhQZJbki-34ggGhE&q=85&s=0375722572a80ae959d8793bb4381a5c" alt="Vikat custom attribute mapping configuration" width="1639" height="899" data-path="media/user-provisioning/custom-attribute-mapping.png" />
    </Frame>

    Click **Next** when done.
  </Step>

  <Step title="Review and enable">
    Review your configuration on the final screen, then click **Enable**.

    <Warning>
      Restart your Vikat server after enabling for the changes to take effect.
    </Warning>
  </Step>
</Steps>

***

## How background sync works

Vikat uses the Directory API credentials from this setup to sync users in the background every **24 hours**. During that sync, Vikat reconciles imported users, role mappings, team mappings, and business-unit mappings from Google Workspace.

Every **15 minutes**, Vikat also refreshes active OIDC sessions. If a session cannot be refreshed, Vikat checks with Google whether the user is still active; if Google reports the user as inactive, Vikat decommissions that user locally.

***

## Optional next steps

**Real-time user sync** - OIDC provisions users on first login and the Directory API runs a 24-hour background sync. For closer to real-time provisioning via SCIM, see [SCIM with Google Workspace](./scim).

***

## Troubleshooting

**`admin_policy_enforced` or `access_denied` during OAuth** - the Workspace admin has blocked third-party OAuth apps. In the Admin Console, go to **Security → Access and data control → API controls** and allow the Vikat OAuth client.

**`unauthorized_client: Client is unauthorized to retrieve access tokens`** - the service account Unique ID and scopes in Domain-Wide Delegation don't match. Re-enter the numeric Unique ID from the service account Details tab (not the client email or OAuth client ID).

**`Not Authorized to access this resource/api` from Directory API** - the impersonated `adminEmail` is missing the **User Management Admin** role. Promote them in Admin Console → Admin roles. Also confirm the Admin SDK API is enabled in the Cloud project.

**`domain_mismatch`** - use the primary domain, not an alias.

**Users see a consent prompt every login** - on the OAuth consent screen, ensure the app is **Published** (or **Internal** for Workspace-only) so it doesn't stay in testing mode.
