Integrating Novelty with Your Identity Provider¶
Novelty 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 Novelty.
When you enable OIDC:
- Users log in with their identity provider credentials
- Novelty receives information about their roles
- Access to features is automatically controlled based on those roles
What You Need From Your Identity Provider¶
Before configuring Novelty, 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}orhttps://{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 Novelty 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 Novelty. Users assigned to this role can use most of the admin endpoints to understand the runtime health of Novelty. This role doesn't have visibility to the internal operation of Novelty, but rather its health as it runs, and the capability of adjusting some of those runtime configurations.
Permissions & Capabilities: Most admin endpoints and Novelty metrics.
Architect
Purpose: Administrative access to inward facing product features
Why This Role Exists: This role focuses on the internal administration of Novelty. 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 Novelty.
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 Novelty will use those roles to control their access to features.
Configuring Novelty for OIDC¶
Novelty is configured using Java system properties passed through Helm values. The configuration specifies the OIDC endpoint URLs, client credentials, and session management settings.
Novelty Full JAR System Properties Example¶
When running the Novelty JAR, below shows an example of configuring OIDC using Java system properties:
thatdot {
audit {
loglevel=INFO
}
novelty {
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=novelty.conf
jars/novelty.jar
Populate each empty property with actual values.
OIDC Helm Values¶
Novelty 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, oroauth2/v1/authorizedepending on provider)
Session Management Properties¶
Helm Values¶
The helm chart for Novelty 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 Novelty 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:
-Dthatdot.novelty.auth.session.secret=<SECRET>
-Dthatdot.novelty.auth.session.expiration-seconds=3600
-Dthatdot.novelty.auth.session.secure-cookies=true
Authentication Methods¶
Once OIDC is configured, users and applications can interact with Novelty in two different ways depending on their use case:
Browser-Based UI Access (Session Cookies)¶
When a user accesses Novelty's web interface through a browser:
- The user is redirected to your identity provider's login page
- After successful authentication, the identity provider redirects the user back to Novelty
- Novelty automatically creates an HTTP session and stores it in a session cookie
- All subsequent browser requests include this session cookie, which Novelty uses to identify the authenticated user and their assigned roles
- 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 Novelty'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 Novelty'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:8081/api/v2/some-endpoint \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
The token will be validated by Novelty, 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 Novelty. 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.