Skip to content

Authentication & Authorization ​

Precept relies on a "bring your own IdP" model — the only requirement is that your IdP supports OAuth 2.0 / OpenID Connect. Any OIDC-compliant provider will work, including (but not limited to):

  • Auth0 / Okta
  • Amazon Cognito
  • Google Identity Platform
  • Microsoft Entra ID
  • Keycloak
  • ORY Hydra

Configuring Your IdP ​

1. Register Precept as an Application ​

In your IdP, create a new Single Page Application (SPA) registration with the following settings:

SettingValue
Application typeSingle Page Application (SPA)
Allowed callback URLhttps://<your-precept-host>/
Allowed logout URLhttps://<your-precept-host>/
Allowed grant typesAuthorization Code (with PKCE)

The UI uses the Authorization Code flow with PKCE — no client secret is needed.

2. Register an API / Resource Server ​

Create an API (or "resource server") entry in your IdP to represent the Precept backend. The identifier you choose here becomes the audience value in Precept's configuration.

For example, you might use https://precept.example.com/api as the identifier.

3. Configure Precept ​

Point Precept at your IdP by setting the http.auth.* server options. The three required options are:

  • http.auth.issuer-base-url — your IdP's issuer URL (must expose /.well-known/openid-configuration)
  • http.auth.audience — the API identifier registered in your IdP
  • http.auth.ui.client-id — the OAuth 2.0 client ID for the Precept UI

See the Server Options reference for the full list of http.auth.* options, including optional settings for authority override, login query parameters, query parameter whitelisting, and the requested login scope.

Example Configuration ​

bash
# Required
PRECEPT_HTTP_AUTH_ISSUER_BASE_URL=https://example.us.auth0.com/
PRECEPT_HTTP_AUTH_AUDIENCE=https://precept.example.com/api
PRECEPT_HTTP_AUTH_UI_CLIENT_ID=abc123def456

# Optional — pass the audience to the IdP - required by Auth0 during login
PRECEPT_HTTP_AUTH_UI_QUERY_PARAMS='{"audience":"https://precept.example.com/api"}'

# Optional — allow the "connection" param to be set via URL
PRECEPT_HTTP_AUTH_UI_QUERY_PARAMS_WHITELIST=connection

# Optional — override the OAuth2 scope requested at login
PRECEPT_HTTP_AUTH_UI_SCOPE="openid profile email"

Provider-Specific Notes ​

Auth0 / Okta ​

Auth0 requires the audience parameter at login time to issue an access token. Set PRECEPT_HTTP_AUTH_UI_QUERY_PARAMS to include it:

bash
PRECEPT_HTTP_AUTH_UI_QUERY_PARAMS='{"audience":"https://precept.example.com/api"}'

If you use Auth0 Organizations or enterprise connections, whitelist the relevant param so it can be passed dynamically:

bash
PRECEPT_HTTP_AUTH_UI_QUERY_PARAMS_WHITELIST=connection

Amazon Cognito ​

Cognito's OIDC endpoints span two hostnames:

EndpointHost
Discovery (/.well-known/openid-configuration), JWKScognito-idp.<region>.amazonaws.com
Token, UserInfo<prefix>.auth.<region>.amazoncognito.com

The issuer origin (cognito-idp.<region>.amazonaws.com) is allowed automatically — Precept derives it from your configured authority — and it is the same host that serves discovery and JWKS. The token/userinfo host cannot be derived from the issuer, so you must allow it explicitly via connect-src:

bash
# <prefix> is your Cognito hosted-UI domain prefix; its region must match the issuer's
PRECEPT_HTTP_AUTH_ISSUER_BASE_URL=https://cognito-idp.us-east-1.amazonaws.com/us-east-1_xxxxxxxxx
PRECEPT_HTTP_UI_CSP_DIRECTIVES='{"connect-src":["https://<prefix>.auth.us-east-1.amazoncognito.com"]}'

Keycloak ​

Set the issuer base URL to your realm endpoint:

bash
PRECEPT_HTTP_AUTH_ISSUER_BASE_URL=https://keycloak.example.com/realms/precept

Microsoft Entra ID ​

Use the v2.0 endpoint as the issuer:

bash
PRECEPT_HTTP_AUTH_ISSUER_BASE_URL=https://login.microsoftonline.com/<tenant-id>/v2.0

Content Security Policy ​

The UI is served with a Content Security Policy that restricts which origins the browser may contact. Your IdP's origin (from http.auth.issuer-base-url / http.auth.ui.authority) is allowed automatically.

If your deployment needs the UI to reach additional origins — a split-host IdP (see Amazon Cognito above), web analytics, a custom CDN, etc. — add them with PRECEPT_HTTP_UI_CSP_DIRECTIVES. It takes a JSON object mapping CSP directive names (kebab-case) to arrays of sources, and is append-only: your sources are added to the built-in policy, never replacing it, so you cannot accidentally weaken or break the defaults.

