1212
1313- ``GATEWAY_AUTH_ISSUER`` - Auth0 issuer URL (must end with ``/``)
1414- ``GATEWAY_AUTH_AUDIENCE`` - Auth0 API identifier the gateway accepts
15+ - ``GATEWAY_AUTH_REQUIRED`` - if truthy, missing issuer/audience is a 503
1516
1617For local development and unit tests the dependency can be bypassed by
1718setting ``GATEWAY_AUTH_DISABLED=1``. This bypass is hard-gated by
2021missing or looks like production, and otherwise requires an explicit
2122``GATEWAY_AUTH_DISABLED_ACK=I_UNDERSTAND_THIS_IS_DEV`` acknowledgement so
2223the bypass cannot be activated by a single stray env var. The gateway
23- also returns ``503`` to callers if auth is enabled but the issuer/audience
24- configuration is missing.
24+ also returns ``503`` to callers if auth is required but the issuer/audience
25+ configuration is missing, or if only one of issuer/audience is present .
2526"""
2627
2728from __future__ import annotations
4041
4142GATEWAY_AUTH_ISSUER_ENV = "GATEWAY_AUTH_ISSUER"
4243GATEWAY_AUTH_AUDIENCE_ENV = "GATEWAY_AUTH_AUDIENCE"
44+ GATEWAY_AUTH_REQUIRED_ENV = "GATEWAY_AUTH_REQUIRED"
4345GATEWAY_AUTH_DISABLED_ENV = "GATEWAY_AUTH_DISABLED"
4446GATEWAY_AUTH_DISABLED_ACK_ENV = "GATEWAY_AUTH_DISABLED_ACK"
4547GATEWAY_AUTH_DISABLED_ACK_VALUE = "I_UNDERSTAND_THIS_IS_DEV"
@@ -64,6 +66,15 @@ def _auth_disabled() -> bool:
6466 }
6567
6668
69+ def _auth_required () -> bool :
70+ return os .environ .get (GATEWAY_AUTH_REQUIRED_ENV , "" ).lower () in {
71+ "1" ,
72+ "true" ,
73+ "yes" ,
74+ "on" ,
75+ }
76+
77+
6778@functools .lru_cache (maxsize = 8 )
6879def _build_decoder (issuer : str , audience : str ) -> JWTDecoder :
6980 """Construct and cache a ``JWTDecoder`` keyed by issuer/audience.
@@ -182,13 +193,20 @@ def require_auth(
182193 missing or invalid token produces a 403 (matching the underlying
183194 decoder's contract).
184195
185- If issuer/audience env configuration is missing the dependency returns
186- 503 so operators see a clear misconfiguration instead of silent bypass.
196+ If issuer/audience env configuration is absent, the dependency preserves
197+ the legacy public gateway behavior unless ``GATEWAY_AUTH_REQUIRED`` is
198+ truthy. Partial auth configuration always returns 503 because it indicates
199+ an operator intended to enable auth but shipped an incomplete secret.
187200 """
188201
189202 if _auth_disabled ():
190203 return None
191204
205+ issuer = os .environ .get (GATEWAY_AUTH_ISSUER_ENV )
206+ audience = os .environ .get (GATEWAY_AUTH_AUDIENCE_ENV )
207+ if not issuer and not audience and not _auth_required ():
208+ return None
209+
192210 try :
193211 decoder = _get_decoder ()
194212 except RuntimeError as exc :
0 commit comments