# OIDC Automatic Configuration

Incode's web-based Onboarding Flows and Workflows that use redirects can be vulnerable to certain security attacks. To address this, you can enable a setting called **OAuth2 Secured**. When you enable that setting, the Flow or Workflow runs as part of a standard OAuth 2.0/OpenID Connect (OIDC) process.

After the user successfully completes the Flow or Workflow, a dedicated OIDC client is automatically generated, configured with:

- An authorization code grant
- A Proof Key for Code Exchange (PKCE) hashed using SHA-256

When you enable **OAuth2 Secured**, a redirect URI is mandatory.

Automatic configuration pre-defaults most other settings for you and does not expose controls for requested scopes,the post-logout redirect URI, or user consent. If you need control over these settings, use [manual configuration](https://developer.incode.com/docs/oidc-manual-configuration) instead.

<Callout icon="⚠️" theme="warn">
  ### Warning

  Disabling and re-enabling **OAuth2 Secured** generates a new OAuth client and invalidates the previous `client_id`. You must update all client integrations with the new `client_id`.

  Also, any change to the redirect URI must be updated in your Flow or Workflow configuration and reflected in all authorization and token requests. Mismatched URIs will cause authorization failures.
</Callout>

Follow the steps on this page to implement OIDC authentication for your Flow or Workflow. Complete them in order.

***

## Enable OAuth2 Secured

1. In Dashboard, click **Flow Builder** in the left menu, then click **Flows** or **Workflows**, depending on which you are configuring.
2. Click the **Settings** tab at the top.
3. In the User Experience section, enable **OAuth2 Secured (web only)**.
4. Scroll down to the After Verification section and enter your **Redirect URL**.
5. Click **Save Changes** for a Flow, **Save & Publish** for a Workflow.

After a Flow or Workflow is configured for OAuth security, its `flowid` no longer works with the incodesmile URL scheme. Follow the steps on this page to move to a new URL scheme and authorization pattern.

***

## Prepare the Authorization Request

1. Generate a cryptographically random `code_verifier` secret and store it. Then compute the `code_challenge` by hashing the `code_verifier` using SHA-256. This is the PKCE mechanism.

2) Generate a cryptographically random `state` value. This protects against <Anchor target="_blank" href="https://datatracker.ietf.org/doc/html/rfc6749#section-10.12">CSRF</Anchor> attacks. It must be unique per authorization request and stored securely: in memory for SPA applications, or in a session cookie or in-memory cache for BFF applications.
3) Generate a cryptographically random `nonce` value. This protects against ID token replay attacks. It must be unique per authentication request and stored the same way as `state`. For more information, see <Anchor target="_blank" href="https://openid.net/specs/openid-connect-core-1_0.html#NonceNotes">OpenID Connect Core: Nonce Notes</Anchor>.
4) Fetch your OIDC configuration from the well-known discovery endpoint: [https://auth.incode.com/.well-known/openid-configuration](https://auth.incode.com/.well-known/openid-configuration). This returns all the server endpoints, supported features, and public keys your application needs.

<Accordion title="Expand for descriptions of authorization request parameters">

| Parameter | Description |
|---|---|
| `client_id` | Required. Your OAuth client ID. Find this in Dashboard under your Flow or Workflow settings. |
| `redirect_uri` | Required. The URI the authorization server redirects to after the user completes the flow. Must exactly match the redirect URI configured in Dashboard for your Flow or Workflow. |
| `response_type` | Required. Must be `code`. This requests an authorization code, which your server exchanges for tokens. |
| `scope` | Required. Must include `openid`. This tells the server to return an ID token. Additional scopes may be added depending on your configuration. |
| `state` | Required. A cryptographically random, unguessable value generated per request. Used to prevent Cross-Site Request Forgery (CSRF) attacks. Your application must verify this value matches when the authorization server redirects back. |
| `nonce` | Required. A cryptographically random, unique value generated per request. Embedded in the ID token by the authorization server. Your application must verify this value matches to prevent token replay attacks. |
| `code_challenge_method` | Required. Must be `S256`. This specifies that the `code_challenge` was hashed using SHA-256. |
| `code_challenge` | Required. The PKCE code challenge. Derived by hashing the `code_verifier` using SHA-256. |
| `response_mode` | Required. Must be `form_post`. This tells the authorization server to return the authorization code via an HTTP POST rather than in the URL, which is more secure. |
| `external_customer_id` | Optional. Your identifier for the user. Use this to correlate the Incode session with a user in your own system. |
</Accordion>

***

## Send the Authorization Request

Construct the following URL and redirect the user's browser to it.

```http
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={code_challenge}
&external_customer_id={external_customer_id}
```

After you send the authorization request, the user is redirected to the Incode Authorization Server, where the associated Flow or Workflow runs as part of the `/authorize` endpoint.

After the Flow or Workflow completes, one of the following happens:

- **On failure**: The user is redirected to `redirect_uri` with `error` and `error_description` URL parameters. For details, see the <Anchor target="_blank" href="https://openid.net/specs/openid-connect-core-1_0.html#AuthError">OIDC spec</Anchor>.
- **On success**: The user is redirected to `redirect_uri` with an authorization code and `state` returned in the URL. You must verify the `state` parameter before proceeding. Compare the returned value with the one you stored before the request. If the value is missing or doesn't match, abort the process.

***

## Exchange the Authorization Code for Tokens

After the user completes the Flow or Workflow, your application receives an authorization code. Exchange it for tokens using the `/oauth2/token` endpoint.

### Token Request Parameters

| Parameter       | Description                                                                           |
| --------------- | ------------------------------------------------------------------------------------- |
| `grant_type`    | Required. Must be `authorization_code`.                                               |
| `code`          | Required. The authorization code returned from the authorization request.             |
| `client_id`     | Required. Must match the `client_id` used in the authorization request.               |
| `redirect_uri`  | Required. Must match the `redirect_uri` used in the authorization request.            |
| `code_verifier` | Required. The original PKCE code verifier generated before the authorization request. |

### Example Token Response

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

### Validate the ID Token

After a successful response, validate the ID token before use. Complete the following checks:

1. Verify the `iss` (issuer) claim exactly matches the Issuer Identifier.
2. Verify the `aud` (audience) claim contains your `client_id`.
3. Verify the JWS signature using:
   - The algorithm specified in the JWT header
   - The corresponding public key from the Issuer's JWKS endpoint. Go to [https://auth.incode.com/.well-known/openid-configuration](https://auth.incode.com/.well-known/openid-configuration) and find the value of `jwks_uri`.
4. Verify the current time is before the time in the `exp` (expiration) claim.
5. Verify the `nonce` claim exactly matches the `nonce` value you sent in the authorization request.

Access token validation is handled by the Incode Platform in the next step.

***

## Access Incode Platform APIs

Use the `access_token` from the previous step to make authenticated requests to the Incode Platform APIs. Include it as a Bearer token in the `Authorization` header.

If you previously sent the `x-incode-hardware-id` header, stop sending it. Use the `Authorization` header with the Bearer token instead.

The access token is bound to a single session. Standard OAuth 2.0 token validation rules apply.

### Example Request

```http
curl --location 'https://saas-api.incodesmile.com/omni/get/score' \
--header 'Content-Type: application/json' \
--header 'api-version: 1.0' \
--header 'x-api-key: <API-KEY>' \
--header 'Authorization: Bearer eyJraWQiOiI2MzM2Nj.....Lf_N7hww'
```

The following endpoints accept this token:

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

<br />
