From ffe9f0114e3410d37f98ec5f0a45c063f9821244 Mon Sep 17 00:00:00 2001 From: "keycard-gh-workflows-access[bot]" <259488581+keycard-gh-workflows-access[bot]@users.noreply.github.com> Date: Mon, 20 Jul 2026 17:59:06 +0000 Subject: [PATCH] =?UTF-8?q?bump:=20keycardai-starlette=20=E2=86=92=200.11.?= =?UTF-8?q?0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Auto-bump for keycardai-starlette. --- packages/starlette/CHANGELOG.md | 32 +++++++++++++++++++++++++++++++ packages/starlette/pyproject.toml | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/packages/starlette/CHANGELOG.md b/packages/starlette/CHANGELOG.md index 241369d..5e27e76 100644 --- a/packages/starlette/CHANGELOG.md +++ b/packages/starlette/CHANGELOG.md @@ -1,3 +1,35 @@ +## 0.11.0-keycardai-starlette (2026-07-20) + + +- fix(keycardai-starlette): return 401/503 (not 500) for JWKS errors (#196) +- * fix(keycardai-starlette): return 401/503 (not 500) for JWKS errors +- KeycardAuthBackend.authenticate() caught only InvalidTokenError. JWKS +errors are a separate tree (JWKSError/JWKSKeyNotFoundError extend +OAuthError(Exception); JWKSDiscoveryError/JWKSUriValidationError extend +OAuthServerError(Exception)), none of which is InvalidTokenError or a +Starlette AuthenticationError. They escaped AuthenticationMiddleware to +ServerErrorMiddleware, yielding HTTP 500 with no WWW-Authenticate. +- So a token whose kid is absent from the JWKS (forged, or rotated out), +or an unreachable/non-2xx JWKS or discovery endpoint, returned 500 +instead of a 401 (client should re-auth) or 503 (transient). This is the +Python-side of the same bug reported against the TypeScript SDK (#119). +- Map the JWKS error classes at the auth boundary: +- JWKSKeyNotFoundError -> KeycardAuthError invalid_token (401 + challenge) +- JWKSError / JWKSDiscoveryError / JWKSUriValidationError -> 503 +- _build_unauthorized_response now emits a bare 503 body with no +WWW-Authenticate header for 5xx, since that challenge is not one a client +can satisfy by re-authenticating. +- Refs keycardai/typescript-sdk#119 +- * docs(keycardai-starlette): note the 503 bucket is intentionally narrow +- The 503 except clause lists the named JWKS discovery/fetch classes rather +than the OAuthServerError base on purpose: config and cache faults +(VerifierConfigError, CacheError) are not per-request failures and must +stay on the unexpected-error path (500), not be advertised as a +transient 503. +- Comment only, no behavior change. +- --------- +- Co-authored-by: GitHub Action + ## 0.10.0-keycardai-starlette (2026-06-15) diff --git a/packages/starlette/pyproject.toml b/packages/starlette/pyproject.toml index d15614a..fb5d5e3 100644 --- a/packages/starlette/pyproject.toml +++ b/packages/starlette/pyproject.toml @@ -114,7 +114,7 @@ addopts = "-ra -q" [tool.commitizen] name = "cz_customize" -version = "0.10.0" +version = "0.11.0" tag_format = "${version}-keycardai-starlette" ignored_tag_formats = ["${version}-*"] update_changelog_on_bump = true