This is an automated email from the ASF dual-hosted git repository. ephraimanierobi pushed a commit to branch v3-1-test in repository https://gitbox.apache.org/repos/asf/airflow.git
commit caa057100f47ff8b659178a86d565163fb71e6f9 Author: Bugra Ozturk <[email protected]> AuthorDate: Mon Feb 2 00:17:03 2026 +0100 [v3-1-test] Fix JWT token generation with unset issuer/audience config (#61278) (#61331) * Fix JWT token generation with unset issuer/audience config (cherry picked from commit a440d1d) Co-authored-by: Amogh Desai <[email protected]> --- airflow-core/pyproject.toml | 2 +- airflow-core/src/airflow/api_fastapi/auth/tokens.py | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/airflow-core/pyproject.toml b/airflow-core/pyproject.toml index fd28b8c716d..a4b46a3ea29 100644 --- a/airflow-core/pyproject.toml +++ b/airflow-core/pyproject.toml @@ -124,7 +124,7 @@ dependencies = [ # Pygments 2.19.0 improperly renders .ini files with dictionaries as values # See https://github.com/pygments/pygments/issues/2834 "pygments>=2.0.1,!=2.19.0", - "pyjwt>=2.10.0", + "pyjwt>=2.11.0", "python-daemon>=3.0.0", "python-dateutil>=2.7.0", "python-slugify>=5.0", diff --git a/airflow-core/src/airflow/api_fastapi/auth/tokens.py b/airflow-core/src/airflow/api_fastapi/auth/tokens.py index 276ae17153d..8fdaed0eb9e 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/tokens.py +++ b/airflow-core/src/airflow/api_fastapi/auth/tokens.py @@ -242,13 +242,13 @@ def _conf_list_factory( def _conf_list_factory(section, key, first_only: bool = False, **kwargs): - def factory() -> list[str] | str: + def factory() -> list[str] | str | None: from airflow.configuration import conf val = conf.getlist(section, key, **kwargs, suppress_warnings=True) - if first_only and val: - return val[0] + if first_only: + return val[0] if val else None return val or [] return factory @@ -330,7 +330,7 @@ class JWTValidator: key, audience=self.audience, issuer=self.issuer, - options={"require": self.required_claims}, + options={"require": list(self.required_claims)}, algorithms=self.algorithm, leeway=self.leeway, ) @@ -446,9 +446,12 @@ class JWTGenerator: "iat": now, } - if claims["iss"] is None: + # Remove iss and aud claims if they are falsy (None, [], "", etc.) + # Per RFC 7519, these are optional claims and should be omitted entirely + # rather than set to empty/invalid values: https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1 + if not claims["iss"]: del claims["iss"] - if claims["aud"] is None: + if not claims["aud"]: del claims["aud"] if extras is not None:
