Skip to main content

Staff SSO

Overview

Deepdesk staff members (employees) use a dedicated Single Sign-On (SSO) flow to access tenant admin dashboards. This allows internal staff to log in to any tenant account using their Google Workspace credentials, without needing separate accounts for each tenant.

The Staff SSO flow involves three services:

  • Google - Identity provider for Deepdesk staff (Google Workspace)
  • Onboarding Service - Acts as an OAuth2/OIDC provider (IdP) for admin dashboards
  • Admin Dashboard - Tenant-specific admin interface that acts as an OAuth2 client

Architecture

The following diagram shows the relationship between the three components:

Component Roles

ComponentRoleDescription
Google WorkspaceIdentity ProviderAuthenticates Deepdesk staff using Google accounts
Onboarding ServiceOAuth2/OIDC ProviderActs as an intermediate IdP, wrapping Google authentication and adding Deepdesk-specific claims
Admin DashboardOAuth2 ClientEach tenant's admin interface that consumes the OIDC tokens

Authentication Flow

The following sequence diagram shows the complete Staff SSO flow:

Flow Steps

1. Authentication Initiation

When a staff user accesses a tenant admin dashboard (e.g., acme.deepdesk.com/admin) without being authenticated, they are redirected to the SSO login endpoint.

2. Admin Dashboard Initiates OAuth Flow

The admin dashboard's google_sso_start view constructs an OAuth2 authorization request to the Onboarding Service:

flow = OAuth2WebServerFlow(
auth_uri=f"{settings.ONBOARDING_URL}/oauth/authorize/",
redirect_uri=callback_url,
client_id=settings.ONBOARDING_CLIENT_ID,
scope="openid",
)
info

Despite being named google_sso_start, this function actually initiates an OAuth flow with the Onboarding Service, not directly with Google. The Onboarding Service acts as the OAuth provider (IdP).

3. Onboarding Service Authentication

If the staff user is not already authenticated with the Onboarding Service, they are redirected to Google SSO:

  1. SingleSignOnStartView constructs a Google OAuth2 authorization URL
  2. User authenticates with Google
  3. SingleSignOnEndView receives the callback with authorization code
  4. Onboarding exchanges the code with Google for tokens
  5. User is created/logged in to the Onboarding Service

4. OAuth Authorization Code Return

Once authenticated, the Onboarding Service (using Django OAuth Toolkit) generates an authorization code and redirects back to the Admin Dashboard.

5. Token Exchange

The Admin Dashboard exchanges the authorization code for tokens:

flow = OAuth2WebServerFlow(
redirect_uri=request.build_absolute_uri(reverse("sso_end")),
token_uri=f"{settings.ONBOARDING_URL}/oauth/token/",
client_id=settings.ONBOARDING_CLIENT_ID,
client_secret=settings.ONBOARDING_CLIENT_SECRET,
scope="openid",
)
credentials = flow.step2_exchange(code)

6. User Provisioning

The Admin Dashboard extracts claims from the ID token and creates/updates the user:

ClaimDescription
subUnique identifier for the user
emailUser's email address
first_nameUser's first name
last_nameUser's last name
is_staffWhether the user has staff access
is_superuserWhether the user has superuser access
groupsList of group memberships (e.g., "Customer Success")

7. Group Assignment

Special handling is applied for Customer Success staff:

  • Users in the "Customer Success" group receive is_staff=True
  • Their account is set to None, giving them access to all tenant accounts
  • They are added to the DEEPDESK_CUSTOMER_SUCCESS group

Configuration

Onboarding Service

The Onboarding Service requires the following environment variables for Google OAuth:

VariableDescription
DJANGO_ADMIN_SSO_OAUTH_CLIENT_IDGoogle OAuth Client ID
DJANGO_ADMIN_SSO_OAUTH_CLIENT_SECRETGoogle OAuth Client Secret

Admin Dashboard

Each tenant's Admin Dashboard requires:

VariableDescription
ONBOARDING_URLURL of the Onboarding Service (e.g., https://onboarding.deepdesk.com)
ONBOARDING_CLIENT_IDOAuth Client ID for this tenant
ONBOARDING_CLIENT_SECRETOAuth Client Secret for this tenant

OIDC Claims

The Onboarding Service's custom OAuth2 validator adds Deepdesk-specific claims to the ID token:

class CustomOAuth2Validator(OAuth2Validator):
def get_additional_claims(self, request: Request) -> dict:
return {
"first_name": request.user.first_name,
"last_name": request.user.last_name,
"email": request.user.email,
"is_staff": request.user.is_staff,
"is_superuser": request.user.is_superuser,
}

These claims are sourced from the user's profile in the Onboarding Service, which is populated from their Google account.

Security Considerations

Session Management

  • The Admin Dashboard uses SameSite=Strict cookies for session management
  • To work around SameSite cookie restrictions during OAuth redirects, the final redirect uses an HTML meta refresh instead of a 302 redirect
  • Redirect URLs are stored in httponly and secure cookies
  • All redirect URLs are verified against trusted domains before use

Token Validation

  • The OAuth2 flow uses client secrets for token exchange
  • ID tokens are validated using the OAuth2 library

Implementation References

See Also