Authentication

For engineers connecting a bank system to the Quant Flow Platform. How to obtain, use and refresh an access token, and what a rejected token looks like.

Who this is for

Integration engineers and security reviewers. This page covers sign-in, the access token protected requests carry, token refresh, first sign-in for an invited user, and how authentication failures are reported.

How authentication works

Protected API requests go to your assigned gateway with a bearer token in the Authorization header:

Authorization: Bearer <access token>

The access token is a JWT issued by the platform's user pool. It carries two claims the platform relies on:

ClaimMeaning
subThe calling principal: a user or a machine client.
tenant_idThe organisation the request is scoped to.

The gateway verifies the token's signature, issuer and expiry. A missing, expired or malformed token is rejected with 401.

Tenant-scoped operations use the organisation in the token. Where an endpoint also names an organisation in its path, it must match the caller's authorised organisation. Follow each endpoint's access rules rather than assuming all reads are tenant-local: SYSTEM templates are shared resources. The user-by-ID lookup is explicitly not tenant-scoped; use your own profile and your organisation's team list for routine integration screens.

Five customer bootstrap operations declare no bearer requirement:

OperationAuthority used
Sign inUser credentials
Refresh user tokensRefresh token
Complete the first-password challengeChallenge session and new password
Activate an invited userTemporary password and new password
Reveal a machine-client secret onceOne-time token in the URL; treat that URL as a secret

Obtain an access token

Sign in with POST /api/auth/login. The response contains either tokens or a challenge, never both.

OutcomeFields returnedWhat to do
TokensaccessToken, refreshToken, tokenType, expiresInUse accessToken as the bearer token. Store refreshToken securely.
Challengechallenge, sessionComplete the challenge before any token is issued. See First sign-in for an invited user.

expiresIn is the access token lifetime in seconds. The spec examples show 3600, and the refresh endpoint describes the access token as lasting 60 minutes. Read expiresIn from each response and do not hard-code the lifetime.

The user sign-in response returns an access token, not an ID token. Use the access token for protected API calls; bootstrap operations use the authority listed above.

Machine clients

A bank's back-office system calls the API as a machine client. Machine clients do not use the email and password sign-in. They use the OAuth 2.0 client credentials grant:

  1. The system authenticates to the identity provider's token endpoint with its client credentials.
  2. The identity provider returns a short-lived access token (a JWT). The client identifier becomes the token's sub.
  3. The system sends the token as the bearer token on every call, exactly as a user token is sent.
  4. The gateway checks the token's signature against the identity provider's published signing keys (JWKS), and its issuer and expiry, on every request.

Who runs the identity provider depends on the deployment model. See Deployment model.

DeploymentIdentity providerWho issues and rotates client credentials
Quant-hostedOperated by QuantQuant
Client-hostedThe bank's configured, trusted identity providerThe bank

In a client-hosted deployment, agree the supported identity-provider integration before registering each confidential client. Verify the trusted issuer, signing keys, audience, required claims and supported client-authentication method against the deployed gateway and services. Standards compliance alone does not make an arbitrary issuer or JWT acceptable. Token lifetime and credential acquisition are set by the configured identity provider.

Your onboarding configuration must include the identity-provider token endpoint, client identifier, credential format and rotation procedure. Store machine secrets in a secret manager; do not call the user login endpoint as a substitute for client credentials.

Use the audience and scopes assigned to your client by the identity provider. The public contract does not publish a per-endpoint OAuth scope map; check endpoint permissions and test access with the assigned identity.

Revoking access

  • For a user session, suspend the user or use the configured global sign-out process to stop refresh-token use. Verify the effect in your environment.
  • Machine clients obtain tokens through client credentials, rather than the user refresh flow. Revoke or rotate their credentials through the assigned identity provider and machine-client administration process; verify that the retired client cannot obtain new tokens.
  • An already issued JWT may remain cryptographically valid until expiry. Some endpoints additionally check the user's current status and reject deactivated users immediately. Test both existing-token use and new-token acquisition after access removal; do not assume all endpoints behave alike.
  • Set token lifetimes and emergency revocation procedures with the identity owner. See Access changes and offboarding.

Choose the correct authentication flow

%%{init: {"theme": "neutral"}}%%
flowchart TB
    Person["Named user"] --> Login["POST auth/login / invitation challenge if needed"]
    Login --> UserToken["Access token / refresh token"]
    Machine["Backend machine client"] --> IdP["Deployment identity provider / client credentials"]
    IdP --> MachineToken["Access token"]
    UserToken --> Gateway["Bearer token + API-Version"]
    MachineToken --> Gateway
    Gateway --> Scoped["Validated identity / organisation-scoped API"]

The identity-provider token endpoint for machine clients is supplied during onboarding. It is distinct from the public user login endpoint. Never place machine secrets in a browser client.

User sign-in · Refresh user token · One-time machine secret reveal

Refresh an access token