bash
PRECEPT_HTTP_UI_CSP_DIRECTIVES='{"connect-src":["https://analytics.example.com"],"script-src":["https://cdn.example.com"]}'

Sources must be valid CSP tokens, including quotes around keywords (e.g. "'unsafe-inline'"). An invalid policy is rejected at server startup.

Authorization & Policies ​

Precept uses a permission-based authorization model via custom JWT claims. Your IdP can embed a https://precept.sh/policy claim in the access token containing an array of permission strings.

Available Permissions ​

PermissionDescription
config.global.writeModify global configuration settings for any PDM
pdm.createUpload and activate new PDMs
pdm.deleteRemove existing PDMs and their configuration
telemetry.readRead the Performance page and its API. Shows error data of all tenants.

Policies are for administering the Precept server and adding & removing integrations. With no policy claims, tokens authorize end-consumer usage of the platform, enabling usage of API calls to any integration which either:

  • A user has individually authenticated to, or
  • An admin has configured with global or org-level credentials

WARNING

Give telemetry.read only to administrators who are cleared to see the data of all tenants. The Performance page shows errors from every tenant. These errors can contain downstream response bodies, headers, URLs and stack traces. Precept does not redact this data. See Observability.

A user without telemetry.read does not see the Performance page in the sidebar. If this user opens /performance directly, the page shows a message and requests no data. The /rest/telemetry API responds with status 403 to this user.

If administrators use the Performance page, add telemetry.read to their policy claim before you upgrade Precept.

Setting Up Policies ​

To assign policies, configure your IdP to inject the https://precept.sh/policy claim into the access token based on user roles or group membership.

Precept reads the claim from the access token, not the ID token. Precept validates the Bearer access token that the UI sends to the API. Emit the claim into that token.

The claim must be an array of permission strings:

json
{
  "https://precept.sh/policy": [
    "config.global.write",
    "pdm.create",
    "pdm.delete",
    "telemetry.read"
  ]
}

Map each Precept role to a group in your IdP. Then emit the permission array for members of that group. If a user is in more than one group, emit the union of their permissions as one flat array. Precept reads each string as one permission. This works with any OIDC provider, including Microsoft Entra ID, Okta, Amazon Cognito, and Keycloak.

The example below uses Auth0 Actions. The claim shape is the same for any provider, so use it as a reference even if you use a different IdP.

Example: assign role-based policies with Auth0 Actions

This example configures Auth0 to inject the policy claim into access tokens based on a user's role.

Prerequisites

  • An Auth0 tenant with an API (resource server) configured.
  • Admin access to the Auth0 Dashboard.

1. Create a role

  1. Go to Auth0 Dashboard > User Management > Roles.
  2. Click Create Role.
  3. Set the name to https://precept.sh/role/admin.

2. Assign the role to users

  1. Go to Auth0 Dashboard > User Management > Users.
  2. Select a user.
  3. Open the Roles tab.
  4. Click Assign Roles and select https://precept.sh/role/admin.

3. Create an Action

  1. Go to Auth0 Dashboard > Actions > Library.
  2. Click Create Action > Build from scratch.
  3. Set the name to Add Precept Policy Claims Based on Roles.
  4. Set the trigger to Login / Post Login.
  5. Replace the default code with the following:
javascript
exports.onExecutePostLogin = async (event, api) => {
  const namespace = "https://precept.sh";

  // Grant admin permissions to users in the admin role.
  if (event.authorization?.roles.includes(`${namespace}/role/admin`)) {
    api.accessToken.setCustomClaim(`${namespace}/policy`, [
      "config.global.write",
      "pdm.create",
      "pdm.delete",
      "telemetry.read",
    ]);
  }
};
  1. Click Save Draft, then Deploy.

4. Attach the Action to the login flow

  1. Go to Auth0 Dashboard > Actions > Triggers.
  2. Select the post-login flow.
  3. Drag the Add Precept Policy Claims Based on Roles Action onto the graph, between Start and Complete.
  4. Click Apply.

Verify

When a user with the admin role signs in, the access token contains the claim:

json
{
  "iss": "https://your-domain.auth0.com/",
  "sub": "auth0|USER-ID",
  "aud": "YOUR_API_AUDIENCE",
  "https://precept.sh/policy": [
    "config.global.write",
    "pdm.create",
    "pdm.delete",
    "telemetry.read"
  ]
}

If the claim does not appear, confirm the Action is attached to the login flow, and confirm the role name matches https://precept.sh/role/admin exactly. Decode the token with a tool such as jwt.io to inspect its contents.

OIDC Scopes ​

The UI requests the following OIDC scopes during login:

  • openid — required for OIDC
  • profile — user display name
  • email — user email address

Ensure these scopes are enabled for your application in your IdP.