<!--
This file was generated by Spark. Do not edit it by hand.
-->
# AshAuthentication.Strategy.DynamicOidc

Strategy for authenticating against arbitrary OpenID Connect providers
whose configuration lives in a database table rather than in your
application's compile-time DSL.

This is the building block for B2B/multi-tenant SSO patterns: each row in
your `OidcConnection` resource is one customer's IdP configuration
(`base_url`, `client_id`, `client_secret`, plus optional UI metadata).
At sign-in time the strategy queries the resource — typically scoped by
the current Ash tenant — and runs the standard OIDC flow against the
matched row.

## Setup

First, define a connection resource using
`AshAuthentication.OidcConnection`:

```elixir
defmodule MyApp.Accounts.OidcConnection do
  use Ash.Resource,
    data_layer: AshPostgres.DataLayer,
    extensions: [AshAuthentication.OidcConnection],
    domain: MyApp.Accounts

  oidc_connection do
    domain MyApp.Accounts
  end

  postgres do
    table "oidc_connections"
    repo MyApp.Repo
  end
end
```

Then add the strategy to your user resource:

```elixir
authentication do
  strategies do
    dynamic_oidc :sso do
      connection_resource MyApp.Accounts.OidcConnection
      identity_resource MyApp.Accounts.UserIdentity
      redirect_uri MyApp.Secrets
    end
  end
end
```

## URL shape

The strategy generates two routes:

  - `GET /<subject>/<strategy_name>/:connection_id/request` — initiate
    sign-in for a specific connection (the user/UI is responsible for
    knowing which connection_id to send to).
  - `GET /<subject>/<strategy_name>/callback` — single, shared callback
    URL. Each customer's IdP admin only ever needs to register *this*
    URL as their redirect URI. The connection_id is remembered between
    request and callback via the user's session.

## Tenant context

If your connection resource is multitenant, the strategy will scope the
lookup using the tenant set on the conn (`Ash.PlugHelpers.set_tenant/2`).
Set the tenant **upstream** of the auth router — typically in a Phoenix
plug that maps subdomain or header to your tenant. If no tenant is set
and the resource is multitenant, the lookup will fail.

Non-multitenant connection resources are also supported — the strategy
simply queries globally.

## More documentation

- `AshAuthentication.OidcConnection` — the resource extension this
  strategy depends on.
- `AshAuthentication.Strategy.Oidc` — the underlying compile-time OIDC
  strategy. The runtime behaviour is identical aside from where the
  config comes from.



### authentication.strategies.dynamic_oidc
```elixir
dynamic_oidc name \\ :dynamic_oidc
```


An OpenID Connect strategy whose connection details (`base_url`,
`client_id`, `client_secret`) are loaded at request time from a
database resource extended with `AshAuthentication.OidcConnection`.

This is the building block for data-driven multi-tenant SSO: each row
in the connection resource is one customer's IdP configuration, and
the strategy looks up the right row based on the request path
(`:connection_id` segment) plus the current Ash tenant.

###### More documentation:
- `AshAuthentication.OidcConnection` — the resource extension this strategy depends on
- `AshAuthentication.Strategy.Oidc` — the underlying compile-time OIDC strategy






### Arguments

| Name | Type | Default | Docs |
|------|------|---------|------|
| [`name`](#authentication-strategies-dynamic_oidc-name){: #authentication-strategies-dynamic_oidc-name .spark-required} | `atom` |  | Uniquely identifies the strategy. |
### Options

| Name | Type | Default | Docs |
|------|------|---------|------|
| [`redirect_uri`](#authentication-strategies-dynamic_oidc-redirect_uri){: #authentication-strategies-dynamic_oidc-redirect_uri .spark-required} | `(any, any -> any) \| module \| String.t` |  | The callback URI *base*. Not the whole URI back to the callback endpoint, but the URI to your `AuthPlug`. Takes either a module which implements the `AshAuthentication.Secret` behaviour, a 2 arity anonymous function or a string. |
| [`connection_resource`](#authentication-strategies-dynamic_oidc-connection_resource){: #authentication-strategies-dynamic_oidc-connection_resource .spark-required} | `module` |  | The Ash resource (extended with `AshAuthentication.OidcConnection`) that stores per-tenant OIDC client configuration. |
| [`site`](#authentication-strategies-dynamic_oidc-site){: #authentication-strategies-dynamic_oidc-site } | `(any, any -> any) \| module \| String.t` |  | Deprecated: Use `base_url` instead. |
| [`prevent_hijacking?`](#authentication-strategies-dynamic_oidc-prevent_hijacking?){: #authentication-strategies-dynamic_oidc-prevent_hijacking? } | `boolean` | `true` | Requires a confirmation add_on to be present if the password strategy is used with the same identity_field. |
| [`auth_method`](#authentication-strategies-dynamic_oidc-auth_method){: #authentication-strategies-dynamic_oidc-auth_method } | `nil \| :client_secret_basic \| :client_secret_post \| :client_secret_jwt \| :private_key_jwt` | `:client_secret_post` | The authentication strategy used, optional. If not set, no authentication will be used during the access token request. |
| [`trusted_audiences`](#authentication-strategies-dynamic_oidc-trusted_audiences){: #authentication-strategies-dynamic_oidc-trusted_audiences } | `(any, any -> any) \| module \| list(any) \| nil` |  | A list of audiences which are trusted. Takes either a module which implements the `AshAuthentication.Secret` behaviour, a 2 arity anonymous function or a string. |
| [`code_verifier`](#authentication-strategies-dynamic_oidc-code_verifier){: #authentication-strategies-dynamic_oidc-code_verifier } | `boolean` | `false` | Boolean to generate and use a random 128 byte long url safe code verifier for PKCE flow, optional, defaults to false. When set to true the session params will contain :code_verifier, :code_challenge, and :code_challenge_method params |
| [`registration_enabled?`](#authentication-strategies-dynamic_oidc-registration_enabled?){: #authentication-strategies-dynamic_oidc-registration_enabled? } | `boolean` | `true` | If enabled, new users will be able to register for your site when authenticating and not already present. If not, only existing users will be able to authenticate. |
| [`register_action_name`](#authentication-strategies-dynamic_oidc-register_action_name){: #authentication-strategies-dynamic_oidc-register_action_name } | `atom` |  | The name of the action to use to register a user, if `registration_enabled?` is `true`. Defaults to `register_with_<name>` See the "Registration and Sign-in" section of the strategy docs for more. |
| [`sign_in_action_name`](#authentication-strategies-dynamic_oidc-sign_in_action_name){: #authentication-strategies-dynamic_oidc-sign_in_action_name } | `atom` |  | The name of the action to use to sign in an existing user, if `sign_in_enabled?` is `true`. Defaults to `sign_in_with_<strategy>`, which is generated for you by default. See the "Registration and Sign-in" section of the strategy docs for more information. |
| [`identity_resource`](#authentication-strategies-dynamic_oidc-identity_resource){: #authentication-strategies-dynamic_oidc-identity_resource } | `module \| false` | `false` | The resource used to store user identities, or `false` to disable. See the User Identities section of the strategy docs for more. |
| [`identity_relationship_name`](#authentication-strategies-dynamic_oidc-identity_relationship_name){: #authentication-strategies-dynamic_oidc-identity_relationship_name } | `atom` | `:identities` | Name of the relationship to the provider identities resource |
| [`identity_relationship_user_id_attribute`](#authentication-strategies-dynamic_oidc-identity_relationship_user_id_attribute){: #authentication-strategies-dynamic_oidc-identity_relationship_user_id_attribute } | `atom` | `:user_id` | The name of the destination (user_id) attribute on your provider identity resource. Only necessary if you've changed the `user_id_attribute_name` option of the provider identity. |
| [`openid_configuration_uri`](#authentication-strategies-dynamic_oidc-openid_configuration_uri){: #authentication-strategies-dynamic_oidc-openid_configuration_uri } | `(any, any -> any) \| module \| String.t` | `"/.well-known/openid-configuration"` | The URI for the OpenID provider |
| [`client_authentication_method`](#authentication-strategies-dynamic_oidc-client_authentication_method){: #authentication-strategies-dynamic_oidc-client_authentication_method } | `"client_secret_basic" \| "client_secret_post" \| "client_secret_jwt" \| "private_key_jwt" \| "none"` | `"client_secret_basic"` | The client authentication method to use. |
| [`openid_configuration`](#authentication-strategies-dynamic_oidc-openid_configuration){: #authentication-strategies-dynamic_oidc-openid_configuration } | `nil \| %{optional(String.t) => any}` |  | The OpenID configuration.  If not set, the configuration will be retrieved from `openid_configuration_uri`. |
| [`id_token_signed_response_alg`](#authentication-strategies-dynamic_oidc-id_token_signed_response_alg){: #authentication-strategies-dynamic_oidc-id_token_signed_response_alg } | `"HS256" \| "HS384" \| "HS512" \| "RS256" \| "RS384" \| "RS512" \| "ES256" \| "ES384" \| "ES512" \| "PS256" \| "PS384" \| "PS512" \| "Ed25519" \| "Ed25519ph" \| "Ed448" \| "Ed448ph" \| "EdDSA"` | `"RS256"` | The `id_token_signed_response_alg` parameter sent by the Client during Registration. |
| [`id_token_ttl_seconds`](#authentication-strategies-dynamic_oidc-id_token_ttl_seconds){: #authentication-strategies-dynamic_oidc-id_token_ttl_seconds } | `nil \| pos_integer` |  | The number of seconds from `iat` that an ID Token will be considered valid. |
| [`nonce`](#authentication-strategies-dynamic_oidc-nonce){: #authentication-strategies-dynamic_oidc-nonce } | `boolean \| (any, any -> any) \| module \| String.t` | `true` | A function for generating the session nonce, `true` to automatically generate it with `AshAuthentication.Strategy.Oidc.NonceGenerator`, or `false` to disable. |
| [`authorization_params`](#authentication-strategies-dynamic_oidc-authorization_params){: #authentication-strategies-dynamic_oidc-authorization_params } | `(any, any -> any) \| module \| keyword \| nil` | `[scope: "profile email"]` | Any additional parameters to encode in the request phase. eg: `authorization_params scope: "openid profile email"` |





### Introspection

Target: `AshAuthentication.Strategy.DynamicOidc`



<style type="text/css">.spark-required::after { content: "*"; color: red !important; }</style>
