OAuth 2.0 with Proof Key for Code Exchange (PKCE) provides a secure authentication framework for integrating Sigma with cloud data platforms. When embedding Sigma analytics in your applications or implementing secure data access patterns, OAuth 2.0 with PKCE ensures that users authenticate with their own credentials and access only the data they're authorized to see.

This QuickStart explains the key concepts, security benefits, and implementation considerations for using OAuth 2.0 with PKCE in Sigma deployments. You'll understand why OAuth matters for both native and embedded analytics, how PKCE enhances security, and what patterns work best for different Sigma use cases.

This is a conceptual QuickStart designed to build foundational understanding and is not "hands-on".

For more information on Sigma's product release strategy, see Sigma product releases

If something doesn't work as expected, here's how to contact Sigma support

Target Audience

The typical audience for this QuickStart includes:

Prerequisites

Footer

What is OAuth 2.0?

OAuth 2.0 is an industry-standard authorization framework that enables applications to obtain limited access to user accounts on an HTTP service. Rather than sharing passwords, OAuth 2.0 allows users to grant applications access to their resources through secure token-based authentication.

Key Components

Resource Owner (User):
The person who owns the data and grants access to it. In Sigma deployments, this is typically an employee or customer accessing data through Sigma workbooks or dashboards embedded in your application.

Client (Application):
The application requesting access to protected resources on behalf of the user. When using Sigma Embedding, this is your custom application hosting embedded Sigma content (dashboards, workbooks, or visualizations).

Authorization Server:
The server that authenticates the user and issues access tokens after successful authorization. For Sigma integrations, this is typically your cloud data warehouse's OAuth service (Snowflake, BigQuery, Redshift, etc.) or your corporate identity provider (Okta, Azure AD, etc.).

Resource Server:
The server hosting the protected resources (data). For Sigma users, this is your cloud data warehouse (Snowflake, BigQuery, Redshift, Azure Synapse, etc.) that Sigma queries on the user's behalf.

The Authorization Flow

Here's how OAuth 2.0 works when a user accesses embedded Sigma content:

  1. User initiates action: User clicks on embedded Sigma dashboard in your application
  2. Authorization request: Your application redirects user to the authorization server (this could be your corporate SSO provider like Okta/Azure AD for federated identity, or directly to the data warehouse OAuth endpoint)
  3. User authentication: User logs in with their credentials
  4. Authorization grant: User approves Sigma's access request to query data on their behalf
  5. Token exchange: Your application receives an access token from the authorization server (if using federated identity, your application exchanges the SSO token for a data warehouse token)
  6. Sigma queries data: Sigma uses the data warehouse token to query with the user's permissions

Connection-Level vs Organization-Level OAuth

When implementing OAuth with Sigma, you have two primary approaches for managing authentication:

Connection-Level OAuth:

Organization-Level OAuth:

Why OAuth 2.0 for Sigma Deployments?

Security:
No database credentials stored in Sigma or your application - users authenticate directly with the data platform

Granular Control:
Each Sigma user queries data with their own permissions - see only what they're authorized to access

Audit Trail:
Detailed logging shows which user ran which Sigma queries and when, meeting governance requirements

User Experience:
Single sign-on enables seamless access to embedded Sigma content without additional logins

Compliance:
Meets regulatory requirements (SOC 2, HIPAA, GDPR) for data access controls and auditability

Footer

What is PKCE?

Proof Key for Code Exchange (PKCE, pronounced "pixie") is an extension to OAuth 2.0 that provides additional security for public clients, particularly browser-based and mobile applications. When using Sigma, PKCE prevents authorization code interception attacks that could compromise user data access.

The Security Problem PKCE Solves

Traditional OAuth 2.0 authorization code flow assumes the client can securely store a client secret. However, public clients like browser-based and mobile applications cannot securely store secrets because:

This creates a vulnerability where an attacker could intercept the authorization code and exchange it for an access token, gaining unauthorized access to your data warehouse.

