Skip to content

Authentication SetupπŸ”—

This guide provides the steps required to configure your OAuth 2.0 / OpenID Connect (OIDC) identity provider so the Apheris Hub can validate JWTs and support multi-user deployments. After completing the provider configuration here, continue with the Docker Deployment Guide or the Kubernetes Deployment Guide depending on how you deploy the Hub.

Identity Provider RequirementsπŸ”—

Your identity provider must meet the following requirements:

  • OIDC Discovery: Exposes {domain}/.well-known/openid-configuration so the Hub can discover the JWKS endpoint
  • JWKS Endpoint: Publishes a JWKS (JSON Web Key Set) for token signature verification
  • JWT Token Format: Issues JWT access tokens with enough standard claims to identify users
  • Required Token Claims:
    • iss (issuer): Must match what the Hub expects as issuer (hub.auth.issuer when set, otherwise hub.auth.domain)
    • aud (audience): Must include the value configured as the Hub audience (hub.auth.audience) so tokens are intended for the Hub API
    • email: Used for user identification and data segregation, so it must be present in the access token
    • exp: Token expiration timestamp
  • Optional but recommended claims (used for a better user experience in the UI):
    • name
    • given_name
    • family_name

The Hub has been tested with Auth0, Microsoft Entra (Azure AD), and Dex. Other OIDC-compliant providers should be supported but have not been validated.

General ConfigurationπŸ”—

The Hub learns about your identity provider through the hub.auth configuration block. The following fields are required for most providers, with issuer, extraScopes, and browserUrl only necessary when your provider requires them:

hub:
  auth:
    enabled: true
    domain: "https://your-auth-domain/"     # required
    audience: "https://your-api-audience"   # required
    clientId: "your-client-id"              # required
    issuer: "https://issuer-if-different/"  # optional (required for Microsoft Entra)
    extraScopes: "optional:scope"           # optional (required for Microsoft Entra)
    browserUrl: "https://hub.example.com"   # optional (internal IdP behind proxy/ingress)

EnabledπŸ”—

Controls whether the Hub enforces authentication and multi-user isolation.

  • When enabled: false, the Hub runs in single-user mode. Tokens are not required, and the other hub.auth.* fields are ignored by the backend.
  • When enabled: true, the Hub requires at least domain, audience and clientId to be set and will reject configuration that is incomplete or malformed.

DomainπŸ”—

hub.auth.domain is the base URL of your identity provider and is used to discover JWKS and metadata, and by the frontend as the OIDC authority.

  • Always provide a full URL with scheme and trailing slash, for example:
    • Auth0: https://<tenant>.auth0.com/
    • Microsoft Entra: https://login.microsoftonline.com/<tenant-id>/v2.0/
    • Dex (cluster DNS): http://dex.dex.svc.cluster.local:5556/
  • If enabled: true and domain is empty, the backend treats the configuration as invalid and will not accept requests using this auth setup.
  • For providers where the discovery base URL and issuer are identical (e.g., Auth0, Dex), domain is sufficient; for providers where they differ (e.g., Entra), also configure issuer (see below).

AudienceπŸ”—

hub.auth.audience tells the Hub which API the access token must target.

  • It must be an identifier, usually a URI or URL, that your identity provider issues tokens for. For example:
    • Auth0: https://hub.yourdomain.com/api
    • Microsoft Entra: api://<client-id>
  • The backend validates that this value is present and has a URL scheme when auth is enabled. If audience is empty while enabled: true, the Hub rejects the configuration.
  • Tokens that do not include this audience are rejected by the validator.

Client IDπŸ”—

hub.auth.clientId is the public client identifier of your Single Page Application (SPA), used by the browser when initiating the authorization code + PKCE (Proof Key for Code Exchange) flow. This value must be set correctly for the frontend to obtain tokens, see examples below for IdP-specific configurations.

Issuer (optional)πŸ”—

