OAuth2 Secured Sessions
This page provides a technical and detailed look into the OAuth2 Secured setting within Workflows and Flows.
This feature is a configurable setting in Workflows and Flows. It is designed to mitigate security risks associated with webflows that rely on redirection.
This functionality enforces execution of the flow or workflow as part of an OAuth 2.0 / OpenID Connect (OIDC) authorization flow. In this mode, the onboarding process is executed during the OIDC authorization request and serves as the authentication mechanism, after which the authorization server issues an authorization code upon successful completion.
When the OAuth2 Secured flag is enabled on a Workflow or Flow:
- A dedicated OIDC client is automatically generated. This OAuth client id is visible in the Workflow/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.
- Any future change to this URL must be updated on the Workflow/Flow configuration and all client authorize and token requests. Mismatches result in authorization failures.
- Disabling and re-enabling the flag regenerates the OAuth client and invalidates the previous client.
When a Workflow or Flow is configured for OAuth security, the old incodesmile URL scheme does not work for that flowid. Customers must move to new URL scheme and authorization pattern described in this document. This ensures there are no security gaps with 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 generated verifier known only to the client.
OpenID Connect (OIDC) Authorization Flow
The following diagram shows the sequence of a successful onboarding using OIDC:
The following diagram shows the sequence of a failed onboarding using OIDC:
Step 1: Authorization Request (/oauth2/authorize)
/oauth2/authorize)Before initiating the authorization request, the client must:
-
Generate a cryptographically random
code_verifierand store it -
Compute the
code_challengeas a transformation of thecode_verifierusing Secure Hash Algorithm 256-bit (SHA-256) -
Generate
stateparameter that is used for CSRF protection.- cryptographically random value
- High entropy (random, unguessable)
- Per authorization request
See more here.
Store state in memory for SPA applications or securely in session cookie or in-memory cache (keyed by session) in BFF
-
Generate
nonceparameter that is used to mitigate id replay attacks.- High-entropy
- Unique per authentication request
- Same quality as state See more here. Store nonce in memory for SPA applications or securely in session cookie or in-memory cache (keyed by session) in a Backends for Frontends (BFF) layer.
Well known endpoint for automatic discovery of configuration, endpoints, and key sets can be found 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 | Id that identifies user in clients external system - optional |
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}A breakdown of what this request does:
- The user is redirected to the Incode Authorization Server.
- The associated Workflow/Flow is executed as part of the
/authorizeendpoint - On successful onboarding completion:
- The user is redirected back to
redirect_uri - An authorization code and state are returned in url
- Client needs to verify state parameter on callback
- Compare returned state with stored value. If missing or mismatched → abort process
- The user is redirected back to
- On failed onboarding completion:
- The user is redirected back to
redirect_uri - Error and error description url parameters are included (oidc spec).
- The user is redirected back to
Step 2: Token Exchange (/oauth2/token)
/oauth2/token)The client exchanges the authorization code for tokens. Client authenticates using 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 include:
- The Issuer Identifier must exactly match the value of the
iss(issuer) Claim. - The
aud(audience) Claim contains itsclient_idvalue - The JWS signature is verified using the algorithm indicated in the JWT header and the corresponding public key obtained from the Issuer’s well-known JWKS endpoint.
- The current time must be before the time represented by the
expClaim. - The
nonceclaim must exactly match thenoncevalue sent by the Client in the authentication request.
Validation of the access token is responsibility of the omni server, and it is done is Step 3.
Step 3: API Access
The access_token issued in Step 2 must be used as a Bearer authorization header (instead of the x-incode-hardware-id header). The token:
- Is required for accessing Omni APIs
- Is bound to a single session
- Adheres to 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'Endpoints we can call with this token:
omni/get/scoreomni/get/custom-fieldsomni/get/onboarding/statusomni/get/ocr-data
Updated about 2 hours ago
