Skip to content

Setting allowed_jwt_audiences crashes: validator only accepts a string #187

Description

@emmanuelmathot

Summary

allowed_jwt_audiences is typed Optional[Sequence[str]], but its mode="before" validator unconditionally calls str2list(v), which assumes v is a string. Passing a list raises AttributeError: 'list' object has no attribute 'replace'.

This only works by accident when the value arrives as a raw env-var string. Any programmatic caller that passes an already-parsed list (e.g. constructing Settings(...) directly, or calling configure_app(allowed_jwt_audiences=[...])) crashes at startup.

Version

  • stac-auth-proxy 1.1.1

Reproduction

from stac_auth_proxy.config import Settings

Settings(
    upstream_url="http://localhost:8080",
    oidc_discovery_url="https://example/.well-known/openid-configuration",
    allowed_jwt_audiences=["sfeos", "account"],   # a valid Sequence[str]
)

The validator narrows the accepted input to str | None, contradicting the field's Optional[Sequence[str]] annotation.

Expected behavior

A list/tuple (any Sequence[str]) should pass through unchanged; a comma-separated string should still be split; None/empty should stay None.

Suggested fix

annotate the field with NoDecode so pydantic-settings hands the validator the raw env string (instead of JSON-decoding it first), and make the validator idempotent for list input. This matches how downstreams already work around it:

from pydantic_settings import NoDecode

allowed_jwt_audiences: Annotated[Optional[Sequence[str]], NoDecode] = None

Workaround

Callers can pass a comma-separated string instead of a list, e.g. ",".join(audiences).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions