# `oidcc_provider_configuration`
[🔗](https://github.com/erlef/oidcc/blob/aa212d52d0140addf057c34917b734647401b34e
/src/oidcc_provider_configuration.erl#L4)

Tooling to load and parse Openid Configuration.

## Records

To use the record, import the definition:

```erlang
-include_lib(["oidcc/include/oidcc_provider_configuration.hrl"]).
```

## Telemetry

See [`Oidcc.ProviderConfiguration`](`m:'Elixir.Oidcc.ProviderConfiguration'`).

# `document`
*since 3.9.0* 

```erlang
-type document() :: #{binary() => term()}.
```

Decoded JSON document as served by the provider.

This is the document the endpoint returned, before `oidcc` merges
`document_overrides` into it or coerces it into a record. Unlike a decoded
record it can be re-encoded losslessly, which is what makes it suitable for
persisting the provider's metadata.

# `error`
*since 3.0.0* 

```erlang
-type error() ::
          invalid_content_type |
          {issuer_mismatch, Issuer :: binary()} |
          {invalid_issuer, Issuer :: binary()} |
          {invalid_document, Document :: term()} |
          oidcc_decode_util:error() |
          oidcc_http_util:error().
```

# `jwks_document`
*since 3.9.0* 

```erlang
-type jwks_document() :: document() | [term()].
```

Decoded JWKS document as served by the provider.

RFC 7517 section 5 defines a JWK Set as a JSON object with a `keys` member, but
`jose_jwk:from/1` also accepts a bare array of keys and some providers serve
one, so both shapes reach the caller.

# `opts`
*since 3.0.0* 

```erlang
-type opts() ::
          #{fallback_expiry => timeout(),
            request_opts => oidcc_http_util:request_opts(),
            quirks => quirks()}.
```

Configure configuration loading / parsing.

## Parameters

* `fallback_expiry` - How long to keep configuration cached if the server doesn't specify expiry.
* `request_opts` - config for HTTP request.

# `quirks`
*since 3.1.0* 

```erlang
-type quirks() ::
          #{allow_unsafe_http => boolean(), document_overrides => map(), issuer_regex => binary()}.
```

Allow Specification Non-compliance.

## Exceptions

* `allow_unsafe_http` - Allow unsafe HTTP. Use this for development
  providers and **never in production**.
* `document_overrides` - a map to merge with the real OIDD document,
  in case the OP left out some values.
* `issuer_regex` - Optional regex pattern to match against the issuer claim
  instead of requiring an exact match. This may be necessary for certain providers that do not
  conform to the OpenID specification, such as Microsoft Entra ID where
  the issuer is 'https://login.microsoftonline.com/{tenantid}/v2.0' in the
  [OpenID configuration](https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration).

# `t`
*since 3.0.0* 

```erlang
-type t() ::
          #oidcc_provider_configuration{issuer :: uri_string:uri_string(),
                                        issuer_regex :: binary() | undefined,
                                        authorization_endpoint :: uri_string:uri_string(),
                                        token_endpoint :: uri_string:uri_string() | undefined,
                                        userinfo_endpoint :: uri_string:uri_string() | undefined,
                                        jwks_uri :: uri_string:uri_string() | undefined,
                                        registration_endpoint :: uri_string:uri_string() | undefined,
                                        scopes_supported :: [binary()] | undefined,
                                        response_types_supported :: [binary()],
                                        response_modes_supported :: [binary()],
                                        grant_types_supported :: [binary()],
                                        acr_values_supported :: [binary()] | undefined,
                                        subject_types_supported :: [pairwise | public],
                                        id_token_signing_alg_values_supported :: [binary()],
                                        id_token_encryption_alg_values_supported ::
                                            [binary()] | undefined,
                                        id_token_encryption_enc_values_supported ::
                                            [binary()] | undefined,
                                        userinfo_signing_alg_values_supported :: [binary()] | undefined,
                                        userinfo_encryption_alg_values_supported ::
                                            [binary()] | undefined,
                                        userinfo_encryption_enc_values_supported ::
                                            [binary()] | undefined,
                                        request_object_signing_alg_values_supported ::
                                            [binary()] | undefined,
                                        request_object_encryption_alg_values_supported ::
                                            [binary()] | undefined,
                                        request_object_encryption_enc_values_supported ::
                                            [binary()] | undefined,
                                        token_endpoint_auth_methods_supported :: [binary()],
                                        token_endpoint_auth_signing_alg_values_supported ::
                                            [binary()] | undefined,
                                        display_values_supported :: [binary()] | undefined,
                                        claim_types_supported :: [normal | aggregated | distributed],
                                        claims_supported :: [binary()] | undefined,
                                        service_documentation :: uri_string:uri_string() | undefined,
                                        claims_locales_supported :: [binary()] | undefined,
                                        ui_locales_supported :: [binary()] | undefined,
                                        claims_parameter_supported :: boolean(),
                                        request_parameter_supported :: boolean(),
                                        request_uri_parameter_supported :: boolean(),
                                        require_request_uri_registration :: boolean(),
                                        op_policy_uri :: uri_string:uri_string() | undefined,
                                        op_tos_uri :: uri_string:uri_string() | undefined,
                                        revocation_endpoint :: uri_string:uri_string() | undefined,
                                        revocation_endpoint_auth_methods_supported :: [binary()],
                                        revocation_endpoint_auth_signing_alg_values_supported ::
                                            [binary()] | undefined,
                                        introspection_endpoint :: uri_string:uri_string() | undefined,
                                        introspection_endpoint_auth_methods_supported :: [binary()],
                                        introspection_endpoint_auth_signing_alg_values_supported ::
                                            [binary()] | undefined,
                                        code_challenge_methods_supported :: [binary()] | undefined,
                                        end_session_endpoint :: uri_string:uri_string() | undefined,
                                        require_pushed_authorization_requests :: boolean(),
                                        pushed_authorization_request_endpoint ::
                                            uri_string:uri_string() | undefined,
                                        authorization_signing_alg_values_supported ::
                                            [binary()] | undefined,
                                        authorization_encryption_alg_values_supported ::
                                            [binary()] | undefined,
                                        authorization_encryption_enc_values_supported ::
                                            [binary()] | undefined,
                                        authorization_response_iss_parameter_supported :: boolean(),
                                        dpop_signing_alg_values_supported :: [binary()] | undefined,
                                        require_signed_request_object :: boolean(),
                                        mtls_endpoint_aliases :: #{binary() => uri_string:uri_string()},
                                        extra_fields :: #{binary() => term()},
                                        tls_client_certificate_bound_access_tokens :: boolean()}.
```

Record containing OpenID and OAuth 2.0 Configuration.

See:
* https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
* https://datatracker.ietf.org/doc/html/draft-jones-oauth-discovery-01#section-4.1
* https://openid.net/specs/openid-connect-rpinitiated-1_0.html#OPMetadata

All unrecognized fields are stored in `extra_fields`.

# `decode_configuration`
*since 3.0.0* 

```erlang
-spec decode_configuration(Configuration) -> {ok, t()} | {error, error()} when Configuration :: map().
```

See `decode_configuration/2`.

# `decode_configuration`
*since 3.1.0* 

```erlang
-spec decode_configuration(Configuration, Opts) -> {ok, t()} | {error, error()}
                              when Configuration :: map(), Opts :: opts().
```

Decode JSON into a `t:oidcc_provider_configuration:t/0` record.

## Examples

```erlang
{ok, {{"HTTP/1.1",200,"OK"}, _Headers, Body}} =
  httpc:request("https://accounts.google.com/.well-known/openid-configuration"),

{ok, DecodedJson} = your_json_lib:decode(Body),

{ok, #oidcc_provider_configuration{}} =
  oidcc_provider_configuration:decode_configuration(DecodedJson).
```

# `load_configuration`
*since 3.1.0* 

```erlang
-spec load_configuration(Issuer) ->
                            {ok, {Configuration :: t(), Expiry :: pos_integer()}} | {error, error()}
                            when Issuer :: uri_string:uri_string().
```

See `load_configuration/2`.

# `load_configuration`
*since 3.0.0* 

```erlang
-spec load_configuration(Issuer, Opts) ->
                            {ok, {Configuration :: t(), Expiry :: pos_integer()}} | {error, error()}
                            when Issuer :: uri_string:uri_string(), Opts :: opts().
```

Load OpenID Configuration into a `t:oidcc_provider_configuration:t/0` record.

## Examples

```erlang
{ok, #oidcc_provider_configuration{}} =
  oidcc_provider_configuration:load_configuration("https://accounts.google.com").
```

# `load_configuration_raw`
*since 3.9.0* 

```erlang
-spec load_configuration_raw(Issuer, Opts) ->
                                {ok,
                                 {Configuration :: t(), Expiry :: pos_integer(), Document :: document()}} |
                                {error, error()}
                                when Issuer :: uri_string:uri_string(), Opts :: opts().
```

Load OpenID Configuration, keeping the document the provider served.

Same as `load_configuration/2`, but additionally returns the decoded JSON
document. The record cannot be re-encoded losslessly - `extra_fields` holds only
the keys the decoder did not recognize, every other key is coerced into a typed
record field, and `issuer_regex` is not an OpenID Discovery field at all - so
callers that persist provider metadata need the document itself.

## Examples

```erlang
{ok, {#oidcc_provider_configuration{}, _Expiry, #{<<"issuer">> := Issuer}}} =
  oidcc_provider_configuration:load_configuration_raw(
    "https://accounts.google.com",
    #{}
  ).
```

# `load_jwks`
*since 3.0.0* 

```erlang
-spec load_jwks(JwksUri, Opts) ->
                   {ok, {Jwks :: jose_jwk:key(), Expiry :: pos_integer()}} | {error, term()}
                   when JwksUri :: uri_string:uri_string(), Opts :: opts().
```

Load JWKs into a `t:jose_jwk:key/0` record.

## Examples

```erlang
{ok, #jose_jwk{}} =
  oidcc_provider_configuration:load_jwks("https://www.googleapis.com/oauth2/v3/certs").
```

# `load_jwks_raw`
*since 3.9.0* 

```erlang
-spec load_jwks_raw(JwksUri, Opts) ->
                       {ok,
                        {Jwks :: jose_jwk:key(), Expiry :: pos_integer(), Document :: jwks_document()}} |
                       {error, error()}
                       when JwksUri :: uri_string:uri_string(), Opts :: opts().
```

Load JWKs, keeping the document the provider served.

Same as `load_jwks/2`, but additionally returns the decoded JSON document, for
callers that persist the key set rather than only using it.

## Examples

```erlang
{ok, {#jose_jwk{}, _Expiry, #{<<"keys">> := _Keys}}} =
  oidcc_provider_configuration:load_jwks_raw(
    "https://www.googleapis.com/oauth2/v3/certs",
    #{}
  ).
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
