Authentication

Configure identity providers, JWT validation, organisation claims, and client sign-in for io.sign

io.sign validates JSON Web Tokens (JWTs) issued by your identity provider. Configure which issuers the backend trusts, then configure your clients to sign in with the same provider and send a token with each authenticated request.

How authentication works

  1. Your client signs in with your identity provider and obtains a JWT.
  2. The client sends the token to the io.sign API in the Authorization: Bearer <JWT> header.
  3. The API matches the token's iss claim to an issuer in JWT_PROVIDERS and validates it using that provider's JSON Web Key Set (JWKS).
  4. The API resolves the active organisation from the validated token for organisation-scoped actions.

Backend token validation and client sign-in configuration are separate. JWT_PROVIDERS controls which tokens the API accepts. The APP_CONFIG_AUTH_* variables tell Mobile Signers how to sign in.

Supported identity providers

ProviderStatusDetails
ClerkImplementedIntegration with Clerk SDK, including Clerk API key validation and team management
OpenID Connect (OIDC)ImplementedGeneric JWT validation using your provider's issuer and JWKS endpoint
WorkOSComing soonDedicated integration
Auth0Coming soonDedicated integration

Use the generic OIDC option with a provider that issues JWTs matching the validation and organisation-claim requirements below. Dedicated WorkOS and Auth0 integrations are coming soon. For help with another provider, contact your sales contact or account manager.

Before you begin

Have the following available from your identity provider:

  • The issuer URL, exactly as it appears in the token's iss claim.
  • The JWKS endpoint, reachable from the io.sign backend.
  • The expected audience and signing algorithms, if you configure those validation constraints.
  • A token containing the active organisation ID in a claim supported by your io.sign release.

For Mobile Signers using OIDC, also register a public client with the redirect URI required by your mobile release. The mobile flow uses Proof Key for Code Exchange (PKCE); it must not require a client secret.

Step 1: Configure token validation

Set these environment variables on the backend. This example uses environment-file syntax suitable for the --env-file commands in Running the service; replace the URLs with values from your provider.

JWT_ENABLED=true
JWT_PROVIDERS=[{"issuer":"https://your-idp.example.com","jwksUri":"https://your-idp.example.com/.well-known/jwks.json"}]

JWT_PROVIDERS is a JSON array, passed as a single-line string. Each entry accepts the following fields:

FieldRequiredPurpose
issuerYesMatches the token's iss claim exactly, including the scheme and any trailing slash.
jwksUriYesIdentifies the JWKS endpoint used to validate the token's signature. Use the endpoint supplied by your provider.
audienceNoSets the expected token audience.
algorithmsNoRestricts the accepted signing algorithms.

Add one entry per trusted issuer to accept tokens from several identity providers. The API selects the entry whose issuer matches the token's iss claim. An unmatched issuer fails with JWT_INVALID_ISSUER.

Step 2: Include the organisation claim

Configure your identity provider to include the active organisation ID in the token's organisationId claim, or the Clerk-style organisation shape supported by your release. The API uses this claim to resolve the tenant. Organisation-scoped actions fail with "Invalid organisation ID" when the required claim is missing or invalid.

Setting APP_CONFIG_AUTH_ORGANISATION_ID for Mobile Signers does not replace this token requirement.

Step 3: Configure client sign-in

For Mobile Signers, follow Public app configuration for Mobile Signers:

  • Clerk: set APP_CONFIG_AUTH_STRATEGY=clerk and APP_CONFIG_AUTH_PUBLISHABLE_KEY.
  • OIDC: set APP_CONFIG_AUTH_STRATEGY=oidc, APP_CONFIG_AUTH_ISSUER_URL, APP_CONFIG_AUTH_CLIENT_ID, and APP_CONFIG_AUTH_ORGANISATION_ID.

For the optional web console, configure its authentication provider as described in Web console. API clients must obtain a token from your identity provider and send it as a bearer token.

Recreate or redeploy the API container after changing its environment variables.

Step 4: Verify an authenticated request

Obtain a valid token for your organisation through your configured identity provider. Use it to call the List signers endpoint:

IO_SIGN_API_URL=https://sign.example.com
IO_SIGN_TOKEN='<JWT-issued-by-your-identity-provider>'

curl --fail-with-body \
  -H "Authorization: Bearer ${IO_SIGN_TOKEN}" \
  "${IO_SIGN_API_URL}/v2/signers?limit=1"

Expect a 200 response containing the organisation's signer list, which can be empty. The public health and app configuration endpoints do not verify authentication.

SymptomWhat to check
JWT_INVALID_ISSUERCompare the token's iss claim with JWT_PROVIDERS; the values must match exactly.
Token validation failsCheck token expiry, JWKS reachability, and any configured audience or algorithm constraints.
"Invalid organisation ID"Confirm the token contains the active organisation in a claim supported by your release.
Mobile sign-in failsCheck the public app configuration, registered redirect URI, and OIDC public-client PKCE configuration.

Configure EMQX broker authentication

The EMQX JWT authentication configuration reads the token from the MQTT connection's password field and validates it against a JWKS endpoint. Configure that endpoint for the identity provider issuing your signers' tokens. The backend's JWT_PROVIDERS setting does not configure broker authentication.

When using the bundled Docker Compose setup, set:

EMQX_AUTH_JWT_JWKS_ENDPOINT=https://your-idp.example.com/.well-known/jwks.json

Docker Compose uses this value to populate the broker's EMQX_AUTHENTICATION configuration. For other deployments, configure the equivalent JWKS endpoint in the broker's JWT authentication settings; setting this variable on the io.sign API container alone has no effect on the broker.

📘

Use your environment's JWKS endpoint

Replace the io.finnet development endpoint supplied in .env.example with the endpoint for your environment. The broker must be able to reach it and retrieve the public keys needed to validate your signers' tokens.


Did this page help you?