Skip to content

Integrating Quine Enterprise with Your Identity Provider

Quine Enterprise supports OpenID Connect (OIDC) for authentication and role-based access control (RBAC). This guide explains how to set up OIDC with any identity provider that implements the OIDC standard.

How OIDC Authentication Works

OIDC is a standard protocol that lets you use your existing identity provider (like Okta, Azure AD, Auth0, or self-hosted solutions) to manage user access to Quine Enterprise.

When you enable OIDC:

  • Users log in with their identity provider credentials
  • Quine Enterprise receives information about their roles
  • Access to features is automatically controlled based on those roles

What You Need From Your Identity Provider

Before configuring Quine Enterprise, your identity provider must be set up with the following:

Required Configuration

Your identity provider must provide these OIDC endpoint URLs. The exact path structure varies by provider, but all OIDC-compliant providers publish these endpoints in their configuration:

  • Issuer URL (Location URL): The base identity provider URL (e.g., https://{IDP_DOMAIN} or https://{IDP_DOMAIN}/{TENANT_OR_REALM})

  • Authorization Endpoint: Where users are redirected to authenticate. Path varies significantly by provider:

  • Token Endpoint: Where authorization codes are exchanged for tokens. Path varies by provider:

  • Login Path: OIDC provider's login endpoint path (appended to locationUrl for user redirect)

Rather than memorizing endpoint paths, OIDC-compliant providers publish a discovery document at https://{IDP_DOMAIN}/.well-known/openid-configuration containing the exact endpoints you need.

Additionally, you need:

  • Client ID: Application identifier in your identity provider
  • Client Secret: Secure password for your application

Required Roles

Your identity provider must include these six roles, which Quine Enterprise uses to control access:

SuperAdmin

Purpose: Full administrative access to all features

Why This Role Exists: A catch-all role that can do everything

Permissions & Capabilities: Everything

Admin

Purpose: Administrative access to outward facing product features

Why This Role Exists: This role focuses on the external administration of Quine Enterprise. Users assigned to this role can use most of the admin endpoints to understand the runtime health of Quine Enterprise. This role doesn't have visibility to the internal operation of Quine Enterprise, but rather its health as it runs, and the capability of adjusting some of those runtime configurations.

Permissions & Capabilities: Most admin endpoints and Quine Enterprise metrics.

Architect

Purpose: Administrative access to inward facing product features

Why This Role Exists: This role focuses on the internal administration of Quine Enterprise. Users assigned to this role can do everything a DataEngineer can, while also able to manipulate namespaces, shard limits, and user defined functions.

Permissions & Capabilities: All product feature related endpoints, along with metrics.

Analyst

Purpose: Query and explore data, create ad-hoc analyses

Why This Role Exists: This role has non-admin read access to different features in the product.

Permissions & Capabilities: Can see what ingests are running and read from the graph, along with issue read queries into the Exploration UI.

DataEngineer

Purpose: Non-administrative manipulation of the product.

Why This Role Exists: This role can do everything the Analyst can do, while also able to write to the graph.

Permissions & Capabilities: Everything the Analyst can do, while also able to perform side-effecting actions to the graph.

Billing

Purpose: Access to license usage data

Why This Role Exists: This role is meant to be assumed by a user who's responsibility it is to consume license usage information.

Permissions & Capabilities: Only the license usage UI and the endpoint that powers it.

Setting Up Roles in Your Identity Provider

To enable role-based access control, you must configure your identity provider to support these six roles. While the specific steps vary by provider, the general process is the same across all OIDC-compliant identity providers:

1. Create the Roles

Create each of the six roles within your identity provider's role or group management system. Depending on your provider, these might be called "roles," "groups," "permissions," or "application roles."

2. Assign Users to Roles

After creating the roles, assign your users to the appropriate role(s). A user can have one or more roles depending on their job responsibilities. Users must be assigned to at least one of the six required roles; users without any of these roles will be unable to access Quine Enterprise.

3. Configure the Roles Claim

Configure your identity provider to include user roles in the OIDC token. Specifically, the provider must include a roles claim in the token containing the list of roles assigned to that user. The roles in this claim should exactly match the role names listed above (SuperAdmin, Admin, Architect, Analyst, DataEngineer, Billing).

Most OIDC providers have a configuration option or scope that controls which claims are included in the token. Consult your provider's documentation to: - Enable the roles claim in the token response - Map your provider's roles to the claim - Ensure the role names are sent exactly as defined above

Once configured, when users authenticate through your identity provider, the OIDC token will automatically include their assigned roles, and Quine Enterprise will use those roles to control their access to features.

Configuring Quine Enterprise for OIDC

Quine Enterprise is configured using Java system properties passed through Helm values. The configuration specifies the OIDC endpoint URLs, client credentials, and session management settings.

Quine Enterprise Full JAR System Properties Example

When running the Quine Enterprise JAR, below shows an example of configuring OIDC using Java system properties:

quine.conf
thatdot {
  audit {
    loglevel=INFO
  }
}
quine {
  license-key=
  auth {
    session {
      secret=
      expiration-seconds=3600
      secure-cookies=true
    }
    oidc {
      full {
        provider {
          location-url=
          authorization-url=
          token-url=
          login-path=
        }
        client {
          id=
          secret=
        }
      }
    }
  }
}
java -jar \
  -Dconfig.file=quine.conf \
  jars/quine-enterprise.jar

Populate each empty property with actual values.

OIDC Helm Values

Quine Enterprise requires the following OIDC properties to be set in your Helm values:

oidc:
  enabled: true
  provider:
    locationUrl: https://<IDP_DOMAIN>/<TENANT_OR_REALM>
    authorizationUrl: https://<IDP_DOMAIN>/<AUTHORIZATION_ENDPOINT_PATH>
    tokenUrl: https://<IDP_DOMAIN>/<TOKEN_ENDPOINT_PATH>
    loginPath: <LOGIN_PATH_FRAGMENT>
  client:
    existingSecret:
      name: <CLIENT_CREDENTIALS_SECRET>

Replace the placeholders with your identity provider's values:

  • <IDP_DOMAIN>: Your identity provider's domain (e.g., auth.example.com)
  • <TENANT_OR_REALM>: Your tenant, realm, or organization identifier (if required by your provider)
  • <AUTHORIZATION_ENDPOINT_PATH>: The full authorization endpoint path from your provider's .well-known/openid-configuration
  • <TOKEN_ENDPOINT_PATH>: The full token endpoint path from your provider's .well-known/openid-configuration
  • <LOGIN_PATH>: The login path segment (e.g., auth, authorize, or oauth2/v1/authorize depending on provider)

Session Management Properties

Helm Values

The helm chart for Quine Enterprise allows you to configure the session encryption secret, the session expiration time, and whether or not to use http-only secure cookies for session handling.

By default, the Quine Enterprise helm chart autogenerates the session secret, along with setting 3600 seconds (1 hour) for the session expiration time, and setting secure cookies to true. These can be overridden using the following helm values. Providing your own session secret is done by setting autoGenerate to false, and providing a reference to a Secret and its key.

Configure how user sessions are managed with Helm values:

oidc:
  session:
    autoGenerate: false
    existingSecret:
      name: ""
      key: ""
    expirationSeconds: 3600
    secureCookies: true

JAR via System Properties

Configure how user sessions are managed with Java System Properties. Replace the session secret value with your own:

-Dquine.auth.session.secret=<SECRET>
-Dquine.auth.session.expiration-seconds=3600
-Dquine.auth.session.secure-cookies=true

Authentication Methods

Once OIDC is configured, users and applications can interact with Quine Enterprise in two different ways depending on their use case:

Browser-Based UI Access (Session Cookies)

When a user accesses Quine Enterprise's web interface through a browser:

  1. The user is redirected to your identity provider's login page
  2. After successful authentication, the identity provider redirects the user back to Quine Enterprise
  3. Quine Enterprise automatically creates an HTTP session and stores it in a session cookie
  4. All subsequent browser requests include this session cookie, which Quine Enterprise uses to identify the authenticated user and their assigned roles
  5. The session remains valid for the configured expiration time (default: 1 hour)

No manual token handling is required – the browser automatically sends the session cookie with each request.

API Access (Bearer Tokens)

For programmatic access to Quine Enterprise's API (such as from scripts, tools, or external services), you need to use bearer tokens:

Prerequisites

Your identity provider should have a service account or machine-to-machine client credentials configured with the appropriate role(s) assigned. Consult your identity provider's documentation for specific steps to create client credentials.

Getting an Access Token

To access Quine Enterprise's API, first obtain an access token from your identity provider using the client credentials grant:

curl -X POST \
  <TOKEN_ENDPOINT> \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=<CLIENT_ID>" \
  -d "client_secret=<CLIENT_SECRET>"

Replace the placeholders: - <TOKEN_ENDPOINT>: Your identity provider's token endpoint (from the .well-known/openid-configuration discovery document) - <CLIENT_ID>: The client ID for your service account - <CLIENT_SECRET>: The client secret for your service account

The response will include an access_token that you can use to make API calls:

{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600
}

Using the Token in API Calls

Use the access token in the Authorization header of your API requests:

curl -X GET \
  http://localhost:8080/api/v2/some-endpoint \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."

The token will be validated by Quine Enterprise, and the request will proceed if the token is valid and the associated service account has the appropriate role(s) for that API endpoint.

Token Expiration: Tokens typically expire after a short period. When a token expires, request a new one from your identity provider using the client credentials flow above.

How to Interpret Auth Errors

If a user attempts to issue a request to an endpoint they don't have authorization with, they will receive an error of the following shape:

{
  "errors": [
    {
      "message": "Missing Permission: <MISSING_PERMISSION>",
      "type": "ApiError"
    }
  ]
}

The <MISSING_PERMISSION> shows why the user was not authorized to perform the action due to the missing permission.

Audit Logging

To enable audit logging, add the -Dthatdot.audit.loglevel=INFO java system property to your configuration.

When set, you will then see audit logs emitted from Quine Enterprise. Audit logs track important security events such as user authentication, token refresh, and API calls. This provides a complete audit trail for compliance, security monitoring, and forensics.

Field Explanations

Authentication Attempt ID

The Authentication Attempt ID is a unique identifier generated at the start of each login flow. It remains constant throughout the entire authentication process and allows you to correlate all the individual steps of a login attempt in the audit log.

  • Purpose: Trace the complete sequence of validation steps for a single login
  • Scope: Spans from initial OAuth state validation through final session creation
  • Uniqueness: Cryptographically strong UUID generated per login attempt (FIPS-compliant when available)
  • Example: dfa5fca3-26db-48c5-864a-c8a29abcefac
Action ID

The Action ID is a unique identifier generated for each API request. It allows you to correlate the initial API call attempt with its outcome (success, prevented, or exception).

  • Purpose: Track the complete lifecycle of an individual API request
  • Scope: From request initiation through response completion
  • Uniqueness: Cryptographically strong UUID generated per API request (FIPS-compliant when available)
  • Example: 28f89843-4567-4523-bad1-7316a7ab8eb2
User Identifiers

When an authenticated user makes an API call, three user-related identifiers appear in the audit log:

  • sub (Subject): The unique user identifier from the OAuth provider. This is the permanent identifier for the user in your system.
  • Example: b55a4959-744e-400e-84de-26a22774cda8

  • a64 (Access Token Hash): The first 64 bits of the HMAC SHA-256 hash of the user's access token. This provides a short identifier for tracing token-specific activity without logging sensitive credentials.

  • Example: MgGBEDKIaxY=

  • s64 (Session Token Hash): The first 64 bits of the HMAC SHA-256 hash of the user's session token. This identifies which session was used for the request.

  • Example: vhEmIRYLdEU=

Example Audit Logs

Login
2025-11-14T17:10:33.589322628Z [Login] [Authentication Attempt ID: dfa5fca3-26db-48c5-864a-c8a29abcefac] Validating OAuth State. Provided (hashed): 4zW+vj65uVs=
2025-11-14T17:10:33.589634878Z [Login] [Authentication Attempt ID: dfa5fca3-26db-48c5-864a-c8a29abcefac] State Validation succeeded.
2025-11-14T17:10:33.590030044Z [Login] [Authentication Attempt ID: dfa5fca3-26db-48c5-864a-c8a29abcefac] Exchanging Authentication Code for Token. Code hash: xO2Di/Ty7CM=
2025-11-14T17:10:33.622655794Z [Login] [Authentication Attempt ID: dfa5fca3-26db-48c5-864a-c8a29abcefac] Validating Token. ID Token hash: SUe4WMtoIrM=, Access Token hash: MgGBEDKIaxY=
2025-11-14T17:10:33.663103253Z [Login] [Authentication Attempt ID: dfa5fca3-26db-48c5-864a-c8a29abcefac] Valid ID Token. sub: b55a4959-744e-400e-84de-26a22774cda8
2025-11-14T17:10:33.666020419Z [Login] [Authentication Attempt ID: dfa5fca3-26db-48c5-864a-c8a29abcefac] Valid Nonce. sub: b55a4959-744e-400e-84de-26a22774cda8
2025-11-14T17:10:33.667495253Z [Login] [Authentication Attempt ID: dfa5fca3-26db-48c5-864a-c8a29abcefac] ID Token verification succeeded. sub: b55a4959-744e-400e-84de-26a22774cda8
2025-11-14T17:10:33.673789169Z [Login] [Authentication Attempt ID: dfa5fca3-26db-48c5-864a-c8a29abcefac] succeeded. sub: b55a4959-744e-400e-84de-26a22774cda8, Session Token hash: vhEmIRYLdEU=

What to look for: All log entries for a single login attempt share the same Authentication Attempt ID. If a login fails, you can use the ID to review all validation steps that were performed.

API Calls
2025-11-14T17:10:34.433407753Z [API Call] [Action ID: 28f89843-4567-4523-bad1-7316a7ab8eb2] [sub: b55a4959-744e-400e-84de-26a22774cda8, a64: MgGBEDKIaxY=, s64: vhEmIRYLdEU=] [List Quick Queries] called. Path: /query-ui/quick-queries
2025-11-14T17:10:34.433419003Z [API Call] [Action ID: 62d7db21-f3a1-44f3-8740-8911255062dd] [sub: b55a4959-744e-400e-84de-26a22774cda8, a64: MgGBEDKIaxY=, s64: vhEmIRYLdEU=] [List Node Appearances] called. Path: /query-ui/node-appearances
2025-11-14T17:10:34.433402503Z [API Call] [Action ID: ad5e5315-8ae7-487b-bb06-939790bb9609] [sub: b55a4959-744e-400e-84de-26a22774cda8, a64: MgGBEDKIaxY=, s64: vhEmIRYLdEU=] [List Sample Queries] called. Path: /query-ui/sample-queries
2025-11-14T17:10:34.435678670Z [API Call] [Action ID: 28f89843-4567-4523-bad1-7316a7ab8eb2] [sub: b55a4959-744e-400e-84de-26a22774cda8, a64: MgGBEDKIaxY=, s64: vhEmIRYLdEU=] [List Quick Queries] succeeded.
2025-11-14T17:10:34.435745253Z [API Call] [Action ID: ad5e5315-8ae7-487b-bb06-939790bb9609] [sub: b55a4959-744e-400e-84de-26a22774cda8, a64: MgGBEDKIaxY=, s64: vhEmIRYLdEU=] [List Sample Queries] succeeded.
2025-11-14T17:10:34.435745253Z [API Call] [Action ID: 62d7db21-f3a1-44f3-8740-8911255062dd] [sub: b55a4959-744e-400e-84de-26a22774cda8, a64: MgGBEDKIaxY=, s64: vhEmIRYLdEU=] [List Node Appearances] succeeded.

What to look for: Each API request appears twice in the audit log—once when the request is initiated ("called") and once with the outcome ("succeeded"). Both log entries share the same Action ID, allowing you to correlate them. The Action ID uniquely identifies that specific API request.