How PKCE Works

PKCE adds two cryptographic elements to the authorization flow:

Code Verifier:
A cryptographically random string (43-128 characters) generated by the client at the start of the flow. This remains secret on the client.

Code Challenge:
A transformed version of the code verifier, created using SHA-256 hashing. This is sent to the authorization server.

PKCE Flow Step-by-Step

  1. Client generates code verifier: Random string created at flow start
  2. Client creates code challenge: SHA-256 hash of code verifier
  3. Authorization request with challenge: Client sends code challenge to auth server
  4. User authenticates: Standard OAuth login flow occurs
  5. Authorization code returned: Server sends code back to client
  6. Token request with verifier: Client sends authorization code AND original code verifier
  7. Server validates: Server hashes verifier, compares to stored challenge
  8. Token issued: If match confirmed, access token provided

PKCE Benefits

No Client Secret Required: Eliminates the need to store secrets in public clients

Prevents Code Interception: Even if authorization code is stolen, it's useless without the verifier

Backward Compatible: Works with existing OAuth 2.0 infrastructure

Industry Best Practice: Recommended by OAuth 2.0 Security Best Practices RFC

Footer

Real-World Use Case: Embedded Sigma Analytics

Consider an enterprise scenario where you want to embed Sigma dashboards into your customer portal:

Without OAuth/PKCE:

With OAuth/PKCE:

Token Lifecycle Management

Access Tokens

Refresh Tokens

Token Expiration Flow in Sigma

  1. User views embedded Sigma dashboard, Sigma queries data with access token
  2. Data warehouse returns "token expired" error
  3. Your application uses refresh token to request new access token from authorization server
  4. New access token issued without user re-authentication
  5. Sigma retries the query with new token - user experience uninterrupted

Scopes and Permissions

OAuth 2.0 uses "scopes" to define what access a token grants. When Sigma integrates with data platforms, scopes determine what Sigma can do on the user's behalf:

Common Scope Examples for Sigma Integration:

OAuth scopes vary by data warehouse platform. Here are examples from commonly used platforms:

Snowflake:

Databricks:

BigQuery:

General Concepts Across Platforms:

Note: Consult your data platform's OAuth documentation for specific scope names and definitions. Most cloud data warehouses support similar security concepts with platform-specific naming conventions.

Scope Request Flow:

  1. Your application requests specific scopes when initiating OAuth flow
  2. Authorization server shows user what Sigma will be able to do
  3. User approves or denies the requested scopes
  4. Token is issued with only approved scopes
  5. Data warehouse enforces scope restrictions on all Sigma queries

Security Considerations

Token Storage:

Token Transmission:

Token Revocation:

Footer

Pattern 1: Connection-Level OAuth with PKCE (Direct User Authentication)

Scenario: Users authenticate directly with data platform before accessing Sigma using connection-level OAuth with PKCE

Flow:

  1. User accesses embedded Sigma dashboard in your application
  2. Application generates PKCE code challenge and redirects to data warehouse OAuth login
  3. User logs in with their data warehouse credentials
  4. Data warehouse issues access token to your application after validating PKCE verifier
  5. Application passes encrypted token to Sigma via embed API
  6. Sigma queries data warehouse using user's individual token and permissions

Pros:

Cons:

Pattern 2: Service Account with Row-Level Security

Scenario: Sigma connects using shared service account, data filtered by user attributes

Flow:

  1. Your application authenticates with shared warehouse service account
  2. User identity passed via Sigma embed parameters (user attributes)
  3. Sigma includes user attributes in SQL queries (e.g., WHERE user_id = ?)
  4. Data warehouse row-level security or custom SQL enforces RLS based on user context
  5. Query results automatically filtered per user permissions

Pros:

Cons:

Pattern 3: Federated Identity

Scenario: Corporate SSO integrated with both Sigma and data platform

