From bff21278ccc749b9e9f4fe7170c84a5a72855da7 Mon Sep 17 00:00:00 2001 From: cgmEdi <156078871+cgmEdi@users.noreply.github.com> Date: Wed, 16 Jul 2025 22:32:20 +0200 Subject: [PATCH 1/9] feat(openid-connect): add encoded id token to downstream --- apisix/plugins/openid-connect.lua | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/apisix/plugins/openid-connect.lua b/apisix/plugins/openid-connect.lua index 6c94ea5d6d56..b07db15007b5 100644 --- a/apisix/plugins/openid-connect.lua +++ b/apisix/plugins/openid-connect.lua @@ -176,6 +176,12 @@ local schema = { type = "boolean", default = true }, + set_id_token_encoded_header = { + description = "Whether the encoded ID token should be added in the X-ID-Token-Encoded header to " .. + "the request for downstream.", + type = "boolean", + default = true + }, set_userinfo_header = { description = "Whether the user info token should be added in the X-Userinfo " .. "header to the request for downstream.", @@ -696,6 +702,11 @@ function _M.rewrite(plugin_conf, ctx) core.request.set_header(ctx, "X-ID-Token", ngx.encode_base64(token)) end + -- Add X-ID-Token-Encoded header, maybe. + if session.data.id_token_enc and conf.set_id_token_encoded_header then + core.request.set_header(ctx, "X-ID-Token-Encoded", session.data.id_token_enc) + end + -- Add X-Userinfo header, maybe. if response.user and conf.set_userinfo_header then core.request.set_header(ctx, "X-Userinfo", From 4e8a108f3850d2f5f27c78fc38170cc1258b9ad1 Mon Sep 17 00:00:00 2001 From: cgmEdi <156078871+cgmEdi@users.noreply.github.com> Date: Thu, 17 Jul 2025 00:30:45 +0200 Subject: [PATCH 2/9] fix: add original id_token if configured and available --- apisix/plugins/openid-connect.lua | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/apisix/plugins/openid-connect.lua b/apisix/plugins/openid-connect.lua index b07db15007b5..7edcea573b35 100644 --- a/apisix/plugins/openid-connect.lua +++ b/apisix/plugins/openid-connect.lua @@ -176,8 +176,8 @@ local schema = { type = "boolean", default = true }, - set_id_token_encoded_header = { - description = "Whether the encoded ID token should be added in the X-ID-Token-Encoded header to " .. + set_original_id_token_header = { + description = "Whether the ID token should be added in the X-ID-Token-Original header to " .. "the request for downstream.", type = "boolean", default = true @@ -697,14 +697,9 @@ function _M.rewrite(plugin_conf, ctx) add_access_token_header(ctx, conf, response.access_token) -- Add X-ID-Token header, maybe. - if response.id_token and conf.set_id_token_header then - local token = core.json.encode(response.id_token) - core.request.set_header(ctx, "X-ID-Token", ngx.encode_base64(token)) - end - - -- Add X-ID-Token-Encoded header, maybe. - if session.data.id_token_enc and conf.set_id_token_encoded_header then - core.request.set_header(ctx, "X-ID-Token-Encoded", session.data.id_token_enc) + if session and session.data and session.data.enc_id_token and conf.set_original_id_token_header then + local token = session.data.enc_id_token + core.request.set_header(ctx, "X-ID-Token-Original", token) end -- Add X-Userinfo header, maybe. From b5a7f0a6c51edd532baf7b2af730f30547873be4 Mon Sep 17 00:00:00 2001 From: Eduard Schleining Date: Thu, 17 Jul 2025 09:11:16 +0200 Subject: [PATCH 3/9] fix: include original id token in headers test --- t/plugin/openid-connect.t | 2 ++ 1 file changed, 2 insertions(+) diff --git a/t/plugin/openid-connect.t b/t/plugin/openid-connect.t index 54fdc8097e63..71deb03c6690 100644 --- a/t/plugin/openid-connect.t +++ b/t/plugin/openid-connect.t @@ -203,6 +203,7 @@ true "introspection_endpoint": "http://127.0.0.1:8080/realms/University/protocol/openid-connect/token/introspect", "set_access_token_header": true, "access_token_in_authorization_header": false, + "set_id_token_original_header": true, "set_id_token_header": true, "set_userinfo_header": true, "set_refresh_token_header": true @@ -281,6 +282,7 @@ host: 127.0.0.1:1984 user-agent: .* x-access-token: ey.* x-id-token: ey.* +x-id-token-original: ey.*\..*\..* x-real-ip: 127.0.0.1 x-refresh-token: ey.* x-userinfo: ey.* From 35552ac11f0d24aa59556fe65ba19447facdc370 Mon Sep 17 00:00:00 2001 From: Eduard Schleining Date: Thu, 17 Jul 2025 09:17:12 +0200 Subject: [PATCH 4/9] fix: include original id token in headers test --- t/plugin/openid-connect.t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/plugin/openid-connect.t b/t/plugin/openid-connect.t index 71deb03c6690..09aed7b475c9 100644 --- a/t/plugin/openid-connect.t +++ b/t/plugin/openid-connect.t @@ -919,7 +919,7 @@ OIDC introspection failed: invalid token } } --- response_body -{"accept_none_alg":false,"accept_unsupported_alg":true,"access_token_expires_leeway":0,"access_token_in_authorization_header":false,"bearer_only":false,"client_id":"kbyuFDidLLm280LIwVFiazOqjO3ty8KH","client_jwt_assertion_expires_in":60,"client_secret":"60Op4HFM0I8ajz0WdiStAbziZ-VFQttXuxixHHs2R7r7-CW8GR79l-mmLqMhc-Sa","discovery":"http://127.0.0.1:1980/.well-known/openid-configuration","force_reauthorize":false,"iat_slack":120,"introspection_endpoint_auth_method":"client_secret_basic","introspection_interval":0,"jwk_expires_in":86400,"jwt_verification_cache_ignore":false,"logout_path":"/logout","realm":"apisix","renew_access_token_on_expiry":true,"revoke_tokens_on_logout":false,"scope":"openid","set_access_token_header":true,"set_id_token_header":true,"set_refresh_token_header":false,"set_userinfo_header":true,"ssl_verify":false,"timeout":3,"token_endpoint_auth_method":"client_secret_basic","unauth_action":"auth","use_nonce":false,"use_pkce":false} +{"accept_none_alg":false,"accept_unsupported_alg":true,"access_token_expires_leeway":0,"access_token_in_authorization_header":false,"bearer_only":false,"client_id":"kbyuFDidLLm280LIwVFiazOqjO3ty8KH","client_jwt_assertion_expires_in":60,"client_secret":"60Op4HFM0I8ajz0WdiStAbziZ-VFQttXuxixHHs2R7r7-CW8GR79l-mmLqMhc-Sa","discovery":"http://127.0.0.1:1980/.well-known/openid-configuration","force_reauthorize":false,"iat_slack":120,"introspection_endpoint_auth_method":"client_secret_basic","introspection_interval":0,"jwk_expires_in":86400,"jwt_verification_cache_ignore":false,"logout_path":"/logout","realm":"apisix","renew_access_token_on_expiry":true,"revoke_tokens_on_logout":false,"scope":"openid","set_access_token_header":true,"set_id_token_header":true,"set_original_id_token_header":true,"set_refresh_token_header":false,"set_userinfo_header":true,"ssl_verify":false,"timeout":3,"token_endpoint_auth_method":"client_secret_basic","unauth_action":"auth","use_nonce":false,"use_pkce":false} From 8533b919ade718834a089e1a62bb9772674eade1 Mon Sep 17 00:00:00 2001 From: Eduard Schleining Date: Thu, 17 Jul 2025 09:29:24 +0200 Subject: [PATCH 5/9] fix: re add id_token --- apisix/plugins/openid-connect.lua | 10 ++++++++-- t/plugin/openid-connect.t | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/apisix/plugins/openid-connect.lua b/apisix/plugins/openid-connect.lua index 7edcea573b35..2c473fc114c6 100644 --- a/apisix/plugins/openid-connect.lua +++ b/apisix/plugins/openid-connect.lua @@ -176,7 +176,7 @@ local schema = { type = "boolean", default = true }, - set_original_id_token_header = { + set_id_token_original_header = { description = "Whether the ID token should be added in the X-ID-Token-Original header to " .. "the request for downstream.", type = "boolean", @@ -697,7 +697,13 @@ function _M.rewrite(plugin_conf, ctx) add_access_token_header(ctx, conf, response.access_token) -- Add X-ID-Token header, maybe. - if session and session.data and session.data.enc_id_token and conf.set_original_id_token_header then + if response.id_token and conf.set_id_token_header then + local token = core.json.encode(response.id_token) + core.request.set_header(ctx, "X-ID-Token", ngx.encode_base64(token)) + end + + -- Add X-ID-Token-Original header, maybe. + if session and session.data and session.data.enc_id_token and conf.set_id_token_original_header then local token = session.data.enc_id_token core.request.set_header(ctx, "X-ID-Token-Original", token) end diff --git a/t/plugin/openid-connect.t b/t/plugin/openid-connect.t index 09aed7b475c9..2fd93fe30320 100644 --- a/t/plugin/openid-connect.t +++ b/t/plugin/openid-connect.t @@ -919,7 +919,7 @@ OIDC introspection failed: invalid token } } --- response_body -{"accept_none_alg":false,"accept_unsupported_alg":true,"access_token_expires_leeway":0,"access_token_in_authorization_header":false,"bearer_only":false,"client_id":"kbyuFDidLLm280LIwVFiazOqjO3ty8KH","client_jwt_assertion_expires_in":60,"client_secret":"60Op4HFM0I8ajz0WdiStAbziZ-VFQttXuxixHHs2R7r7-CW8GR79l-mmLqMhc-Sa","discovery":"http://127.0.0.1:1980/.well-known/openid-configuration","force_reauthorize":false,"iat_slack":120,"introspection_endpoint_auth_method":"client_secret_basic","introspection_interval":0,"jwk_expires_in":86400,"jwt_verification_cache_ignore":false,"logout_path":"/logout","realm":"apisix","renew_access_token_on_expiry":true,"revoke_tokens_on_logout":false,"scope":"openid","set_access_token_header":true,"set_id_token_header":true,"set_original_id_token_header":true,"set_refresh_token_header":false,"set_userinfo_header":true,"ssl_verify":false,"timeout":3,"token_endpoint_auth_method":"client_secret_basic","unauth_action":"auth","use_nonce":false,"use_pkce":false} +{"accept_none_alg":false,"accept_unsupported_alg":true,"access_token_expires_leeway":0,"access_token_in_authorization_header":false,"bearer_only":false,"client_id":"kbyuFDidLLm280LIwVFiazOqjO3ty8KH","client_jwt_assertion_expires_in":60,"client_secret":"60Op4HFM0I8ajz0WdiStAbziZ-VFQttXuxixHHs2R7r7-CW8GR79l-mmLqMhc-Sa","discovery":"http://127.0.0.1:1980/.well-known/openid-configuration","force_reauthorize":false,"iat_slack":120,"introspection_endpoint_auth_method":"client_secret_basic","introspection_interval":0,"jwk_expires_in":86400,"jwt_verification_cache_ignore":false,"logout_path":"/logout","realm":"apisix","renew_access_token_on_expiry":true,"revoke_tokens_on_logout":false,"scope":"openid","set_access_token_header":true,"set_id_token_header":true,"set_id_token_original_header":true,"set_refresh_token_header":false,"set_userinfo_header":true,"ssl_verify":false,"timeout":3,"token_endpoint_auth_method":"client_secret_basic","unauth_action":"auth","use_nonce":false,"use_pkce":false} From 58b8ceb9539bb7acfd930579fc12f5282fc5ac96 Mon Sep 17 00:00:00 2001 From: Eduard Schleining Date: Thu, 17 Jul 2025 09:34:00 +0200 Subject: [PATCH 6/9] doc: add documentation --- docs/en/latest/plugins/openid-connect.md | 127 ++++++++++++----------- 1 file changed, 64 insertions(+), 63 deletions(-) diff --git a/docs/en/latest/plugins/openid-connect.md b/docs/en/latest/plugins/openid-connect.md index 6d5b7b71f300..63f9d030e6be 100644 --- a/docs/en/latest/plugins/openid-connect.md +++ b/docs/en/latest/plugins/openid-connect.md @@ -37,69 +37,70 @@ The `openid-connect` Plugin supports the integration with [OpenID Connect (OIDC) ## Attributes -| Name | Type | Required | Default | Valid values | Description | -|--------------------------------------|----------|----------|-----------------------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| client_id | string | True | | | OAuth client ID. | -| client_secret | string | True | | | OAuth client secret. | -| discovery | string | True | | | URL to the well-known discovery document of the OpenID provider, which contains a list of OP API endpoints. The Plugin can directly utilize the endpoints from the discovery document. You can also configure these endpoints individually, which takes precedence over the endpoints supplied in the discovery document. | -| scope | string | False | openid | | OIDC scope that corresponds to information that should be returned about the authenticated user, also known as [claims](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims). This is used to authorize users with proper permission. The default value is `openid`, the required scope for OIDC to return a `sub` claim that uniquely identifies the authenticated user. Additional scopes can be appended and delimited by spaces, such as `openid email profile`. | -| required_scopes | array[string] | False | | | Scopes required to be present in the access token. Used in conjunction with the introspection endpoint when `bearer_only` is `true`. If any required scope is missing, the Plugin rejects the request with a 403 forbidden error. | -| realm | string | False | apisix | | Realm in [`WWW-Authenticate`](https://www.rfc-editor.org/rfc/rfc6750#section-3) response header accompanying a 401 unauthorized request due to invalid bearer token. | -| bearer_only | boolean | False | false | | If true, strictly require bearer access token in requests for authentication. | -| logout_path | string | False | /logout | | Path to activate the logout. | -| post_logout_redirect_uri | string | False | | | URL to redirect users to after the `logout_path` receive a request to log out. | -| redirect_uri | string | False | | | URI to redirect to after authentication with the OpenID provider. Note that the redirect URI should not be the same as the request URI, but a sub-path of the request URI. For example, if the `uri` of the Route is `/api/v1/*`, `redirect_uri` can be configured as `/api/v1/redirect`. If `redirect_uri` is not configured, APISIX will append `/.apisix/redirect` to the request URI to determine the value for `redirect_uri`. | -| timeout | integer | False | 3 | [1,...] | Request timeout time in seconds. | -| ssl_verify | boolean | False | false | | If true, verify the OpenID provider 's SSL certificates. | -| introspection_endpoint | string | False | | | URL of the [token introspection](https://datatracker.ietf.org/doc/html/rfc7662) endpoint for the OpenID provider used to introspect access tokens. If this is unset, the introspection endpoint presented in the well-known discovery document is used [as a fallback](https://github.com/zmartzone/lua-resty-openidc/commit/cdaf824996d2b499de4c72852c91733872137c9c). | -| introspection_endpoint_auth_method | string | False | client_secret_basic | | Authentication method for the token introspection endpoint. The value should be one of the authentication methods specified in the `introspection_endpoint_auth_methods_supported` [authorization server metadata](https://www.rfc-editor.org/rfc/rfc8414.html) as seen in the well-known discovery document, such as `client_secret_basic`, `client_secret_post`, `private_key_jwt`, and `client_secret_jwt`. | -| token_endpoint_auth_method | string | False | client_secret_basic | | Authentication method for the token endpoint. The value should be one of the authentication methods specified in the `token_endpoint_auth_methods_supported` [authorization server metadata](https://www.rfc-editor.org/rfc/rfc8414.html) as seen in the well-known discovery document, such as `client_secret_basic`, `client_secret_post`, `private_key_jwt`, and `client_secret_jwt`. If the configured method is not supported, fall back to the first method in the `token_endpoint_auth_methods_supported` array. | -| public_key | string | False | | | Public key used to verify JWT signature id asymmetric algorithm is used. Providing this value to perform token verification will skip token introspection in client credentials flow. You can pass the public key in `-----BEGIN PUBLIC KEY-----\\n……\\n-----END PUBLIC KEY-----` format. | -| use_jwks | boolean | False | false | | If true and if `public_key` is not set, use the JWKS to verify JWT signature and skip token introspection in client credentials flow. The JWKS endpoint is parsed from the discovery document. | -| use_pkce | boolean | False | false | | If true, use the Proof Key for Code Exchange (PKCE) for Authorization Code Flow as defined in [RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636). | -| token_signing_alg_values_expected | string | False | | | Algorithm used for signing JWT, such as `RS256`. | -| set_access_token_header | boolean | False | true | | If true, set the access token in a request header. By default, the `X-Access-Token` header is used. | -| access_token_in_authorization_header | boolean | False | false | | If true and if `set_access_token_header` is also true, set the access token in the `Authorization` header. | -| set_id_token_header | boolean | False | true | | If true and if the ID token is available, set the value in the `X-ID-Token` request header. | -| set_userinfo_header | boolean | False | true | | If true and if user info data is available, set the value in the `X-Userinfo` request header. | -| set_refresh_token_header | boolean | False | false | | If true and if the refresh token is available, set the value in the `X-Refresh-Token` request header. | -| session | object | False | | | Session configuration used when `bearer_only` is `false` and the Plugin uses Authorization Code flow. | -| session.secret | string | True | | 16 or more characters | Key used for session encryption and HMAC operation when `bearer_only` is `false`. It is automatically generated and saved to etcd if not configured. When using APISIX in the standalone mode where etcd is no longer the configuration center, the `secret` should be configured. | -| session.cookie | object | False | | | Cookie configurations. | -| session.cookie.lifetime | integer | False | 3600 | | Cookie lifetime in seconds. | -| session_contents | object | False | | | Session content configurations. If unconfigured, all data will be stored in the session. | -| session_contents.access_token | boolean | False | | | If true, store the access token in the session. | -| session_contents.id_token | boolean | False | | | If true, store the ID token in the session. | -| session_contents.enc_id_token | boolean | False | | | If true, store the encrypted ID token in the session. | -| session_contents.user | boolean | False | | | If true, store the user info in the session. | -| unauth_action | string | False | auth | ["auth","deny","pass"] | Action for unauthenticated requests. When set to `auth`, redirect to the authentication endpoint of the OpenID provider. When set to `pass`, allow the request without authentication. When set to `deny`, return 401 unauthenticated responses rather than start the authorization code grant flow. | -| proxy_opts | object | False | | | Configurations for the proxy server that the OpenID provider is behind. | -| proxy_opts.http_proxy | string | False | | | Proxy server address for HTTP requests, such as `http://:`. | -| proxy_opts.https_proxy | string | False | | | Proxy server address for HTTPS requests, such as `http://:`. | -| proxy_opts.http_proxy_authorization | string | False | | Basic [base64 username:password] | Default `Proxy-Authorization` header value to be used with `http_proxy`. Can be overridden with custom `Proxy-Authorization` request header. | -| proxy_opts.https_proxy_authorization | string | False | | Basic [base64 username:password] | Default `Proxy-Authorization` header value to be used with `https_proxy`. Cannot be overridden with custom `Proxy-Authorization` request header since with HTTPS, the authorization is completed when connecting. | -| proxy_opts.no_proxy | string | False | | | Comma separated list of hosts that should not be proxied. | -| authorization_params | object | False | | | Additional parameters to send in the request to the authorization endpoint. | -| client_rsa_private_key | string | False | | | Client RSA private key used to sign JWT for authentication to the OP. Required when `token_endpoint_auth_method` is `private_key_jwt`. | -| client_rsa_private_key_id | string | False | | | Client RSA private key ID used to compute a signed JWT. Optional when `token_endpoint_auth_method` is `private_key_jwt`. | -| client_jwt_assertion_expires_in | integer | False | 60 | | Life duration of the signed JWT for authentication to the OP, in seconds. Used when `token_endpoint_auth_method` is `private_key_jwt` or `client_secret_jwt`. | -| renew_access_token_on_expiry | boolean | False | true | | If true, attempt to silently renew the access token when it expires or if a refresh token is available. If the token fails to renew, redirect user for re-authentication. | -| access_token_expires_in | integer | False | | | Lifetime of the access token in seconds if no `expires_in` attribute is present in the token endpoint response. | -| refresh_session_interval | integer | False | | | Time interval to refresh user ID token without requiring re-authentication. When not set, it will not check the expiration time of the session issued to the client by the gateway. If set to 900, it means refreshing the user's id_token (or session in the browser) after 900 seconds without requiring re-authentication. | -| iat_slack | integer | False | 120 | | Tolerance of clock skew in seconds with the `iat` claim in an ID token. | -| accept_none_alg | boolean | False | false | | Set to true if the OpenID provider does not sign its ID token, such as when the signature algorithm is set to `none`. | -| accept_unsupported_alg | boolean | False | true | | If true, ignore ID token signature to accept unsupported signature algorithm. | -| access_token_expires_leeway | integer | False | 0 | | Expiration leeway in seconds for access token renewal. When set to a value greater than 0, token renewal will take place the set amount of time before token expiration. This avoids errors in case the access token just expires when arriving to the resource server. | -| force_reauthorize | boolean | False | false | | If true, execute the authorization flow even when a token has been cached. | -| use_nonce | boolean | False | false | | If true, enable nonce parameter in authorization request. | -| revoke_tokens_on_logout | boolean | False | false | | If true, notify the authorization server a previously obtained refresh or access token is no longer needed at the revocation endpoint. | -| jwk_expires_in | integer | False | 86400 | | Expiration time for JWK cache in seconds. | -| jwt_verification_cache_ignore | boolean | False | false | | If true, force re-verification for a bearer token and ignore any existing cached verification results. | -| cache_segment | string | False | | | Optional name of a cache segment, used to separate and differentiate caches used by token introspection or JWT verification. | -| introspection_interval | integer | False | 0 | | TTL of the cached and introspected access token in seconds. The default value is 0, which means this option is not used and the Plugin defaults to use the TTL passed by expiry claim defined in `introspection_expiry_claim`. If `introspection_interval` is larger than 0 and less than the TTL passed by expiry claim defined in `introspection_expiry_claim`, use `introspection_interval`. | -| introspection_expiry_claim | string | False | exp | | Name of the expiry claim, which controls the TTL of the cached and introspected access token. | -| introspection_addon_headers | array[string] | False | | | Used to append additional header values to the introspection HTTP request. If the specified header does not exist in origin request, value will not be appended. | -| claim_validator.issuer.valid_issuers | string[] | False | | | Whitelist the vetted issuers of the jwt. When not passed by the user, the issuer returned by discovery endpoint will be used. In case both are missing, the issuer will not be validated. | +| Name | Type | Required | Default | Valid values | Description | +|--------------------------------------|----------|----------|-----------------------|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| client_id | string | True | | | OAuth client ID. | +| client_secret | string | True | | | OAuth client secret. | +| discovery | string | True | | | URL to the well-known discovery document of the OpenID provider, which contains a list of OP API endpoints. The Plugin can directly utilize the endpoints from the discovery document. You can also configure these endpoints individually, which takes precedence over the endpoints supplied in the discovery document. | +| scope | string | False | openid | | OIDC scope that corresponds to information that should be returned about the authenticated user, also known as [claims](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims). This is used to authorize users with proper permission. The default value is `openid`, the required scope for OIDC to return a `sub` claim that uniquely identifies the authenticated user. Additional scopes can be appended and delimited by spaces, such as `openid email profile`. | +| required_scopes | array[string] | False | | | Scopes required to be present in the access token. Used in conjunction with the introspection endpoint when `bearer_only` is `true`. If any required scope is missing, the Plugin rejects the request with a 403 forbidden error. | +| realm | string | False | apisix | | Realm in [`WWW-Authenticate`](https://www.rfc-editor.org/rfc/rfc6750#section-3) response header accompanying a 401 unauthorized request due to invalid bearer token. | +| bearer_only | boolean | False | false | | If true, strictly require bearer access token in requests for authentication. | +| logout_path | string | False | /logout | | Path to activate the logout. | +| post_logout_redirect_uri | string | False | | | URL to redirect users to after the `logout_path` receive a request to log out. | +| redirect_uri | string | False | | | URI to redirect to after authentication with the OpenID provider. Note that the redirect URI should not be the same as the request URI, but a sub-path of the request URI. For example, if the `uri` of the Route is `/api/v1/*`, `redirect_uri` can be configured as `/api/v1/redirect`. If `redirect_uri` is not configured, APISIX will append `/.apisix/redirect` to the request URI to determine the value for `redirect_uri`. | +| timeout | integer | False | 3 | [1,...] | Request timeout time in seconds. | +| ssl_verify | boolean | False | false | | If true, verify the OpenID provider 's SSL certificates. | +| introspection_endpoint | string | False | | | URL of the [token introspection](https://datatracker.ietf.org/doc/html/rfc7662) endpoint for the OpenID provider used to introspect access tokens. If this is unset, the introspection endpoint presented in the well-known discovery document is used [as a fallback](https://github.com/zmartzone/lua-resty-openidc/commit/cdaf824996d2b499de4c72852c91733872137c9c). | +| introspection_endpoint_auth_method | string | False | client_secret_basic | | Authentication method for the token introspection endpoint. The value should be one of the authentication methods specified in the `introspection_endpoint_auth_methods_supported` [authorization server metadata](https://www.rfc-editor.org/rfc/rfc8414.html) as seen in the well-known discovery document, such as `client_secret_basic`, `client_secret_post`, `private_key_jwt`, and `client_secret_jwt`. | +| token_endpoint_auth_method | string | False | client_secret_basic | | Authentication method for the token endpoint. The value should be one of the authentication methods specified in the `token_endpoint_auth_methods_supported` [authorization server metadata](https://www.rfc-editor.org/rfc/rfc8414.html) as seen in the well-known discovery document, such as `client_secret_basic`, `client_secret_post`, `private_key_jwt`, and `client_secret_jwt`. If the configured method is not supported, fall back to the first method in the `token_endpoint_auth_methods_supported` array. | +| public_key | string | False | | | Public key used to verify JWT signature id asymmetric algorithm is used. Providing this value to perform token verification will skip token introspection in client credentials flow. You can pass the public key in `-----BEGIN PUBLIC KEY-----\\n……\\n-----END PUBLIC KEY-----` format. | +| use_jwks | boolean | False | false | | If true and if `public_key` is not set, use the JWKS to verify JWT signature and skip token introspection in client credentials flow. The JWKS endpoint is parsed from the discovery document. | +| use_pkce | boolean | False | false | | If true, use the Proof Key for Code Exchange (PKCE) for Authorization Code Flow as defined in [RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636). | +| token_signing_alg_values_expected | string | False | | | Algorithm used for signing JWT, such as `RS256`. | +| set_access_token_header | boolean | False | true | | If true, set the access token in a request header. By default, the `X-Access-Token` header is used. | +| access_token_in_authorization_header | boolean | False | false | | If true and if `set_access_token_header` is also true, set the access token in the `Authorization` header. | +| set_id_token_header | boolean | False | true | | If true and if the ID token is available, set the value in the `X-ID-Token` request header. | +| set_id_token_original_header | boolean | False | true | | If true and if the ID token is available, set the value in the `X-ID-Token-Original` request header. In contrast to the `X-ID-TOKEN` header, this header will keep the original JWT encoding (including JWT headers and JWS signature). | +| set_userinfo_header | boolean | False | true | | If true and if user info data is available, set the value in the `X-Userinfo` request header. | +| set_refresh_token_header | boolean | False | false | | If true and if the refresh token is available, set the value in the `X-Refresh-Token` request header. | +| session | object | False | | | Session configuration used when `bearer_only` is `false` and the Plugin uses Authorization Code flow. | +| session.secret | string | True | | 16 or more characters | Key used for session encryption and HMAC operation when `bearer_only` is `false`. It is automatically generated and saved to etcd if not configured. When using APISIX in the standalone mode where etcd is no longer the configuration center, the `secret` should be configured. | +| session.cookie | object | False | | | Cookie configurations. | +| session.cookie.lifetime | integer | False | 3600 | | Cookie lifetime in seconds. | +| session_contents | object | False | | | Session content configurations. If unconfigured, all data will be stored in the session. | +| session_contents.access_token | boolean | False | | | If true, store the access token in the session. | +| session_contents.id_token | boolean | False | | | If true, store the ID token in the session. | +| session_contents.enc_id_token | boolean | False | | | If true, store the encrypted ID token in the session. | +| session_contents.user | boolean | False | | | If true, store the user info in the session. | +| unauth_action | string | False | auth | ["auth","deny","pass"] | Action for unauthenticated requests. When set to `auth`, redirect to the authentication endpoint of the OpenID provider. When set to `pass`, allow the request without authentication. When set to `deny`, return 401 unauthenticated responses rather than start the authorization code grant flow. | +| proxy_opts | object | False | | | Configurations for the proxy server that the OpenID provider is behind. | +| proxy_opts.http_proxy | string | False | | | Proxy server address for HTTP requests, such as `http://:`. | +| proxy_opts.https_proxy | string | False | | | Proxy server address for HTTPS requests, such as `http://:`. | +| proxy_opts.http_proxy_authorization | string | False | | Basic [base64 username:password] | Default `Proxy-Authorization` header value to be used with `http_proxy`. Can be overridden with custom `Proxy-Authorization` request header. | +| proxy_opts.https_proxy_authorization | string | False | | Basic [base64 username:password] | Default `Proxy-Authorization` header value to be used with `https_proxy`. Cannot be overridden with custom `Proxy-Authorization` request header since with HTTPS, the authorization is completed when connecting. | +| proxy_opts.no_proxy | string | False | | | Comma separated list of hosts that should not be proxied. | +| authorization_params | object | False | | | Additional parameters to send in the request to the authorization endpoint. | +| client_rsa_private_key | string | False | | | Client RSA private key used to sign JWT for authentication to the OP. Required when `token_endpoint_auth_method` is `private_key_jwt`. | +| client_rsa_private_key_id | string | False | | | Client RSA private key ID used to compute a signed JWT. Optional when `token_endpoint_auth_method` is `private_key_jwt`. | +| client_jwt_assertion_expires_in | integer | False | 60 | | Life duration of the signed JWT for authentication to the OP, in seconds. Used when `token_endpoint_auth_method` is `private_key_jwt` or `client_secret_jwt`. | +| renew_access_token_on_expiry | boolean | False | true | | If true, attempt to silently renew the access token when it expires or if a refresh token is available. If the token fails to renew, redirect user for re-authentication. | +| access_token_expires_in | integer | False | | | Lifetime of the access token in seconds if no `expires_in` attribute is present in the token endpoint response. | +| refresh_session_interval | integer | False | | | Time interval to refresh user ID token without requiring re-authentication. When not set, it will not check the expiration time of the session issued to the client by the gateway. If set to 900, it means refreshing the user's id_token (or session in the browser) after 900 seconds without requiring re-authentication. | +| iat_slack | integer | False | 120 | | Tolerance of clock skew in seconds with the `iat` claim in an ID token. | +| accept_none_alg | boolean | False | false | | Set to true if the OpenID provider does not sign its ID token, such as when the signature algorithm is set to `none`. | +| accept_unsupported_alg | boolean | False | true | | If true, ignore ID token signature to accept unsupported signature algorithm. | +| access_token_expires_leeway | integer | False | 0 | | Expiration leeway in seconds for access token renewal. When set to a value greater than 0, token renewal will take place the set amount of time before token expiration. This avoids errors in case the access token just expires when arriving to the resource server. | +| force_reauthorize | boolean | False | false | | If true, execute the authorization flow even when a token has been cached. | +| use_nonce | boolean | False | false | | If true, enable nonce parameter in authorization request. | +| revoke_tokens_on_logout | boolean | False | false | | If true, notify the authorization server a previously obtained refresh or access token is no longer needed at the revocation endpoint. | +| jwk_expires_in | integer | False | 86400 | | Expiration time for JWK cache in seconds. | +| jwt_verification_cache_ignore | boolean | False | false | | If true, force re-verification for a bearer token and ignore any existing cached verification results. | +| cache_segment | string | False | | | Optional name of a cache segment, used to separate and differentiate caches used by token introspection or JWT verification. | +| introspection_interval | integer | False | 0 | | TTL of the cached and introspected access token in seconds. The default value is 0, which means this option is not used and the Plugin defaults to use the TTL passed by expiry claim defined in `introspection_expiry_claim`. If `introspection_interval` is larger than 0 and less than the TTL passed by expiry claim defined in `introspection_expiry_claim`, use `introspection_interval`. | +| introspection_expiry_claim | string | False | exp | | Name of the expiry claim, which controls the TTL of the cached and introspected access token. | +| introspection_addon_headers | array[string] | False | | | Used to append additional header values to the introspection HTTP request. If the specified header does not exist in origin request, value will not be appended. | +| claim_validator.issuer.valid_issuers | string[] | False | | | Whitelist the vetted issuers of the jwt. When not passed by the user, the issuer returned by discovery endpoint will be used. In case both are missing, the issuer will not be validated. | NOTE: `encrypt_fields = {"client_secret"}` is also defined in the schema, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields). From af5164a46158aa06ed1082942d5657318984ed94 Mon Sep 17 00:00:00 2001 From: Eduard Schleining Date: Thu, 17 Jul 2025 10:11:44 +0200 Subject: [PATCH 7/9] fix: reformat table to reduce diff complexity --- docs/en/latest/plugins/openid-connect.md | 126 +++++++++++------------ 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/docs/en/latest/plugins/openid-connect.md b/docs/en/latest/plugins/openid-connect.md index 63f9d030e6be..2cf25e3ed522 100644 --- a/docs/en/latest/plugins/openid-connect.md +++ b/docs/en/latest/plugins/openid-connect.md @@ -37,70 +37,70 @@ The `openid-connect` Plugin supports the integration with [OpenID Connect (OIDC) ## Attributes -| Name | Type | Required | Default | Valid values | Description | -|--------------------------------------|----------|----------|-----------------------|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| client_id | string | True | | | OAuth client ID. | -| client_secret | string | True | | | OAuth client secret. | -| discovery | string | True | | | URL to the well-known discovery document of the OpenID provider, which contains a list of OP API endpoints. The Plugin can directly utilize the endpoints from the discovery document. You can also configure these endpoints individually, which takes precedence over the endpoints supplied in the discovery document. | -| scope | string | False | openid | | OIDC scope that corresponds to information that should be returned about the authenticated user, also known as [claims](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims). This is used to authorize users with proper permission. The default value is `openid`, the required scope for OIDC to return a `sub` claim that uniquely identifies the authenticated user. Additional scopes can be appended and delimited by spaces, such as `openid email profile`. | -| required_scopes | array[string] | False | | | Scopes required to be present in the access token. Used in conjunction with the introspection endpoint when `bearer_only` is `true`. If any required scope is missing, the Plugin rejects the request with a 403 forbidden error. | -| realm | string | False | apisix | | Realm in [`WWW-Authenticate`](https://www.rfc-editor.org/rfc/rfc6750#section-3) response header accompanying a 401 unauthorized request due to invalid bearer token. | -| bearer_only | boolean | False | false | | If true, strictly require bearer access token in requests for authentication. | -| logout_path | string | False | /logout | | Path to activate the logout. | -| post_logout_redirect_uri | string | False | | | URL to redirect users to after the `logout_path` receive a request to log out. | -| redirect_uri | string | False | | | URI to redirect to after authentication with the OpenID provider. Note that the redirect URI should not be the same as the request URI, but a sub-path of the request URI. For example, if the `uri` of the Route is `/api/v1/*`, `redirect_uri` can be configured as `/api/v1/redirect`. If `redirect_uri` is not configured, APISIX will append `/.apisix/redirect` to the request URI to determine the value for `redirect_uri`. | -| timeout | integer | False | 3 | [1,...] | Request timeout time in seconds. | -| ssl_verify | boolean | False | false | | If true, verify the OpenID provider 's SSL certificates. | -| introspection_endpoint | string | False | | | URL of the [token introspection](https://datatracker.ietf.org/doc/html/rfc7662) endpoint for the OpenID provider used to introspect access tokens. If this is unset, the introspection endpoint presented in the well-known discovery document is used [as a fallback](https://github.com/zmartzone/lua-resty-openidc/commit/cdaf824996d2b499de4c72852c91733872137c9c). | -| introspection_endpoint_auth_method | string | False | client_secret_basic | | Authentication method for the token introspection endpoint. The value should be one of the authentication methods specified in the `introspection_endpoint_auth_methods_supported` [authorization server metadata](https://www.rfc-editor.org/rfc/rfc8414.html) as seen in the well-known discovery document, such as `client_secret_basic`, `client_secret_post`, `private_key_jwt`, and `client_secret_jwt`. | +| Name | Type | Required | Default | Valid values | Description | +|--------------------------------------|----------|----------|-----------------------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| client_id | string | True | | | OAuth client ID. | +| client_secret | string | True | | | OAuth client secret. | +| discovery | string | True | | | URL to the well-known discovery document of the OpenID provider, which contains a list of OP API endpoints. The Plugin can directly utilize the endpoints from the discovery document. You can also configure these endpoints individually, which takes precedence over the endpoints supplied in the discovery document. | +| scope | string | False | openid | | OIDC scope that corresponds to information that should be returned about the authenticated user, also known as [claims](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims). This is used to authorize users with proper permission. The default value is `openid`, the required scope for OIDC to return a `sub` claim that uniquely identifies the authenticated user. Additional scopes can be appended and delimited by spaces, such as `openid email profile`. | +| required_scopes | array[string] | False | | | Scopes required to be present in the access token. Used in conjunction with the introspection endpoint when `bearer_only` is `true`. If any required scope is missing, the Plugin rejects the request with a 403 forbidden error. | +| realm | string | False | apisix | | Realm in [`WWW-Authenticate`](https://www.rfc-editor.org/rfc/rfc6750#section-3) response header accompanying a 401 unauthorized request due to invalid bearer token. | +| bearer_only | boolean | False | false | | If true, strictly require bearer access token in requests for authentication. | +| logout_path | string | False | /logout | | Path to activate the logout. | +| post_logout_redirect_uri | string | False | | | URL to redirect users to after the `logout_path` receive a request to log out. | +| redirect_uri | string | False | | | URI to redirect to after authentication with the OpenID provider. Note that the redirect URI should not be the same as the request URI, but a sub-path of the request URI. For example, if the `uri` of the Route is `/api/v1/*`, `redirect_uri` can be configured as `/api/v1/redirect`. If `redirect_uri` is not configured, APISIX will append `/.apisix/redirect` to the request URI to determine the value for `redirect_uri`. | +| timeout | integer | False | 3 | [1,...] | Request timeout time in seconds. | +| ssl_verify | boolean | False | false | | If true, verify the OpenID provider 's SSL certificates. | +| introspection_endpoint | string | False | | | URL of the [token introspection](https://datatracker.ietf.org/doc/html/rfc7662) endpoint for the OpenID provider used to introspect access tokens. If this is unset, the introspection endpoint presented in the well-known discovery document is used [as a fallback](https://github.com/zmartzone/lua-resty-openidc/commit/cdaf824996d2b499de4c72852c91733872137c9c). | +| introspection_endpoint_auth_method | string | False | client_secret_basic | | Authentication method for the token introspection endpoint. The value should be one of the authentication methods specified in the `introspection_endpoint_auth_methods_supported` [authorization server metadata](https://www.rfc-editor.org/rfc/rfc8414.html) as seen in the well-known discovery document, such as `client_secret_basic`, `client_secret_post`, `private_key_jwt`, and `client_secret_jwt`. | | token_endpoint_auth_method | string | False | client_secret_basic | | Authentication method for the token endpoint. The value should be one of the authentication methods specified in the `token_endpoint_auth_methods_supported` [authorization server metadata](https://www.rfc-editor.org/rfc/rfc8414.html) as seen in the well-known discovery document, such as `client_secret_basic`, `client_secret_post`, `private_key_jwt`, and `client_secret_jwt`. If the configured method is not supported, fall back to the first method in the `token_endpoint_auth_methods_supported` array. | -| public_key | string | False | | | Public key used to verify JWT signature id asymmetric algorithm is used. Providing this value to perform token verification will skip token introspection in client credentials flow. You can pass the public key in `-----BEGIN PUBLIC KEY-----\\n……\\n-----END PUBLIC KEY-----` format. | -| use_jwks | boolean | False | false | | If true and if `public_key` is not set, use the JWKS to verify JWT signature and skip token introspection in client credentials flow. The JWKS endpoint is parsed from the discovery document. | -| use_pkce | boolean | False | false | | If true, use the Proof Key for Code Exchange (PKCE) for Authorization Code Flow as defined in [RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636). | -| token_signing_alg_values_expected | string | False | | | Algorithm used for signing JWT, such as `RS256`. | -| set_access_token_header | boolean | False | true | | If true, set the access token in a request header. By default, the `X-Access-Token` header is used. | -| access_token_in_authorization_header | boolean | False | false | | If true and if `set_access_token_header` is also true, set the access token in the `Authorization` header. | -| set_id_token_header | boolean | False | true | | If true and if the ID token is available, set the value in the `X-ID-Token` request header. | -| set_id_token_original_header | boolean | False | true | | If true and if the ID token is available, set the value in the `X-ID-Token-Original` request header. In contrast to the `X-ID-TOKEN` header, this header will keep the original JWT encoding (including JWT headers and JWS signature). | -| set_userinfo_header | boolean | False | true | | If true and if user info data is available, set the value in the `X-Userinfo` request header. | -| set_refresh_token_header | boolean | False | false | | If true and if the refresh token is available, set the value in the `X-Refresh-Token` request header. | -| session | object | False | | | Session configuration used when `bearer_only` is `false` and the Plugin uses Authorization Code flow. | -| session.secret | string | True | | 16 or more characters | Key used for session encryption and HMAC operation when `bearer_only` is `false`. It is automatically generated and saved to etcd if not configured. When using APISIX in the standalone mode where etcd is no longer the configuration center, the `secret` should be configured. | -| session.cookie | object | False | | | Cookie configurations. | -| session.cookie.lifetime | integer | False | 3600 | | Cookie lifetime in seconds. | -| session_contents | object | False | | | Session content configurations. If unconfigured, all data will be stored in the session. | -| session_contents.access_token | boolean | False | | | If true, store the access token in the session. | -| session_contents.id_token | boolean | False | | | If true, store the ID token in the session. | -| session_contents.enc_id_token | boolean | False | | | If true, store the encrypted ID token in the session. | -| session_contents.user | boolean | False | | | If true, store the user info in the session. | -| unauth_action | string | False | auth | ["auth","deny","pass"] | Action for unauthenticated requests. When set to `auth`, redirect to the authentication endpoint of the OpenID provider. When set to `pass`, allow the request without authentication. When set to `deny`, return 401 unauthenticated responses rather than start the authorization code grant flow. | -| proxy_opts | object | False | | | Configurations for the proxy server that the OpenID provider is behind. | -| proxy_opts.http_proxy | string | False | | | Proxy server address for HTTP requests, such as `http://:`. | -| proxy_opts.https_proxy | string | False | | | Proxy server address for HTTPS requests, such as `http://:`. | -| proxy_opts.http_proxy_authorization | string | False | | Basic [base64 username:password] | Default `Proxy-Authorization` header value to be used with `http_proxy`. Can be overridden with custom `Proxy-Authorization` request header. | -| proxy_opts.https_proxy_authorization | string | False | | Basic [base64 username:password] | Default `Proxy-Authorization` header value to be used with `https_proxy`. Cannot be overridden with custom `Proxy-Authorization` request header since with HTTPS, the authorization is completed when connecting. | -| proxy_opts.no_proxy | string | False | | | Comma separated list of hosts that should not be proxied. | -| authorization_params | object | False | | | Additional parameters to send in the request to the authorization endpoint. | -| client_rsa_private_key | string | False | | | Client RSA private key used to sign JWT for authentication to the OP. Required when `token_endpoint_auth_method` is `private_key_jwt`. | -| client_rsa_private_key_id | string | False | | | Client RSA private key ID used to compute a signed JWT. Optional when `token_endpoint_auth_method` is `private_key_jwt`. | -| client_jwt_assertion_expires_in | integer | False | 60 | | Life duration of the signed JWT for authentication to the OP, in seconds. Used when `token_endpoint_auth_method` is `private_key_jwt` or `client_secret_jwt`. | -| renew_access_token_on_expiry | boolean | False | true | | If true, attempt to silently renew the access token when it expires or if a refresh token is available. If the token fails to renew, redirect user for re-authentication. | -| access_token_expires_in | integer | False | | | Lifetime of the access token in seconds if no `expires_in` attribute is present in the token endpoint response. | -| refresh_session_interval | integer | False | | | Time interval to refresh user ID token without requiring re-authentication. When not set, it will not check the expiration time of the session issued to the client by the gateway. If set to 900, it means refreshing the user's id_token (or session in the browser) after 900 seconds without requiring re-authentication. | -| iat_slack | integer | False | 120 | | Tolerance of clock skew in seconds with the `iat` claim in an ID token. | -| accept_none_alg | boolean | False | false | | Set to true if the OpenID provider does not sign its ID token, such as when the signature algorithm is set to `none`. | -| accept_unsupported_alg | boolean | False | true | | If true, ignore ID token signature to accept unsupported signature algorithm. | -| access_token_expires_leeway | integer | False | 0 | | Expiration leeway in seconds for access token renewal. When set to a value greater than 0, token renewal will take place the set amount of time before token expiration. This avoids errors in case the access token just expires when arriving to the resource server. | -| force_reauthorize | boolean | False | false | | If true, execute the authorization flow even when a token has been cached. | -| use_nonce | boolean | False | false | | If true, enable nonce parameter in authorization request. | -| revoke_tokens_on_logout | boolean | False | false | | If true, notify the authorization server a previously obtained refresh or access token is no longer needed at the revocation endpoint. | -| jwk_expires_in | integer | False | 86400 | | Expiration time for JWK cache in seconds. | -| jwt_verification_cache_ignore | boolean | False | false | | If true, force re-verification for a bearer token and ignore any existing cached verification results. | -| cache_segment | string | False | | | Optional name of a cache segment, used to separate and differentiate caches used by token introspection or JWT verification. | -| introspection_interval | integer | False | 0 | | TTL of the cached and introspected access token in seconds. The default value is 0, which means this option is not used and the Plugin defaults to use the TTL passed by expiry claim defined in `introspection_expiry_claim`. If `introspection_interval` is larger than 0 and less than the TTL passed by expiry claim defined in `introspection_expiry_claim`, use `introspection_interval`. | -| introspection_expiry_claim | string | False | exp | | Name of the expiry claim, which controls the TTL of the cached and introspected access token. | -| introspection_addon_headers | array[string] | False | | | Used to append additional header values to the introspection HTTP request. If the specified header does not exist in origin request, value will not be appended. | -| claim_validator.issuer.valid_issuers | string[] | False | | | Whitelist the vetted issuers of the jwt. When not passed by the user, the issuer returned by discovery endpoint will be used. In case both are missing, the issuer will not be validated. | +| public_key | string | False | | | Public key used to verify JWT signature id asymmetric algorithm is used. Providing this value to perform token verification will skip token introspection in client credentials flow. You can pass the public key in `-----BEGIN PUBLIC KEY-----\\n……\\n-----END PUBLIC KEY-----` format. | +| use_jwks | boolean | False | false | | If true and if `public_key` is not set, use the JWKS to verify JWT signature and skip token introspection in client credentials flow. The JWKS endpoint is parsed from the discovery document. | +| use_pkce | boolean | False | false | | If true, use the Proof Key for Code Exchange (PKCE) for Authorization Code Flow as defined in [RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636). | +| token_signing_alg_values_expected | string | False | | | Algorithm used for signing JWT, such as `RS256`. | +| set_access_token_header | boolean | False | true | | If true, set the access token in a request header. By default, the `X-Access-Token` header is used. | +| access_token_in_authorization_header | boolean | False | false | | If true and if `set_access_token_header` is also true, set the access token in the `Authorization` header. | +| set_id_token_header | boolean | False | true | | If true and if the ID token is available, set the value in the `X-ID-Token` request header. | +| set_id_token_original_header | boolean | False | true | | If true and if the ID token is available, set the value in the `X-ID-Token-Original` request header, which contains the original ID-Token with JWS signature and Headers (in contrast to the `X-ID-Token` header). | +| set_userinfo_header | boolean | False | true | | If true and if user info data is available, set the value in the `X-Userinfo` request header. | +| set_refresh_token_header | boolean | False | false | | If true and if the refresh token is available, set the value in the `X-Refresh-Token` request header. | +| session | object | False | | | Session configuration used when `bearer_only` is `false` and the Plugin uses Authorization Code flow. | +| session.secret | string | True | | 16 or more characters | Key used for session encryption and HMAC operation when `bearer_only` is `false`. It is automatically generated and saved to etcd if not configured. When using APISIX in the standalone mode where etcd is no longer the configuration center, the `secret` should be configured. | +| session.cookie | object | False | | | Cookie configurations. | +| session.cookie.lifetime | integer | False | 3600 | | Cookie lifetime in seconds. | +| session_contents | object | False | | | Session content configurations. If unconfigured, all data will be stored in the session. | +| session_contents.access_token | boolean | False | | | If true, store the access token in the session. | +| session_contents.id_token | boolean | False | | | If true, store the ID token in the session. | +| session_contents.enc_id_token | boolean | False | | | If true, store the encrypted ID token in the session. | +| session_contents.user | boolean | False | | | If true, store the user info in the session. | +| unauth_action | string | False | auth | ["auth","deny","pass"] | Action for unauthenticated requests. When set to `auth`, redirect to the authentication endpoint of the OpenID provider. When set to `pass`, allow the request without authentication. When set to `deny`, return 401 unauthenticated responses rather than start the authorization code grant flow. | +| proxy_opts | object | False | | | Configurations for the proxy server that the OpenID provider is behind. | +| proxy_opts.http_proxy | string | False | | | Proxy server address for HTTP requests, such as `http://:`. | +| proxy_opts.https_proxy | string | False | | | Proxy server address for HTTPS requests, such as `http://:`. | +| proxy_opts.http_proxy_authorization | string | False | | Basic [base64 username:password] | Default `Proxy-Authorization` header value to be used with `http_proxy`. Can be overridden with custom `Proxy-Authorization` request header. | +| proxy_opts.https_proxy_authorization | string | False | | Basic [base64 username:password] | Default `Proxy-Authorization` header value to be used with `https_proxy`. Cannot be overridden with custom `Proxy-Authorization` request header since with HTTPS, the authorization is completed when connecting. | +| proxy_opts.no_proxy | string | False | | | Comma separated list of hosts that should not be proxied. | +| authorization_params | object | False | | | Additional parameters to send in the request to the authorization endpoint. | +| client_rsa_private_key | string | False | | | Client RSA private key used to sign JWT for authentication to the OP. Required when `token_endpoint_auth_method` is `private_key_jwt`. | +| client_rsa_private_key_id | string | False | | | Client RSA private key ID used to compute a signed JWT. Optional when `token_endpoint_auth_method` is `private_key_jwt`. | +| client_jwt_assertion_expires_in | integer | False | 60 | | Life duration of the signed JWT for authentication to the OP, in seconds. Used when `token_endpoint_auth_method` is `private_key_jwt` or `client_secret_jwt`. | +| renew_access_token_on_expiry | boolean | False | true | | If true, attempt to silently renew the access token when it expires or if a refresh token is available. If the token fails to renew, redirect user for re-authentication. | +| access_token_expires_in | integer | False | | | Lifetime of the access token in seconds if no `expires_in` attribute is present in the token endpoint response. | +| refresh_session_interval | integer | False | | | Time interval to refresh user ID token without requiring re-authentication. When not set, it will not check the expiration time of the session issued to the client by the gateway. If set to 900, it means refreshing the user's id_token (or session in the browser) after 900 seconds without requiring re-authentication. | +| iat_slack | integer | False | 120 | | Tolerance of clock skew in seconds with the `iat` claim in an ID token. | +| accept_none_alg | boolean | False | false | | Set to true if the OpenID provider does not sign its ID token, such as when the signature algorithm is set to `none`. | +| accept_unsupported_alg | boolean | False | true | | If true, ignore ID token signature to accept unsupported signature algorithm. | +| access_token_expires_leeway | integer | False | 0 | | Expiration leeway in seconds for access token renewal. When set to a value greater than 0, token renewal will take place the set amount of time before token expiration. This avoids errors in case the access token just expires when arriving to the resource server. | +| force_reauthorize | boolean | False | false | | If true, execute the authorization flow even when a token has been cached. | +| use_nonce | boolean | False | false | | If true, enable nonce parameter in authorization request. | +| revoke_tokens_on_logout | boolean | False | false | | If true, notify the authorization server a previously obtained refresh or access token is no longer needed at the revocation endpoint. | +| jwk_expires_in | integer | False | 86400 | | Expiration time for JWK cache in seconds. | +| jwt_verification_cache_ignore | boolean | False | false | | If true, force re-verification for a bearer token and ignore any existing cached verification results. | +| cache_segment | string | False | | | Optional name of a cache segment, used to separate and differentiate caches used by token introspection or JWT verification. | +| introspection_interval | integer | False | 0 | | TTL of the cached and introspected access token in seconds. The default value is 0, which means this option is not used and the Plugin defaults to use the TTL passed by expiry claim defined in `introspection_expiry_claim`. If `introspection_interval` is larger than 0 and less than the TTL passed by expiry claim defined in `introspection_expiry_claim`, use `introspection_interval`. | +| introspection_expiry_claim | string | False | exp | | Name of the expiry claim, which controls the TTL of the cached and introspected access token. | +| introspection_addon_headers | array[string] | False | | | Used to append additional header values to the introspection HTTP request. If the specified header does not exist in origin request, value will not be appended. | +| claim_validator.issuer.valid_issuers | string[] | False | | | Whitelist the vetted issuers of the jwt. When not passed by the user, the issuer returned by discovery endpoint will be used. In case both are missing, the issuer will not be validated. | NOTE: `encrypt_fields = {"client_secret"}` is also defined in the schema, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields). From 5dd43e179c48cba62f0e0dc409fa89a1d76b752c Mon Sep 17 00:00:00 2001 From: cgmEdi <156078871+cgmEdi@users.noreply.github.com> Date: Tue, 22 Jul 2025 14:18:10 +0200 Subject: [PATCH 8/9] Update docs/en/latest/plugins/openid-connect.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/en/latest/plugins/openid-connect.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/en/latest/plugins/openid-connect.md b/docs/en/latest/plugins/openid-connect.md index 2cf25e3ed522..d474fb548d2c 100644 --- a/docs/en/latest/plugins/openid-connect.md +++ b/docs/en/latest/plugins/openid-connect.md @@ -61,7 +61,8 @@ The `openid-connect` Plugin supports the integration with [OpenID Connect (OIDC) | set_access_token_header | boolean | False | true | | If true, set the access token in a request header. By default, the `X-Access-Token` header is used. | | access_token_in_authorization_header | boolean | False | false | | If true and if `set_access_token_header` is also true, set the access token in the `Authorization` header. | | set_id_token_header | boolean | False | true | | If true and if the ID token is available, set the value in the `X-ID-Token` request header. | -| set_id_token_original_header | boolean | False | true | | If true and if the ID token is available, set the value in the `X-ID-Token-Original` request header, which contains the original ID-Token with JWS signature and Headers (in contrast to the `X-ID-Token` header). | +| set_id_token_original_header | boolean | False | true | | If true and if the ID token is available, set the value in the `X-ID-Token-Original` request header. +| | | | | | This header contains the original ID-Token with JWS signature and Headers (in contrast to the `X-ID-Token` header). | | set_userinfo_header | boolean | False | true | | If true and if user info data is available, set the value in the `X-Userinfo` request header. | | set_refresh_token_header | boolean | False | false | | If true and if the refresh token is available, set the value in the `X-Refresh-Token` request header. | | session | object | False | | | Session configuration used when `bearer_only` is `false` and the Plugin uses Authorization Code flow. | From 98bc71441dd2d57ea1adce53225f2d5d43a875a3 Mon Sep 17 00:00:00 2001 From: cgmEdi <156078871+cgmEdi@users.noreply.github.com> Date: Tue, 22 Jul 2025 14:18:19 +0200 Subject: [PATCH 9/9] Update apisix/plugins/openid-connect.lua Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- apisix/plugins/openid-connect.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apisix/plugins/openid-connect.lua b/apisix/plugins/openid-connect.lua index 2c473fc114c6..a9c2430c87f9 100644 --- a/apisix/plugins/openid-connect.lua +++ b/apisix/plugins/openid-connect.lua @@ -180,7 +180,7 @@ local schema = { description = "Whether the ID token should be added in the X-ID-Token-Original header to " .. "the request for downstream.", type = "boolean", - default = true + default = false }, set_userinfo_header = { description = "Whether the user info token should be added in the X-Userinfo " ..