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
- Bifrost Enterprise deployed and accessible
- Your Bifrost callback URL:
https://<your-bifrost-domain>/login - Bifrost roles created for the roles you plan to map
Step 1: Configure the OAuth consent screen
Open the OAuth consent screen
In the Google Cloud Console, go to APIs & Services → OAuth consent screen.
Choose Internal if you only want Workspace users, or External otherwise.Fill in the App name, support email, and developer contact information.

Step 2: Create an OAuth client ID
Create a new credential
Go to APIs & Services → Credentials and click Create credentials → OAuth client ID.

Configure the OAuth client
Set the following values:
Click Create.
| Field | Value |
|---|---|
| Application type | Web application |
| Name | Bifrost Enterprise |
| Authorized JavaScript origins | https://<your-bifrost-domain> |
| Authorized redirect URIs | https://<your-bifrost-domain>/login |
Copy your credentials
Copy the Client ID and Client Secret - you will need them in Step 5.
Step 3: Create a service account for Directory API access (optional)
Skip this section if you only need SSO login and do not want directory-based user import or team sync.
Create the service account
Go to IAM & Admin → Service Accounts and click Create service account.
Give it a name (e.g.

bifrost-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.Generate a JSON key
Open the service account, go to Keys → Add Key → Create new key, and select JSON.
Download and store the JSON key file securely.

Step 4: Enable the Admin SDK and set up domain-wide delegation (optional)
Required only if you created a service account in Step 3.
Enable the Admin SDK API
Go to APIs & Services → Library, search for Admin SDK API, and click Enable.
Configure domain-wide delegation
In the Google Admin Console, go to Security → Access and data control → API controls → Manage Domain Wide Delegation.
Click Add new and enter:Click Authorize.

- Client ID: the service account Unique ID from Step 3
- OAuth scopes (copy all three, comma-separated):
Domain-wide delegation requires impersonating an admin user. Choose an admin email that will persist (e.g. a dedicated
[email protected]) - Bifrost uses this as the Admin Email in Step 5.Step 5: Configure Bifrost
Open User Provisioning and choose Google Workspace
In your Bifrost dashboard, go to Governance → User Provisioning.Select Google Workspace as the identity provider and click Next.
Fill in the provider configuration

| 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 |
Discover claims
On the Attribute Mapping screen, click Discover Claims.Bifrost 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.Set up attribute mappings
Use the sections below the claim list to map Google claim values to Bifrost roles, teams, and business units.Attribute-to-Role MappingsMap a claim value to a Bifrost role.

Click Next when done.
- 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
- Use a specific value (e.g.
engineering) to map that exact claim value to a named Bifrost team - Use
*as the value to sync the claim value directly as the team name - Use
${*}to extract part of the string - e.g.Bifrost Playground: ${*} TeammatchesBifrost Playground: Alpha Teamand creates team Alpha
- Use a specific value (e.g.
platform) to map that exact claim value to a named Bifrost business unit - Use
${*}to extract a substring as the business unit name - e.g.Bifrost Playground: ${*} BUmatchesBifrost Playground: Alpha BUand 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


How background sync works
Bifrost uses the Directory API credentials from this setup to sync users in the background every 24 hours. During that sync, Bifrost reconciles imported users, role mappings, team mappings, and business-unit mappings from Google Workspace. Every 15 minutes, Bifrost also refreshes active OIDC sessions. If a session cannot be refreshed, Bifrost checks with Google whether the user is still active; if Google reports the user as inactive, Bifrost 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.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 Bifrost 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.
