> ## Documentation Index
> Fetch the complete documentation index at: https://docs.corsa.finance/llms.txt
> Use this file to discover all available pages before exploring further.

# Use your own identity provider (OIDC)

> Let HYOK decryptors sign in to the Secure Viewer with your own OIDC identity provider, such as Okta or Microsoft Entra ID, instead of Cognito.

By default, the people who decrypt sign in with Cognito, which the HYOK stack sets up in your AWS account. If you already manage identities in an OIDC identity provider, such as Okta or Microsoft Entra ID, your users can sign in to the Secure Viewer with it instead. They use their existing account, MFA, and sign-in policies. You manage who can decrypt with a group in your identity provider.

With your own identity provider, the stack doesn't set up Cognito, and there's no emailed code or passkey step.

<Note>
  This page is about signing in to the Secure Viewer to decrypt HYOK fields. Signing in to the Corsa app itself is configured separately. See [Single sign-on](/security/sso).
</Note>

***

## Requirements

| Requirement | Details |
| - | - |
| **Issuer** | An HTTPS issuer URL. `<issuer>/.well-known/openid-configuration` must be reachable from the internet and report exactly the same `issuer`. Tokens must be signed with RS256 or ES256 |
| **Client** | A public client (no client secret) for a single-page application, using the **authorization code** flow with **PKCE**. It must allow the `openid` and `email` scopes |
| **Audience** | The `aud` (or `client_id`) value in the tokens your identity provider issues to this client. For most setups, this is the client ID |
| **Redirect URI** | The Secure Viewer's address followed by `/oidc/callback`. After the stack is created, the stack's `OidcRedirectUri` output shows the exact value |
| **Decryptor group claim** | A claim in the token that contains a value only decryptors have, for example a `groups` claim that contains `corsa-hyok-decryptors`. The claim can be a string or an array |
| **Email claim** | A claim with the user's email, `email` by default. It must equal the email of the user's Corsa account. Case doesn't matter |

You enter these values in the install wizard when you choose **Your identity provider (OIDC)**. Corsa checks that the issuer uses HTTPS and that its discovery document is reachable and matches, then prefills them for your stack.

### Order of steps

The redirect URI contains the Secure Viewer's URL, which exists only after the stack is created. So you set up the client in two passes:

<Steps>
  <Step title="Create the client">
    Create the OIDC client in your identity provider, the decryptor group, and the group and email claims. Note the issuer, client ID, and audience.
  </Step>

  <Step title="Install the stack">
    In Corsa, choose **Your identity provider (OIDC)**, enter the values, and [deploy the stack](/hyok/setup#deploy-the-stack).
  </Step>

  <Step title="Add the redirect URI">
    Copy the redirect URI (the stack's `OidcRedirectUri` output) and add it to the client's redirect URIs. For Okta, also add the Secure Viewer's address (the stack's `ViewerUrl` output) as a trusted origin.
  </Step>

  <Step title="Complete setup">
    A workspace Owner who is in the decryptor group opens an encrypted field in Corsa and signs in through your identity provider. This first sign-in completes setup.
  </Step>
</Steps>

***

## Example: Okta

<Steps>
  <Step title="Create the app integration">
    In the Okta Admin Console, go to **Applications** → **Applications** → **Create App Integration**. Choose **OIDC - OpenID Connect** and **Single-Page Application**.

    * **Grant type:** **Authorization Code**. Okta uses PKCE for single-page applications.
    * **Sign-in redirect URIs:** add a placeholder for now, for example `https://localhost/oidc/callback`. You'll replace it after the stack is created.
    * **Assignments:** assign the decryptor group, or everyone who might decrypt.
  </Step>

  <Step title="Create the decryptor group">
    Go to **Directory** → **Groups**, create `corsa-hyok-decryptors`, and add the people who may decrypt.
  </Step>

  <Step title="Add the groups claim">
    Open the app → **Sign On** → **OpenID Connect ID Token** → **Edit**. Set **Groups claim type** to **Filter**, the claim name to `groups`, and the filter to **Equals** `corsa-hyok-decryptors`.
  </Step>

  <Step title="Enter the values in Corsa">
    | Field | Value |
    | - | - |
    | Issuer URL | `https://your-org.okta.com` |
    | Client ID | The app's **Client ID** |
    | Audience | The same client ID |
    | Decryptor claim | `groups` |
    | Decryptor value | `corsa-hyok-decryptors` |
    | Email claim | `email` |
  </Step>

  <Step title="Finish after the stack is created">
    Replace the placeholder sign-in redirect URI with the `OidcRedirectUri` output. Then go to **Security** → **API** → **Trusted Origins** and add the `ViewerUrl` output with **CORS** enabled.
  </Step>
</Steps>

If you use a custom authorization server, for example `https://your-org.okta.com/oauth2/default`, use its URL as the issuer and add the `groups` claim in that authorization server instead.

***

## Example: Microsoft Entra ID

<Steps>
  <Step title="Register the application">
    In the Microsoft Entra admin center, go to **Identity** → **Applications** → **App registrations** → **New registration**. Under **Redirect URI**, choose **Single-page application (SPA)** and enter a placeholder, for example `https://localhost/oidc/callback`. Entra ID uses the authorization code flow with PKCE for SPA redirect URIs.
  </Step>

  <Step title="Create the decryptor group">
    Create a security group, for example `corsa-hyok-decryptors`, add the people who may decrypt, and note its **Object ID**.
  </Step>

  <Step title="Add the groups and email claims">
    In the app registration, open **Token configuration**:

    * **Add groups claim:** choose **Security groups**, or **Groups assigned to the application**, and emit **Group ID** in the ID and access tokens.
    * **Add optional claim:** choose **ID** and add `email`.

    Make sure every decryptor's Entra ID account has an email address that matches their Corsa account.
  </Step>

  <Step title="Enter the values in Corsa">
    | Field | Value |
    | - | - |
    | Issuer URL | `https://login.microsoftonline.com/<your-tenant-id>/v2.0` |
    | Client ID | The app's **Application (client) ID** |
    | Audience | The same client ID |
    | Decryptor claim | `groups` |
    | Decryptor value | The group's **Object ID** |
    | Email claim | `email` |
  </Step>

  <Step title="Finish after the stack is created">
    In **Authentication**, replace the placeholder SPA redirect URI with the `OidcRedirectUri` output.
  </Step>
</Steps>

<Note>
  Entra ID emits group **Object IDs**, not group names, in the `groups` claim. If a user belongs to more than 200 groups, Entra ID leaves the groups out of the token, and that user can't decrypt. Use **Groups assigned to the application** and assign the decryptor group to the app to avoid this.
</Note>

***

## How unwrap authorization works

Unwrapping a data key still needs **two tokens**, as with Cognito. Your identity provider's token replaces the Cognito token. The [Corsa unwrap token](/hyok/index#what-happens-when-a-user-views-a-field) and resource binding don't change.

1. The user signs in to the Secure Viewer through your identity provider.
2. Corsa checks that the user may view the record, then issues a short-lived Corsa unwrap token that names the user's email and the requested fields.
3. The Secure Viewer sends the wrapped data key to the decryption check in your account with both tokens.
4. Your stack checks your identity provider's token:
   * its signature, against the keys published by your issuer (your stack caches them for 10 minutes);
   * `iss` equals your issuer, and `aud` or `client_id` equals your audience;
   * it isn't expired or not yet valid, with 60 seconds of tolerance;
   * the decryptor claim contains the decryptor value.
5. Your stack checks the Corsa token as usual: its signature, expiry, your stack and workspace, and the requested field.
6. The email claim in your token must equal the email in the Corsa token, ignoring case. This ties the person signed in to your identity provider to the Corsa user whose access Corsa checked.
7. Only then does your stack use your KMS key to unwrap the data key.

So Corsa alone still can't decrypt: it has no identity in your identity provider. And a user of your identity provider alone can't decrypt either: they also need a Corsa token issued after Corsa's access check, for their own email.

### Grant and remove access

* **Grant:** add the person to the decryptor group in your identity provider. They also need a Corsa account with the same email.
* **Remove:** remove them from the group, or disable their account. Tokens already issued stay valid until they expire, so keep token lifetimes short. To stop all decryption at once, disable your HYOK key in AWS KMS. See [Control access to decryption](/hyok/operations#control-access-to-decryption).

***

## Limitations

* **One identity provider per stack.** The stack trusts a single issuer and client.
* **Choose at install.** The upgrade flow keeps your current identity provider settings. To switch between Cognito and your own identity provider later, contact Corsa. If you switch an existing Cognito stack, your Cognito users stay in your account. Delete them yourself when you no longer need them.
* **Public issuer only.** Your stack fetches your issuer's discovery document and keys from your AWS account over the internet. An identity provider that's only reachable on your private network doesn't work.
* **Algorithms.** Only RS256 and ES256 token signatures are accepted.
* **Sign-in strength is yours.** Corsa doesn't add a passkey step. Enforce MFA for the client in your identity provider.
* **Revocation isn't instant.** Removing someone from the group takes effect when their current token expires. After you rotate your identity provider's signing keys, your stack picks up the new keys within 10 minutes.
* **Email must match.** Users whose email claim is missing, or differs from their Corsa email, can't decrypt.
* **No `hyok-decryptors` Cognito group.** The Cognito-specific steps in [Setup](/hyok/setup#add-decryptors), including the first administrator, don't apply.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.