Flow:

  1. User logs into your application via corporate SSO (Okta, Azure AD, etc.)
  2. Your application exchanges SSO token for data warehouse OAuth token
  3. Data warehouse OAuth token passed to Sigma for embedded content
  4. Sigma uses token to query data - single identity across all systems
  5. User never sees additional login prompts

Pros:

Cons:

Choosing the Right Pattern for Sigma

Use Connection-Level OAuth with PKCE (Pattern 1) when:

Use Service Account with RLS when:

Use Federated Identity when:

Footer

Before implementing OAuth 2.0 with PKCE for your Sigma deployment, ensure your environment meets the necessary requirements and understand common challenges you'll encounter.

Platform Requirements

Your OAuth implementation requires support from both the authorization server (your data platform) and your application.

Authorization Server Must Support:

Your Application Must Support:

Footer

Let's walk through the four most common challenges teams face when implementing OAuth with Sigma, with practical solutions you can apply.

Challenge 1: Token Refresh Timing

The Problem:

Your embedded Sigma dashboard is working perfectly. A user is exploring data, building visualizations, when suddenly: "Authentication Error - Token Expired." The access token expired mid-session, breaking their workflow.

Why This Happens:

Access tokens typically expire after 60 minutes. If you wait for the token to expire before refreshing, users will see errors when Sigma tries to query data.

The Solution:

Implement proactive token refresh that runs before expiration.

Practical Example:

// Check token expiration every 5 minutes
setInterval(async () => {
  const tokenExpiry = getTokenExpiration();
  const now = Date.now();
  const timeUntilExpiry = tokenExpiry - now;

  // Refresh if less than 10 minutes remaining
  if (timeUntilExpiry < 10 * 60 * 1000) {
    await refreshAccessToken();
  }
}, 5 * 60 * 1000);

Best Practices:

Challenge 2: Redirect URI Management

The Problem:

OAuth requires exact redirect URI matching. You register https://app.example.com/callback with your data warehouse, but your staging environment uses https://staging.example.com/callback. Result? OAuth fails in staging with "redirect_uri_mismatch" error.

Why This Happens:

For security, authorization servers require exact matches between registered redirect URIs and the URI in your OAuth request. Different environments (dev/staging/prod) need different URIs.

The Solution:

Register separate OAuth applications for each environment and use environment variables.

Practical Example:

// config/oauth.js
const oauthConfig = {
  development: {
    clientId: process.env.DEV_OAUTH_CLIENT_ID,
    redirectUri: 'http://localhost:3000/oauth/callback'
  },
  staging: {
    clientId: process.env.STAGING_OAUTH_CLIENT_ID,
    redirectUri: 'https://staging.example.com/oauth/callback'
  },
  production: {
    clientId: process.env.PROD_OAUTH_CLIENT_ID,
    redirectUri: 'https://app.example.com/oauth/callback'
  }
};

const config = oauthConfig[process.env.NODE_ENV];

Best Practices:

Challenge 3: Secure Token Storage

The Problem:

A developer stores OAuth tokens in browser localStorage for convenience. Later, a security audit flags this as a critical XSS vulnerability - any malicious script can steal tokens and access your data warehouse.

Why This Happens:

localStorage is accessible to any JavaScript running on your page. If an attacker injects malicious code (XSS attack), they can steal tokens and impersonate users in Sigma.

The Solution:

Use httpOnly, secure cookies that JavaScript cannot access.

Practical Example:

// Backend: Set token as httpOnly cookie (Node.js/Express)
app.post('/oauth/callback', async (req, res) => {
  const tokens = await exchangeCodeForTokens(req.query.code);

  // Store access token in httpOnly cookie
  res.cookie('sigma_access_token', tokens.access_token, {
    httpOnly: true,    // JavaScript cannot access
    secure: true,      // HTTPS only
    sameSite: 'strict', // CSRF protection
    maxAge: 3600000    // 1 hour
  });

  // Store refresh token separately with longer expiry
  res.cookie('sigma_refresh_token', tokens.refresh_token, {
    httpOnly: true,
    secure: true,
    sameSite: 'strict',
    maxAge: 90 * 24 * 3600000  // 90 days
  });

  res.redirect('/dashboard');
});

