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

# OpenID Connect Action

> The OpenID Connect (OIDC) action restricts access to only authorized users by enforcing OIDC through an identity provider of your choice.

export const ConfigChildren = ({children}) => {
  return <Accordion title="Show Child Properties">
      {children}
    </Accordion>;
};

export const ConfigField = ({title, type, cel = false, defaultValue = false, required = false, children}) => {
  const id = `config-${title.replace(/\.|\s|\*/g, "_")}`;
  return <div className="field pt-2.5 pb-5 my-2.5 border-gray-50 dark:border-gray-800/50 border-b" style={{
    scrollMarginTop: '120px'
  }} id={id}>
      <div className="flex font-mono group/param-head param-head break-all relative">
        <div className="flex-1 flex content-start py-0.5 mr-5">
          <div className="flex items-center flex-wrap gap-2">
            <div class="absolute -top-1.5">
              <a href={`#${id}`} className="-ml-10 flex items-center opacity-0 border-0 group-hover/param-head:opacity-100 py-2 [.expandable-content_&]:-ml-[2.1rem]" aria-label="Navigate to header">
                ​<div className="w-6 h-6 rounded-md flex items-center justify-center shadow-sm text-gray-400 dark:text-white/50 dark:bg-background-dark dark:brightness-[1.35] dark:ring-1 dark:hover::rightness-150 bg-white ring-1 ring-gray-400/30 dark:ring-gray-700/25 hover:ring-gray-400/60 dark:hover:ring-white/20">
                  <svg xmlns="http://www.w3.org/2000/svg" fill="gray" height="12px" viewBox="0 0 576 512"><path d="M0 256C0 167.6 71.6 96 160 96h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C98.1 144 48 194.1 48 256s50.1 112 112 112h72c13.3 0 24 10.7 24 24s-10.7 24-24 24H160C71.6 416 0 344.4 0 256zm576 0c0 88.4-71.6 160-160 160H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c61.9 0 112-50.1 112-112s-50.1-112-112-112H344c-13.3 0-24-10.7-24-24s10.7-24 24-24h72c88.4 0 160 71.6 160 160zM184 232H392c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z"></path></svg>
                </div>
              </a>
            </div>
            <div className="font-semibold text-primary dark:text-primary-light overflow-wrap-anywhere">{title}</div>
            <div className="inline items-center gap-2 text-xs font-medium [&_div]:inline [&_div]:mr-2 [&_div]:leading-5 [&_a]:inline [&_a]:mr-2 [&_a]:leading-5">
              {type && <div className="flex items-center px-2 py-0.5 rounded-md bg-gray-100/50 dark:bg-white/5 break-all">
                <span className="text-gray-600 dark:text-gray-200 !font-medium">{type}</span>
              </div>}
              {defaultValue && <div className="flex items-center px-2 py-0.5 rounded-md bg-gray-100/50 dark:bg-white/5 break-all">
                  <span class="text-gray-400 dark:text-gray-500">default:</span>
                  <span className="text-gray-600 dark:text-gray-200 !font-medium">{defaultValue}</span>
                </div>}
              {required && <div className="px-2 py-0.5 rounded-md bg-red-100/50 dark:bg-red-400/10 whitespace-nowrap">
                <span className="text-red-600 dark:text-red-300 !font-medium">Required</span>
              </div>}
              {cel && <a className="px-2 py-0.5 rounded-md !border-none bg-blue-100/50 dark:bg-blue-400/10 whitespace-nowrap" href="/traffic-policy/concepts/cel-interpolation">
                <span className="text-blue-600 dark:text-blue-300 !font-medium">Supports CEL</span>
              </a>}
            </div>
          </div>
        </div>
      </div>
      <div className="mt-4 prose-sm prose-gray dark:prose-invert [&_.prose>p:first-child]:mt-0 [&_.prose>p:last-child]:mb-0">
        {children}
      </div>
    </div>;
};

The **OpenID Connect** Traffic Policy action restricts access to only authorized users
by enforcing **OIDC** through an identity provider of your choice.

## Configuration reference

The [Traffic Policy](/traffic-policy/) configuration reference for this action.

### Supported phases

`on_http_request`

### Type

`openid-connect`

### Configuration fields

<ConfigField title="issuer_url" type="string" required={true}>
  The base URL of the Open ID provider that serves an OpenID Provider
  Configuration Document at `/.well-known/openid-configuration`.
</ConfigField>

<ConfigField title="auth_id" type="string" required={false}>
  Unique authentication identifier for this provider.
  Used to scope the session cookie and to target this provider in login and logout paths.
  See [Special paths](#special-paths).
</ConfigField>

<ConfigField title="client_id" type="string" required={false} cel={true}>
  Your OpenID Connect app's client ID.
</ConfigField>

<ConfigField title="client_secret" type="string" required={false} cel={true}>
  Your OpenID Connect app's client secret.
</ConfigField>

<ConfigField title="scopes" type="array of strings" required={false}>
  A list of additional scopes to request when users authenticate with the
  identity provider.
</ConfigField>

<ConfigField title="authz_url_params" type="map of string to string" required={false}>
  A map of additional URL parameters to apply to the authorization endpoint
  URL.
</ConfigField>

<ConfigField title="max_session_duration" type="duration" required={false}>
  Defines the maximum lifetime of a session regardless of activity.
</ConfigField>

<ConfigField title="idle_session_duration" type="duration" required={false}>
  Defines the period of inactivity after which a user's session is
  automatically ended, requiring re-authentication.
</ConfigField>

<ConfigField title="userinfo_refresh_interval" type="duration" required={false}>
  How often should ngrok refresh data about the authenticated user from the
  identity provider.
</ConfigField>

<ConfigField title="allow_cors_preflight" type="boolean" required={false}>
  Allow CORS preflight requests to bypass authentication checks. Enable if
  the endpoint needs to be accessible via CORS.
</ConfigField>

<ConfigField title="auth_cookie_domain" type="string" required={false}>
  Sets the allowed domain for the auth cookie.
</ConfigField>

### Special paths

#### Logging users in

To start an OIDC authentication flow explicitly—for example, from a "Log in" button or link—redirect users to `/ngrok/login`.
After a successful authentication, ngrok redirects the user to `/`.

If you've configured `auth_id` to identify this provider, include it in the URL:

```
/ngrok/login?auth_id=my-provider
```

If the IdP supports it, ngrok instructs it to force re-authentication—users must re-enter their credentials even if they already have an active IdP session.

#### Logging users out

To end a user's session—for example, from a "Log out" button or link—redirect users to `/ngrok/logout`.
This clears the ngrok session cookie.

If you've configured `auth_id`, include it in the URL to target the correct provider:

```
/ngrok/logout?auth_id=my-provider
```

<Note>
  When using the Google OAuth 2.0/OIDC provider in Chrome with a [managed profile](https://support.google.com/chrome/a/answer/188446), `/ngrok/logout` only clears the ngrok session cookie; it does not end the Google/IdP session maintained by the browser.
  Users may be silently re-authenticated on the next request.
  To fully sign out, sign out of Chrome or Google (or use a non-managed profile or Incognito) in addition to calling `/ngrok/logout`.
</Note>

### Events

When this module is enabled, it populates the following fields in the
[http\_request\_complete.v0](/obs/events/reference/#http-request-complete) event:

* `oauth.app_client_id`
* `oauth.decision`
* `oauth.user.id`
* `oauth.user.name`

### Supported providers

ngrok currently supports the following OAuth providers (see the Integration Guides for more details). In some instances, ngrok has a
[managed application](/traffic-policy/actions/oauth/#managed-applications) that allows you to configure OAuth without setting up your own application in your provider. This is useful for testing and
development, but when you move into production, use your own custom application in your specific provider.

| Provider  | Provider Identifier | Managed App Available | Integration Guide                                    |
| --------- | ------------------- | --------------------- | ---------------------------------------------------- |
| Amazon    | `amazon`            | no                    | [Documentation](/integrations/oauth/oauth/)          |
| Facebook  | `facebook`          | no                    | [Documentation](/integrations/oauth/facebook-oauth)  |
| GitHub    | `github`            | yes                   | [Documentation](/integrations/oauth/github-oauth)    |
| GitLab    | `gitlab`            | yes                   | [Documentation](/integrations/oauth/gitlab-oauth)    |
| Google    | `google`            | yes                   | [Documentation](/integrations/oauth/google-oauth)    |
| LinkedIn  | `linkedin`          | yes                   | [Documentation](/integrations/oauth/linkedin-oauth)  |
| Microsoft | `microsoft`         | yes                   | [Documentation](/integrations/oauth/microsoft-oauth) |
| Twitch    | `twitch`            | yes                   | [Documentation](/integrations/oauth/twitch-oauth)    |

## Try it out

Consult the list of [supported providers](#supported-providers) for
step-by-step integration guides.

## Behavior

### Callback URL

When you create your own OIDC app, you must specify a 'Callback URL' or
'Redirect URL' to the OIDC provider. When using ngrok's OIDC action, that
Callback URL is always:

```
https://idp.ngrok.com/oauth2/callback
```

### Authentication

When an unauthenticated request is made to an OIDC-protected endpoint, it
returns a redirect response that begins an authentication flow with the
configured identity provider. The original URI path is saved so that users can
be redirected to it if they successfully authenticate.

**If the user fails to authenticate with the identity provider**, ngrok will
display an error describing the failure returned by the identity provider and
prompt them to try logging in again.

**If the user successfully authenticates with the identity provider**, ngrok
will take the following actions:

* Check any authorization constraints you've defined (like allowed
  emails or allowed email domains). If the user is not authorized, ngrok renders
  an error and prompts them to try logging in again.
* Sets a [session cookie](#cookies) to avoid repeating the authentication flow again.
* Redirects the user to the original URI path they were attempting to access
  before the authentication flow began. If no such URI path was captured, they
  are redirected to `/`.

### Continuous authorization

When an authenticated user makes a request, ngrok will sometimes refresh a
user's data from the identity provider (email, name, etc) and re-evaluate
authorization constraints. This refresh is executed as a back channel request to
the identity provider; it is transparent to the user and they do not go through
a re-authentication flow.

The following circumstances trigger refresh and authorization re-evaluation:

* On a periodic interval defined by the [`userinfo_refresh_interval`](/traffic-policy/actions/oidc/#configuration-fields) parameter.
* If you update the OIDC configuration of the endpoint by restarting your
  agent with a new configuration.
* If you update the OIDC configuration of the endpoint.

If a previously authenticated user becomes unauthorized because their identity
provider information changed or because the OIDC action configuration changed,
they are presented an error and are prompted to try logging in again.

### Traffic Identities

ngrok's [Traffic Identities](/traffic-policy/identities/) feature can be used to observe
all of the authenticated user activity across your account in the ngrok
dashboard or via API. Whenever a user authenticates or accesses an endpoint
with a configured OIDC action, their Traffic Identity record is created or updated.

You may also use Traffic Identities to remotely log a user out by [revoking a
session](/traffic-policy/identities/#revoke-sessions).

### Cookies

This action sets two cookies in its operation. Cookies values are opaque to the
upstream service and must not be modified.

| Cookie    | Description                             |
| --------- | --------------------------------------- |
| `session` | Used to track an authenticated user.    |
| `nonce`   | Used to secure the authentication flow. |

### Non-terminating action

This is a **Non-terminating action**. It does not return a response, and will allow Traffic Policy processing to continue to the next Action in the chain. All **Cloud Endpoint** Traffic Policies must end with a terminating action. This requirement does not apply to **Agent Endpoints**.

## Examples

### Using a managed provider

The following [Traffic Policy](/traffic-policy/)
configuration will provide your app with an authentication step.

<CodeGroup>
  ```yaml policy.yml theme={null}
  on_http_request:
    - actions:
        - type: openid-connect
          config:
            issuer_url: '{your issuer url}'
            client_id: '{your app''s oauth client id}'
            client_secret: '{your app''s oauth client secret}'
            scopes:
              - openid
              - profile
              - email
  ```

  ```json policy.json theme={null}
  {
    "on_http_request": [
      {
        "actions": [
          {
            "type": "openid-connect",
            "config": {
              "issuer_url": "{your issuer url}",
              "client_id": "{your app's oauth client id}",
              "client_secret": "{your app's oauth client secret}",
              "scopes": [
                "openid",
                "profile",
                "email"
              ]
            }
          }
        ]
      }
    ]
  }
  ```
</CodeGroup>

## Action result variables

The following variables are made available for use in subsequent expressions and
CEL interpolations after the action has run. Variable values will only apply
to the last action execution, results are not concatenated.

<ConfigField title="actions.ngrok.oidc.error" type="object">
  <ConfigChildren>
    <ConfigField title="actions.ngrok.oidc.error.code" type="string">
      Code for an error that occurred during the invocation of an action.
    </ConfigField>

    <ConfigField title="actions.ngrok.oidc.error.message" type="string">
      Message for an error that occurred during the invocation of an action.
    </ConfigField>
  </ConfigChildren>
</ConfigField>

<ConfigField title="actions.ngrok.oidc.identity" type="object">
  <ConfigChildren>
    <ConfigField title="actions.ngrok.oidc.identity.id" type="string">
      Unique identifier for the ngrok Identity entity
    </ConfigField>

    <ConfigField title="actions.ngrok.oidc.identity.email" type="string">
      Email address of the authorized user from the provider.
    </ConfigField>

    <ConfigField title="actions.ngrok.oidc.identity.name" type="string">
      Name for the authorized user from the provider.
    </ConfigField>

    <ConfigField title="actions.ngrok.oidc.identity.provider_user_id" type="string">
      Identifier for the authorized user from the provider.
    </ConfigField>

    <ConfigField title="actions.ngrok.oidc.identity.current_session_id" type="string">
      The current Identity session identifier for this request.
    </ConfigField>
  </ConfigChildren>
</ConfigField>

<ConfigField title="actions.ngrok.oidc" type="object">
  <ConfigChildren>
    <ConfigField title="actions.ngrok.oidc.identity_token" type="string">
      The identity token from the provider for the current user.
    </ConfigField>

    <ConfigField title="actions.ngrok.oidc.access_token" type="string">
      The access token from the provider.
    </ConfigField>

    <ConfigField title="actions.ngrok.oidc.refresh_token" type="string">
      The refresh token from the provider.
    </ConfigField>

    <ConfigField title="actions.ngrok.oidc.expires_at" type="string">
      Timestamp when the current session will expire.
    </ConfigField>

    <ConfigField title="actions.ngrok.oidc.session_timed_out" type="boolean">
      Returns true when the session timed out.
    </ConfigField>

    <ConfigField title="actions.ngrok.oidc.session_max_duration_reached" type="boolean">
      Returns true when the current session reached the max duration.
    </ConfigField>

    <ConfigField title="actions.ngrok.oidc.user_info_refreshed" type="boolean">
      Returns true when ngrok updates the user information on the identity.
    </ConfigField>
  </ConfigChildren>
</ConfigField>
