General reference

OAuth2 Secured Sessions

OAuth2 Secured Sessions is a configurable setting in Workflows and Flows that mitigates security risks associated with redirect-based webflows.

When enabled, the Workflow or Flow runs as part of an OAuth 2.0 / OpenID Connect (OIDC) authorization flow. The onboarding process itself serves as the authentication step. After the user completes onboarding successfully, the authorization server issues an authorization code.

When the OAuth2 Secured setting is enabled on a Workflow or Flow:

  • A dedicated OIDC client is automatically generated. This OAuth client ID is visible in the Workflow or Flow settings after saving. The client is configured with:
    • Authorization Code grant
    • Proof Key for Code Exchange (PKCE) S256
  • The Workflow or Flow execution is part of an OIDC authentication process
  • A redirect URL becomes mandatory.
    • If you change this URL later, you must update it in the Workflow or Flow configuration and in all client authorize and token requests. Mismatches cause authorization failures.
  • Disabling and re-enabling the setting regenerates the OAuth client and invalidates the previous one.

When a Workflow or Flow uses OAuth security, the legacy incodesmile.com URL scheme no longer works for that Flow ID. You must use the new URL scheme and authorization pattern described below. This prevents security gaps caused by manual URL tampering.

Security Model

The generated OAuth client uses Proof Key for Code Exchange (PKCE) (RFC 7636) and does not require a client secret. This makes the secured session flow suitable for Single Page Applications (SPAs), mobile applications, or any client unable to securely store secrets.

PKCE protects the authorization code from interception by binding it to a cryptographically random verifier known only to the client.

OpenID Connect (OIDC) Authorization Flow

The following diagram shows the sequence of a successful onboarding using OIDC:

Sequence diagram showing a successful OIDC onboarding flow between client, authorization server, and Omni API

The following diagram shows the sequence of a failed onboarding using OIDC:

Sequence diagram showing a failed OIDC onboarding flow with error response

Step 1: Authorization Request (/oauth2/authorize)

Before initiating the authorization request, the client must:

  1. Generate a cryptographically random code_verifier and store it

  2. Compute the code_challenge by hashing the code_verifier with SHA-256

  3. Generate a state parameter that is used for CSRF protection. The value should be:

    • Cryptographically random
    • High entropy (unguessable)
    • Unique per authorization request

    Store state in memory for SPAs, or in a secure session cookie or session-keyed in-memory cache for a Backend for Frontend (BFF) layer. For more detail, see RFC 6749 §10.12.

  4. Generate a nonce parameter to prevent ID token replay attacks. The value should be:

    • High-entropy

    • Unique per authentication request

    • Same quality as state

      Store nonce the same way you store state. For more detail, see the OIDC nonce notes.

The well-known endpoint for automatic discovery of configuration, endpoints, and key sets is at https://auth.incode.com/.well-known/openid-configuration.

Authorization Request Parameters

Parameter Description
client_id OAuth Client ID generated and stored in the Workflow/Flow settings.
redirect_uri Redirect URI configured in the Workflow/Flow settings.
response_type code
scope openid
state Opaque value used to maintain request/response integrity
nonce Value used to associate the ID Token with the client session and prevent replay attacks
code_challenge_method S256
code_challenge Generated PKCE challenge
response_mode form_post
external_customer_id
Optional
ID that identifies user in clients external system

Example Authorization Request

https://auth.incode.com/oauth2/authorize
?client_id={client_id}
&redirect_uri={redirect_uri}
&scope=openid
&response_type=code
&response_mode=form_post
&state={state}
&nonce={nonce}
&code_challenge_method=S256
&code_challenge={codeChallenge}
&external_customer_id={external_customer_id}

Here's what this request does:

  • The user is redirected to the Incode authorization server.
  • The associated Workflow or Flow runs as part of the /authorize endpoint.
  • If onboarding succeeds:
    • The user is redirected back to redirect_uri.
    • An authorization code and state are returned in the URL.
    • The client must verify the state parameter on callback by comparing the returned value to the stored one. If it's missing or doesn't match, abort the process.
  • If onboarding fails:
    • The user is redirected back to redirect_uri.
    • Error and error description parameters are included in the URL (see the OIDC error spec).

Step 2: Token Exchange (/oauth2/token)

The client exchanges the authorization code for tokens. Client authenticates using the code_verifier generated in Step 1.

Token Request Parameters

Parameter Description
grant_type authorization_code
code Authorization code from Step 1
client_id Client ID used in the authorize request
redirect_uri Redirect URI used in the authorize request
code_verifier Original PKCE code verifier

Example Token Response Body

{
  "access_token": "eyJraWQiOiI2MzM2NjAy....zAZ4-FboQg",
  "scope": "openid profile",
  "id_token": "eyJraWQiOiI2MzM2NjAyYy05....O3dDfO13Yyg",
  "token_type": "Bearer",
  "expires_in": 86399
}

After a successful response, client must validate ID token. Validation must confirm that:

  • The issuer identifier exactly matches the iss claim.
  • The aud claim contains the client's client_id value.
  • The JWS signature is valid, using the algorithm in the JWT header and the public key from the issuer's well-known JWKS endpoint.
  • The current time is before the exp claim.
  • The nonce claim exactly matches the nonce value the client sent in the authentication request.

Access token validation is the responsibility of the Omni server, and happens in Step 3.

Step 3: API Access

Use the access_token from Step 2 as a Bearer token in the Authorization header instead of the x-incode-hardware-id header. The token:

  • Is required to access Omni APIs
  • Is bound to a single session
  • Follows standard OAuth 2.0 token validation rules

Example curl request with OAuth Secured Workflows/Flows

curl --location 'https://saas-api.incodesmile.com/omni/get/score' \
--header 'Content-Type: application/json' \
--header 'api-version: 1.0' \
--header 'x-api-key: 13cf313e0db1507e77bf8d0631f3ca736173ccde' \
--header 'Authorization: Bearer eyJraWQiOiI2MzM2Nj.....Lf_N7hww'

You can use this token with the following endpoints:

  • omni/get/score
  • omni/get/custom-fields
  • omni/get/onboarding/status
  • omni/get/ocr-data

Was this page helpful?