Best Practices:

Challenge 4: Mobile Deep Linking

The Problem:

A user clicks your embedded Sigma dashboard in your mobile app. OAuth redirects them to Safari/Chrome for data warehouse login. After authenticating, they're stuck in the browser - the app doesn't resume, and the user is confused.

Why This Happens:

OAuth redirects users to the authorization server's web login. Mobile apps need special URL schemes to redirect users back from the browser to the app.

The Solution:

Implement universal links (iOS) or app links (Android) to seamlessly return users to your app.

Practical Example:

// iOS Universal Link Configuration (apple-app-site-association)
{
  "applinks": {
    "apps": [],
    "details": [
      {
        "appID": "TEAMID.com.example.app",
        "paths": ["/oauth/callback"]
      }
    ]
  }
}

// Handle OAuth callback in your app
func application(_ app: UIApplication,
                 continue userActivity: NSUserActivity,
                 restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {

  guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
        let url = userActivity.webpageURL,
        url.path == "/oauth/callback" else {
    return false
  }

  // Extract authorization code from URL
  let code = extractAuthCode(from: url)

  // Exchange for tokens and load Sigma embed
  exchangeCodeForTokens(code) { tokens in
    loadSigmaEmbed(with: tokens.accessToken)
  }

  return true
}

Best Practices:

Footer

Testing Your OAuth Implementation

Local Development:

Start by testing OAuth flows on your development machine:

// Use localhost for development
const devRedirectUri = 'http://localhost:3000/oauth/callback';

// Mock authorization server for unit tests
const mockAuthServer = {
  generateTokens: () => ({
    access_token: 'mock_access_token',
    refresh_token: 'mock_refresh_token',
    expires_in: 3600
  })
};

Key Tests to Run:

Staging Environment:

Register a separate OAuth application for staging and test with production-like data:

Production Monitoring:

Once deployed, monitor your OAuth implementation continuously:

// Log OAuth events (but never log tokens!)
logger.info('OAuth authorization started', {
  userId: user.id,
  timestamp: Date.now()
});

logger.info('Token refresh succeeded', {
  userId: user.id,
  expiresIn: 3600,
  scopes: ['sql', 'offline_access']
});

logger.error('Token refresh failed', {
  userId: user.id,
  errorType: 'invalid_grant',
  // DO NOT log the actual token or refresh token
});

Metrics to Monitor:

Footer

OAuth implementations must meet audit, privacy, and security requirements.

Audit Requirements

What to Log:

Practical Example:

// Audit log entry for Sigma query
{
  "timestamp": "2025-12-08T14:30:00Z",
  "event_type": "sigma_query_executed",
  "user_id": "john.doe@example.com",
  "data_platform": "snowflake",
  "query_type": "dashboard_load",
  "dashboard_id": "sales_metrics_q4",
  "scopes_used": ["session:role-any", "refresh_token"],
  "rows_returned": 1523
}

Retention: Retain audit logs according to your compliance requirements (typically 1-7 years).

Data Privacy

User Consent:

Users must understand what access they're granting when they authorize Sigma:

Privacy Controls:

Security Policies

Token Lifetime Policies:

Rate Limiting:

Prevent abuse by limiting OAuth requests:

// Example rate limit: 10 token refresh requests per hour per user
const rateLimiter = {
  maxRequests: 10,
  windowMs: 3600000,  // 1 hour
  message: 'Too many token refresh requests'
};

Regular Security Audits:

Footer

In this QuickStart, we explored OAuth 2.0 and PKCE authentication patterns for secure data integration.

Key Concepts:

To learn more about secure embedding:

Additional Resource Links

Blog
Community
Help Center
QuickStarts

Be sure to check out all the latest developments at Sigma's First Friday Feature page!

Footer