hub.auth.issuer is the issuer URL the backend expects in the iss claim of access tokens.

  • If issuer is empty, the backend uses domain as the expected issuer.
  • For providers where the discovery URL and token issuer are the same (Auth0, Dex), you can leave this field empty.
  • For providers where they differ (Microsoft Entra), set hub.auth.issuer to the exact issuer in the token (for example, https://sts.windows.net/<tenant-id>/) while keeping domain as the discovery URL.
  • If you set issuer, it must be a valid URL with a scheme; otherwise the backend treats the configuration as invalid.

Extra Scopes (optional)πŸ”—

hub.auth.extraScopes lets you request provider-specific scopes in addition to the default openid profile email offline_access.

  • If empty, the frontend requests only the default scopes. Many providers (e.g., Auth0) will still issue an access token for your API when audience is set.
  • Some providers (notably Microsoft Entra) require you to request a specific API scope (for example, api://<client-id>/<scope-name>) so the identity provider issues an access token with the expected audience. In those cases, use the scope name you configured on the provider side.

Browser URL (optional)πŸ”—

hub.auth.browserUrl is only needed when the backend reaches the identity provider through an internal address that browsers cannot resolve (for example, Kubernetes cluster DNS) but users access the provider through a different, browser-friendly URL.

  • When set, the Hub fetches the discovery document from issuer and rewrites its URLs so the browser talks to the browserUrl host that it can reach.
    • Typical use case: an internal IdP with issuer https://idp.internal.svc.cluster.local/ and an external proxy or ingress at https://sso.example.com; set issuer to the internal URL and browserUrl to the public one.
  • For Auth0 and Entra, where discovery uses public HTTPS endpoints reachable from the browser, leave browserUrl empty and the frontend will use direct discovery.

Docker Deployment Demo Auth0πŸ”—

The Docker deployment script deploy_apherisfold includes a proof-of-concept configuration that uses a shared Apheris-managed Auth0 tenant so you can try multi-user mode without configuring your own identity provider.

  • Set the following in your config.yaml:

    config.yaml
    hub:
      auth:
        enabled: true
        domain: ""
        audience: ""
        clientId: ""
    
  • When enabled: true and these fields are left empty, the script injects demo Auth0 domain, audience, and clientId values when starting the Hub container.
  • This mode is:
    • Intended for localhost development only (ports 8080/8081).
    • Shared across multiple users and environments.

When you are ready to use your own identity provider, replace the empty values with your real hub.auth.domain, hub.auth.audience, and hub.auth.clientId and follow the Auth0, Microsoft Entra, or Dex sections below.

Auth0 GuideπŸ”—

  1. Create the SPA application
    • Visit Applications β†’ Applications β†’ Create Application.
    • Name it (e.g., ApherisFold) and choose Single Page Application.
    • Note the Domain and Client ID from the Settings tab (you will need them for hub.auth.domain and hub.auth.clientId).
  2. Configure allowed URLs

    • In the application settings, add your frontend URLs to Allowed Callback URLs, Allowed Logout URLs, and Allowed Web Origins. Example entries for localhost development:

      http://localhost:8000
      http://localhost:8000/login
      
  3. Create the API

    • Navigate to Applications β†’ APIs β†’ Create API.
    • Set the name (e.g., ApherisFold API) and use a URL-like identifier such as https://fold.apheris.com/api.
    • Keep the signing algorithm at RS256.
  4. Authorize the SPA
    • In the API’s Machine to Machine Applications tab, authorize your SPA so it can request an access token for the API.
  5. Enable login methods
    • Under Authentication β†’ Connections, enable the identity providers you want (Database, Google, GitHub, Microsoft, etc.).
    • Back in Applications β†’ [Your SPA], toggle the desired connections so they appear on the login screen.
  6. Claims
    • Auth0 already includes email claim in both ID and access tokens, so no extra configuration is required.

Example configuration:

config.yaml
hub:
  auth:
    enabled: true
    domain: "https://<tenant>.auth0.com/"
    audience: "https://fold.apheris.com/api"
    clientId: "<client-id>"

Auth0 deployments do not require issuer or extraScopes to be set since the discovery URL and token issuer are identical, and the audience is sufficient to obtain access tokens for your API.

Microsoft Entra (Azure AD) GuideπŸ”—

Use this section to configure Microsoft Entra (formerly Azure AD) as the OIDC provider for the Hub.

Microsoft Entra setupπŸ”—

  1. Register a SPA application
    • In the Microsoft Entra admin center, go to Identity β†’ Applications β†’ App registrations β†’ New registration.
    • Enter a name (for example, ApherisFold) and choose the supported account types.
    • Leave redirect URIs empty for now.
    • Click Register.
  2. Configure the application as a SPA
    • In Authentication (Preview), on the Redirect URI configuration tab, click Add Redirect URI.
    • Select Single-page application.
    • Add a redirect URI, for example http://localhost:8000, matching the URL where your frontend is served.
    • Click Configure.
    • Still in Authentication (Preview), on the Settings tab, enable Allow public client flows so the SPA can use the authorization code + PKCE flow to obtain access tokens.
    • Click Save.
  3. Expose the API (audience and scope)
    • In Expose an API, click Add a scope.
    • Keep the default Application ID URI (api://<client-id>). This becomes your hub.auth.audience. Click Save and continue.
    • Set a Scope name (for example, access) so the resulting full scope is api://<client-id>/<scope-name> (for example, api://<client-id>/access).
    • Select Admins and users for who can consent, add a short Admin consent display name and Admin consent description, then click Add scope.
  4. Configure token claims
    • Under Token configuration, click Add optional claim, choose token type Access, and select the email claim so the access token includes email.
    • Optionally also add the given_name and family_name claims for a better user experience in the UI.
    • Confirm by granting consent and clicking Add.

Hub configurationπŸ”—

On the Overview tab of your registered application, note the following values:

  • Application (client) ID: use this for hub.auth.clientId.
  • Directory (tenant) ID: use this to build the hub.auth.domain and hub.auth.issuer URLs.
  • Application ID URI: use this for hub.auth.audience.
  • When you click on Application ID URI, you can see the full scope name you created earlier; use this for hub.auth.extraScopes (for example, api://<client-id>/access).

Example configuration:

config.yaml
hub:
  auth:
    enabled: true
    domain: "https://login.microsoftonline.com/<tenant-id>/v2.0/"
    issuer: "https://sts.windows.net/<tenant-id>/"
    audience: "api://<client-id>"
    clientId: "<client-id>"
    extraScopes: "api://<client-id>/<scope-name>"
  • hub.auth.domain (https://login.microsoftonline.com/<tenant-id>/v2.0/) is the discovery URL used by both the frontend and backend to fetch metadata and JWKS.
  • hub.auth.issuer (https://sts.windows.net/<tenant-id>/) is the expected iss claim used by the backend for token validation. This differs from the discovery URL, so you must set it explicitly.
  • hub.auth.audience (api://<client-id>) must match the aud claim in access tokens issued for your API.
  • hub.auth.clientId is the public client identifier of your SPA application.
  • hub.auth.extraScopes must include the API scope you created so the frontend requests an access token for your API. Both hub.auth.issuer and hub.auth.extraScopes are required when you integrate with Microsoft Entra.

Dex (Cluster OIDC Provider) GuideπŸ”—

Dex can act as a central OIDC provider inside your Kubernetes cluster, with traffic flowing through your existing ingress or gateway and the Hub integrating via standard OAuth2/OIDC.

Dex setupπŸ”—

  1. Deploy Dex behind ingress or gateway

    • Install Dex into the cluster (for example, via the official Helm chart).
    • Expose it at a stable HTTPS URL, such as https://sso.example.com/dex.
  2. Set issuer

    • Configure Dex’s Issuer to exactly match the external URL (for example, https://sso.example.com/dex).
    • This value becomes the iss claim in issued tokens and the base URL for OIDC discovery.
  3. Create a static client for the Hub

    • id: a client identifier for the Hub, for example https://apherisfold.example.com/api.
    • redirectURIs: the Hub URLs where users return after login, for example:
      • https://apherisfold.example.com
      • https://apherisfold.example.com/login
  4. Configure identity sources and claims

    • Connectors: Add connectors such as LDAP (Lightweight Directory Access Protocol), GitHub, or upstream OIDC providers so Dex can authenticate your users.
    • Claims: Ensure access tokens issued to the Hub always include email (required for multi-user isolation). Optionally also include name, given_name, and family_name for a better user experience in the UI.

Hub configuration for DexπŸ”—

With Dex exposed at https://sso.example.com/dex and the Hub UI/API reachable at https://apherisfold.example.com, configure hub.auth as follows:

hub:
  auth:
    enabled: true
    domain: "https://sso.example.com/dex"
    issuer: "https://sso.example.com/dex"
    audience: "https://apherisfold.example.com/api"
    clientId: "https://apherisfold.example.com/api"

In this setup:

  • domain and issuer should point to the same Dex URL. If you omit issuer, the Hub automatically falls back to domain as the expected issuer, which is the recommended configuration for Dex.
  • Dex uses the OAuth client ID as the aud claim in issued tokens by default. Because the Hub validates aud against hub.auth.audience, you must keep hub.auth.clientId and hub.auth.audience identical for Dex-based setups.
  • Both the Hub backend and the browser talk to Dex via the same public URL, so browserUrl is not needed. Only set browserUrl when Dex is reachable via an internal URL from the Hub but via a different external URL from users’ browsers (see below for the internal/external URL example).

If Dex is only reachable by the Hub over an internal cluster address (for example, https://dex.dex.svc.cluster.local:5556) but users reach it through a different external URL (for example, https://sso.example.com/dex via ingress), configure:

  • domain and issuer with the internal URL (used to fetch discovery and JWKS).
  • browserUrl with the external URL, as described in the Browser URL section, so the discovery proxy rewrites URLs for the browser.

Next StepsπŸ”—

After configuring your identity provider, return to the Docker Deployment Guide or the Kubernetes Deployment Guide to finish the deployment that matches your environment.