Exchange the refresh token at POST /api/auth/refresh for a new access token with the same claims.

  • No new refresh token is returned. Keep the one issued at sign-in until it expires.
  • The refresh token's lifetime is set on the platform's side. Use the refresh-token expiry and rotation rules configured by the identity provider. On refresh rejection, require a new sign-in rather than repeatedly replaying the expired credential.
  • Expiry, revocation and a disabled account all end the session. Every failure returns the same 401 with the message Refresh token is invalid or expired. When you receive it, sign in again.

First sign-in for an invited user

An invited user receives a temporary password. Their first POST /api/auth/login returns the challenge NEW_PASSWORD_REQUIRED with a session value, and no token.

There are two ways to complete it:

EndpointRequestUse when
POST /api/auth/new-passwordemail, newPassword, sessionYou have already called login and hold the session.
POST /api/auth/activateemail, temporaryPassword, newPasswordYou want to activate in one call.

Both return tokens and set the user to ACTIVE. The temporary password cannot be used again. Password complexity is enforced by the user pool policy. Use the password policy supplied with your environment and display the returned validation error when a new password is refused.

Maintain the backend identity

Keep the token endpoint, issuer, client identifier, credential owner and approved rotation process in the environment record. Cache access tokens only for their permitted lifetime; route failed refresh or credential acquisition to the bank's identity/integration team. Do not repeatedly submit business writes under a token that cannot be authenticated.

Credential replacement changes access, not instruction identity. Preserve original idempotency keys and unresolved transaction IDs across the cutover so recovery does not duplicate payments. Verify the replacement client's authorised reads and writes in non-production, then retire the old credentials through the identity provider. Follow Access changes and offboarding.

Worked example

Sign in

POST /api/auth/login HTTP/1.1
Host: api.qfp.quantnetwork.net
API-Version: 1.0.0
Content-Type: application/json

{
  "email": "[email protected]",
  "password": "S3cret!Passw0rd"
}
HTTP/1.1 200 OK
Content-Type: application/json

{
  "accessToken": "eyJraWQiOiJ...",
  "refreshToken": "eyJjdHkiOiJ...",
  "tokenType": "Bearer",
  "expiresIn": 3600
}

If the user has not yet set a password, the same call returns:

{
  "challenge": "NEW_PASSWORD_REQUIRED",
  "session": "AYABeC..."
}

Call the API with the token

Illustrative example built from the schema.

GET /api/transactions/3f7c1a90-5d2e-4b08-9a41-6c2b8e5d7f13 HTTP/1.1
Host: api.qfp.quantnetwork.net
Authorization: Bearer eyJraWQiOiJ...
API-Version: 1.0.0

Refresh

POST /api/auth/refresh HTTP/1.1
Host: api.qfp.quantnetwork.net
API-Version: 1.0.0
Content-Type: application/json

{
  "refreshToken": "eyJjdHkiOiJ..."
}
HTTP/1.1 200 OK
Content-Type: application/json

{
  "accessToken": "eyJraWQiOiJ...",
  "tokenType": "Bearer",
  "expiresIn": 3600
}

View in API Reference

Errors and edge cases

StatusWhenClient action
400The sign-in body failed validation. The message reads Invalid Request parameter. {field}, or Malformed JSON request for unreadable JSON.Fix the request. Do not retry unchanged.
401 on login, new-password or activateWrong credentials, a user with no organisation, or a user whose status is not ACTIVE. Always Invalid credentials. The reason is not disclosed.Do not retry automatically. Check the credentials and the user's status with your administrator.
401 on refreshThe refresh token is expired or revoked, or the account is disabled. Always Refresh token is invalid or expired.Sign in again.
401 on any other endpointNo token, or a token that failed verification.For a user, refresh once or sign in again. For a machine client, obtain a new token from its configured identity provider once; escalate persistent rejection. Preserve the original write key.
403The token is valid but the caller lacks the permission, or a path names another organisation.Do not retry. See Roles and access.
500 on sign-inThe sign-in service could not complete the request.Retry with backoff.

Edge cases:

  • Refresh before expiry. Use expiresIn to refresh shortly before the access token expires, so in-flight requests do not fail with 401.
  • One token per principal. Approvals enforce separation of duties by comparing the approver's sub with the initiator's. A flow that needs an approver needs a second identity. See Policy, approvals and audit.
  • Deactivated users. A user whose status is no longer ACTIVE receives 401 with Your access has been revoked. on identity endpoints, even with an unexpired token.
  • The 401 body differs by endpoint. All share the error envelope described in Errors, but the message text varies. Branch on the HTTP status. Do not parse the message.

You do not need to verify access tokens yourself. The gateway validates every token before a request reaches the platform. In a client-hosted deployment the issuer and signing keys are those of your own identity provider. If your application needs independent token verification, obtain the expected issuer, audience and trusted JWKS location from your identity-provider configuration. Never select a verification key URL from an untrusted token.

API Reference

Open an endpoint for request fields, response examples and the interactive API console.

Related pages

Implementation resources

Machine clients code recipes.

Use Implement a backend client for request handling, durable idempotency and outcome tracking. The developer integration coverage map links every public operation to its API Reference and contract-derived code recipe. Replace example identifiers with values from your assigned environment.


Did this page help you?