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
- Your client signs in with your identity provider and obtains a JWT.
- The client sends the token to the io.sign API in the
Authorization: Bearer <JWT>header. - The API matches the token's
issclaim to an issuer inJWT_PROVIDERSand validates it using that provider's JSON Web Key Set (JWKS). - 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
| Provider | Status | Details |
|---|---|---|
| Clerk | Implemented | Integration with Clerk SDK, including Clerk API key validation and team management |
| OpenID Connect (OIDC) | Implemented | Generic JWT validation using your provider's issuer and JWKS endpoint |
| WorkOS | Coming soon | Dedicated integration |
| Auth0 | Coming soon | Dedicated 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
issclaim. - 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:
| Field | Required | Purpose |
|---|---|---|
issuer | Yes | Matches the token's iss claim exactly, including the scheme and any trailing slash. |
jwksUri | Yes | Identifies the JWKS endpoint used to validate the token's signature. Use the endpoint supplied by your provider. |
audience | No | Sets the expected token audience. |
algorithms | No | Restricts 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=clerkandAPP_CONFIG_AUTH_PUBLISHABLE_KEY. - OIDC: set
APP_CONFIG_AUTH_STRATEGY=oidc,APP_CONFIG_AUTH_ISSUER_URL,APP_CONFIG_AUTH_CLIENT_ID, andAPP_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.
| Symptom | What to check |
|---|---|
JWT_INVALID_ISSUER | Compare the token's iss claim with JWT_PROVIDERS; the values must match exactly. |
| Token validation fails | Check 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 fails | Check 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.jsonDocker 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 endpointReplace the io.finnet development endpoint supplied in
.env.examplewith the endpoint for your environment. The broker must be able to reach it and retrieve the public keys needed to validate your signers' tokens.
Updated about 1 month ago