Skip to content

Bearers Reference

JWTClaims

missil.JWTClaims

Bases: TypedDict

Base TypedDict for JWT claim payloads (RFC 7519).

All standard JWT registered claims are declared as optional fields. Subclass this to add application-specific claims with full type-checker support while remaining a plain :class:dict at runtime.

ATTRIBUTE DESCRIPTION
exp

Expiration time — Unix timestamp after which the token is invalid. Validated automatically by PyJWT on decode.

TYPE: int

iat

Issued at — Unix timestamp of when the token was issued.

TYPE: int

nbf

Not before — Unix timestamp before which the token is not valid. Validated automatically by PyJWT on decode.

TYPE: int

sub

Subject — identifier of the token's subject (e.g. user ID).

TYPE: str

iss

Issuer — identifies who issued the token (e.g. "myapp.com").

TYPE: str

aud

Audience — identifies the recipients the token is intended for.

TYPE: str | list[str]

jti

JWT ID — unique identifier for the token, useful for revocation.

TYPE: str

Examples:

The field holding user permissions must match the permissions_key configured on the bearer instance:

bearer = missil.TokenBearer(TOKEN_KEY, SECRET_KEY, permissions_key="scopes")

Declare a subclass with a field of the same name:

from missil import JWTClaims


class AppClaims(JWTClaims):
    username: str
    scopes: dict[str, int]  # must match permissions_key

Then annotate route parameters with the subclass:

@app.get("/profile", dependencies=[areas.finances.READ])
def profile(user: Annotated[AppClaims, areas.finances.READ]) -> AppClaims:
    username = user["username"]  # typed as str
    return user

exp instance-attribute

exp

iat instance-attribute

iat

nbf instance-attribute

nbf

sub instance-attribute

sub

iss instance-attribute

iss

aud instance-attribute

aud

jti instance-attribute

jti

TokenBearer

missil.TokenBearer

TokenBearer(token_key, secret_key, permissions_key=None, algorithms='HS256', *, user_permissions_key=None)

Bases: TokenSource

Try to read the token from cookies, falling back to the request header.

Configure JWT token extraction and decoding.

PARAMETER DESCRIPTION
token_key

Name of the header or cookie key that carries the JWT token.

TYPE: str

secret_key

Secret key used to decode the signed token.

TYPE: str

permissions_key

Key inside the decoded JWT payload that holds the permissions dict. Example payload:

{
    "username": "John Doe",
    "permissions": {  # permissions_key = "permissions"
        "finances": 0,
        "it": 1,
    },
}

TYPE: str DEFAULT: None

algorithms

JWT decoding algorithm(s), by default "HS256". See PyJWT docs for supported values.

TYPE: str | list[str] DEFAULT: 'HS256'

user_permissions_key

Deprecated. Use permissions_key instead.

TYPE: str DEFAULT: None

Source code in missil/bearers.py
def __init__(
    self,
    token_key: str,
    secret_key: str,
    permissions_key: str | None = None,
    algorithms: str | list[str] = "HS256",
    *,
    user_permissions_key: str | None = None,
):
    """
    Configure JWT token extraction and decoding.

    Parameters
    ----------
    token_key : str
        Name of the header or cookie key that carries the JWT token.
    secret_key : str
        Secret key used to decode the signed token.
    permissions_key : str
        Key inside the decoded JWT payload that holds the permissions dict.
        Example payload:

        ```python
        {
            "username": "John Doe",
            "permissions": {  # permissions_key = "permissions"
                "finances": 0,
                "it": 1,
            },
        }
        ```

    algorithms : str | list[str], optional
        JWT decoding algorithm(s), by default "HS256".
        See PyJWT docs for supported values.
    user_permissions_key : str, optional
        Deprecated. Use ``permissions_key`` instead.
    """
    if user_permissions_key is not None:
        warnings.warn(
            "'user_permissions_key' is deprecated and will be removed in a future "
            "version. Use 'permissions_key' instead.",
            DeprecationWarning,
            stacklevel=2,
        )
        permissions_key = permissions_key or user_permissions_key

    if not permissions_key:
        raise ValueError(
            "permissions_key is required. "
            "Pass the JWT claim key that holds the permissions dict, "
            "e.g. TokenSource(..., permissions_key='permissions')."
        )
    self.token_key = token_key
    self.token_secret_key = secret_key
    self.algorithms: list[str] = (
        [algorithms] if isinstance(algorithms, str) else list(algorithms)
    )
    self.permissions_key = permissions_key

token_key instance-attribute

token_key = token_key

token_secret_key instance-attribute

token_secret_key = secret_key

algorithms instance-attribute

algorithms = [algorithms] if isinstance(algorithms, str) else list(algorithms)

permissions_key instance-attribute

permissions_key = permissions_key

split_token_str

split_token_str(token, sep=' ')

Get only the token value from the source.

Source code in missil/bearers.py
def split_token_str(self, token: str, sep: str = " ") -> str:
    """Get only the token value from the source."""
    if "bearer" in token.lower():
        token = token.split(sep, 1)[-1]

    return token

get_token_from_cookies

get_token_from_cookies(request)

Read the token value from http cookies.

Source code in missil/bearers.py
def get_token_from_cookies(self, request: Request) -> str:
    """Read the token value from http cookies."""
    token = request.cookies.get(self.token_key)

    if not token:
        raise TokenValidationException(
            status.HTTP_403_FORBIDDEN,
            f"Token not found on request cookies using key '{self.token_key}'",
        )

    return self.split_token_str(token)

get_token_from_header

get_token_from_header(request)

Get the token value from request headers.

Source code in missil/bearers.py
def get_token_from_header(self, request: Request) -> str:
    """Get the token value from request headers."""
    token = request.headers.get(self.token_key)

    if not token:
        raise TokenValidationException(
            status.HTTP_403_FORBIDDEN,
            f"Token not found on request headers using key '{self.token_key}'",
        )

    return self.split_token_str(token)

decode_jwt

decode_jwt(token)

Decode a retrieved token value and return the full JWT claims.

Source code in missil/bearers.py
def decode_jwt(self, token: str) -> JWTClaims:
    """Decode a retrieved token value and return the full JWT claims."""
    return decode_jwt_token(
        token, self.token_secret_key, algorithms=self.algorithms
    )

decode_from_cookies

decode_from_cookies(request)

Get token from cookies and decode it.

Source code in missil/bearers.py
def decode_from_cookies(self, request: Request) -> JWTClaims:
    """Get token from cookies and decode it."""
    token = self.get_token_from_cookies(request)
    return self.decode_jwt(token)

decode_from_header

decode_from_header(request)

Get token from headers and decode it.

Source code in missil/bearers.py
def decode_from_header(self, request: Request) -> JWTClaims:
    """Get token from headers and decode it."""
    token = self.get_token_from_header(request)
    return self.decode_jwt(token)

get_user_permissions

get_user_permissions(decoded_token)

Get user permissions from a decoded token.

Source code in missil/bearers.py
def get_user_permissions(self, decoded_token: JWTClaims) -> dict[str, int]:
    """Get user permissions from a decoded token."""
    raw: dict[str, Any] = cast(dict[str, Any], decoded_token)
    try:
        user_permissions: dict[str, int] = raw[self.permissions_key]
    except KeyError as ke:
        raise TokenValidationException(
            401,
            f"User permissions not found at token key " f"'{self.permissions_key}'",
        ) from ke
    return user_permissions

CookieTokenBearer

missil.CookieTokenBearer

CookieTokenBearer(token_key, secret_key, permissions_key=None, algorithms='HS256', *, user_permissions_key=None)

Bases: TokenSource

Read JWT token from http cookies.

Configure JWT token extraction and decoding.

PARAMETER DESCRIPTION
token_key

Name of the header or cookie key that carries the JWT token.

TYPE: str

secret_key

Secret key used to decode the signed token.

TYPE: str

permissions_key

Key inside the decoded JWT payload that holds the permissions dict. Example payload:

{
    "username": "John Doe",
    "permissions": {  # permissions_key = "permissions"
        "finances": 0,
        "it": 1,
    },
}

TYPE: str DEFAULT: None

algorithms

JWT decoding algorithm(s), by default "HS256". See PyJWT docs for supported values.

TYPE: str | list[str] DEFAULT: 'HS256'

user_permissions_key

Deprecated. Use permissions_key instead.

TYPE: str DEFAULT: None

Source code in missil/bearers.py
def __init__(
    self,
    token_key: str,
    secret_key: str,
    permissions_key: str | None = None,
    algorithms: str | list[str] = "HS256",
    *,
    user_permissions_key: str | None = None,
):
    """
    Configure JWT token extraction and decoding.

    Parameters
    ----------
    token_key : str
        Name of the header or cookie key that carries the JWT token.
    secret_key : str
        Secret key used to decode the signed token.
    permissions_key : str
        Key inside the decoded JWT payload that holds the permissions dict.
        Example payload:

        ```python
        {
            "username": "John Doe",
            "permissions": {  # permissions_key = "permissions"
                "finances": 0,
                "it": 1,
            },
        }
        ```

    algorithms : str | list[str], optional
        JWT decoding algorithm(s), by default "HS256".
        See PyJWT docs for supported values.
    user_permissions_key : str, optional
        Deprecated. Use ``permissions_key`` instead.
    """
    if user_permissions_key is not None:
        warnings.warn(
            "'user_permissions_key' is deprecated and will be removed in a future "
            "version. Use 'permissions_key' instead.",
            DeprecationWarning,
            stacklevel=2,
        )
        permissions_key = permissions_key or user_permissions_key

    if not permissions_key:
        raise ValueError(
            "permissions_key is required. "
            "Pass the JWT claim key that holds the permissions dict, "
            "e.g. TokenSource(..., permissions_key='permissions')."
        )
    self.token_key = token_key
    self.token_secret_key = secret_key
    self.algorithms: list[str] = (
        [algorithms] if isinstance(algorithms, str) else list(algorithms)
    )
    self.permissions_key = permissions_key

token_key instance-attribute

token_key = token_key

token_secret_key instance-attribute

token_secret_key = secret_key

algorithms instance-attribute

algorithms = [algorithms] if isinstance(algorithms, str) else list(algorithms)

permissions_key instance-attribute

permissions_key = permissions_key

split_token_str

split_token_str(token, sep=' ')

Get only the token value from the source.

Source code in missil/bearers.py
def split_token_str(self, token: str, sep: str = " ") -> str:
    """Get only the token value from the source."""
    if "bearer" in token.lower():
        token = token.split(sep, 1)[-1]

    return token

get_token_from_cookies

get_token_from_cookies(request)

Read the token value from http cookies.

Source code in missil/bearers.py
def get_token_from_cookies(self, request: Request) -> str:
    """Read the token value from http cookies."""
    token = request.cookies.get(self.token_key)

    if not token:
        raise TokenValidationException(
            status.HTTP_403_FORBIDDEN,
            f"Token not found on request cookies using key '{self.token_key}'",
        )

    return self.split_token_str(token)

get_token_from_header

get_token_from_header(request)

Get the token value from request headers.

Source code in missil/bearers.py
def get_token_from_header(self, request: Request) -> str:
    """Get the token value from request headers."""
    token = request.headers.get(self.token_key)

    if not token:
        raise TokenValidationException(
            status.HTTP_403_FORBIDDEN,
            f"Token not found on request headers using key '{self.token_key}'",
        )

    return self.split_token_str(token)

decode_jwt

decode_jwt(token)

Decode a retrieved token value and return the full JWT claims.

Source code in missil/bearers.py
def decode_jwt(self, token: str) -> JWTClaims:
    """Decode a retrieved token value and return the full JWT claims."""
    return decode_jwt_token(
        token, self.token_secret_key, algorithms=self.algorithms
    )

decode_from_cookies

decode_from_cookies(request)

Get token from cookies and decode it.

Source code in missil/bearers.py
def decode_from_cookies(self, request: Request) -> JWTClaims:
    """Get token from cookies and decode it."""
    token = self.get_token_from_cookies(request)
    return self.decode_jwt(token)

decode_from_header

decode_from_header(request)

Get token from headers and decode it.

Source code in missil/bearers.py
def decode_from_header(self, request: Request) -> JWTClaims:
    """Get token from headers and decode it."""
    token = self.get_token_from_header(request)
    return self.decode_jwt(token)

get_user_permissions

get_user_permissions(decoded_token)

Get user permissions from a decoded token.

Source code in missil/bearers.py
def get_user_permissions(self, decoded_token: JWTClaims) -> dict[str, int]:
    """Get user permissions from a decoded token."""
    raw: dict[str, Any] = cast(dict[str, Any], decoded_token)
    try:
        user_permissions: dict[str, int] = raw[self.permissions_key]
    except KeyError as ke:
        raise TokenValidationException(
            401,
            f"User permissions not found at token key " f"'{self.permissions_key}'",
        ) from ke
    return user_permissions

HeaderTokenBearer

missil.HeaderTokenBearer

HeaderTokenBearer(token_key, secret_key, permissions_key=None, algorithms='HS256', *, user_permissions_key=None)

Bases: TokenSource

Read JWT token from the Authorization request header.

Configure JWT token extraction and decoding.

PARAMETER DESCRIPTION
token_key

Name of the header or cookie key that carries the JWT token.

TYPE: str

secret_key

Secret key used to decode the signed token.

TYPE: str

permissions_key

Key inside the decoded JWT payload that holds the permissions dict. Example payload:

{
    "username": "John Doe",
    "permissions": {  # permissions_key = "permissions"
        "finances": 0,
        "it": 1,
    },
}

TYPE: str DEFAULT: None

algorithms

JWT decoding algorithm(s), by default "HS256". See PyJWT docs for supported values.

TYPE: str | list[str] DEFAULT: 'HS256'

user_permissions_key

Deprecated. Use permissions_key instead.

TYPE: str DEFAULT: None

Source code in missil/bearers.py
def __init__(
    self,
    token_key: str,
    secret_key: str,
    permissions_key: str | None = None,
    algorithms: str | list[str] = "HS256",
    *,
    user_permissions_key: str | None = None,
):
    """
    Configure JWT token extraction and decoding.

    Parameters
    ----------
    token_key : str
        Name of the header or cookie key that carries the JWT token.
    secret_key : str
        Secret key used to decode the signed token.
    permissions_key : str
        Key inside the decoded JWT payload that holds the permissions dict.
        Example payload:

        ```python
        {
            "username": "John Doe",
            "permissions": {  # permissions_key = "permissions"
                "finances": 0,
                "it": 1,
            },
        }
        ```

    algorithms : str | list[str], optional
        JWT decoding algorithm(s), by default "HS256".
        See PyJWT docs for supported values.
    user_permissions_key : str, optional
        Deprecated. Use ``permissions_key`` instead.
    """
    if user_permissions_key is not None:
        warnings.warn(
            "'user_permissions_key' is deprecated and will be removed in a future "
            "version. Use 'permissions_key' instead.",
            DeprecationWarning,
            stacklevel=2,
        )
        permissions_key = permissions_key or user_permissions_key

    if not permissions_key:
        raise ValueError(
            "permissions_key is required. "
            "Pass the JWT claim key that holds the permissions dict, "
            "e.g. TokenSource(..., permissions_key='permissions')."
        )
    self.token_key = token_key
    self.token_secret_key = secret_key
    self.algorithms: list[str] = (
        [algorithms] if isinstance(algorithms, str) else list(algorithms)
    )
    self.permissions_key = permissions_key

token_key instance-attribute

token_key = token_key

token_secret_key instance-attribute

token_secret_key = secret_key

algorithms instance-attribute

algorithms = [algorithms] if isinstance(algorithms, str) else list(algorithms)

permissions_key instance-attribute

permissions_key = permissions_key

split_token_str

split_token_str(token, sep=' ')

Get only the token value from the source.

Source code in missil/bearers.py
def split_token_str(self, token: str, sep: str = " ") -> str:
    """Get only the token value from the source."""
    if "bearer" in token.lower():
        token = token.split(sep, 1)[-1]

    return token

get_token_from_cookies

get_token_from_cookies(request)

Read the token value from http cookies.

Source code in missil/bearers.py
def get_token_from_cookies(self, request: Request) -> str:
    """Read the token value from http cookies."""
    token = request.cookies.get(self.token_key)

    if not token:
        raise TokenValidationException(
            status.HTTP_403_FORBIDDEN,
            f"Token not found on request cookies using key '{self.token_key}'",
        )

    return self.split_token_str(token)

get_token_from_header

get_token_from_header(request)

Get the token value from request headers.

Source code in missil/bearers.py
def get_token_from_header(self, request: Request) -> str:
    """Get the token value from request headers."""
    token = request.headers.get(self.token_key)

    if not token:
        raise TokenValidationException(
            status.HTTP_403_FORBIDDEN,
            f"Token not found on request headers using key '{self.token_key}'",
        )

    return self.split_token_str(token)

decode_jwt

decode_jwt(token)

Decode a retrieved token value and return the full JWT claims.

Source code in missil/bearers.py
def decode_jwt(self, token: str) -> JWTClaims:
    """Decode a retrieved token value and return the full JWT claims."""
    return decode_jwt_token(
        token, self.token_secret_key, algorithms=self.algorithms
    )

decode_from_cookies

decode_from_cookies(request)

Get token from cookies and decode it.

Source code in missil/bearers.py
def decode_from_cookies(self, request: Request) -> JWTClaims:
    """Get token from cookies and decode it."""
    token = self.get_token_from_cookies(request)
    return self.decode_jwt(token)

decode_from_header

decode_from_header(request)

Get token from headers and decode it.

Source code in missil/bearers.py
def decode_from_header(self, request: Request) -> JWTClaims:
    """Get token from headers and decode it."""
    token = self.get_token_from_header(request)
    return self.decode_jwt(token)

get_user_permissions

get_user_permissions(decoded_token)

Get user permissions from a decoded token.

Source code in missil/bearers.py
def get_user_permissions(self, decoded_token: JWTClaims) -> dict[str, int]:
    """Get user permissions from a decoded token."""
    raw: dict[str, Any] = cast(dict[str, Any], decoded_token)
    try:
        user_permissions: dict[str, int] = raw[self.permissions_key]
    except KeyError as ke:
        raise TokenValidationException(
            401,
            f"User permissions not found at token key " f"'{self.permissions_key}'",
        ) from ke
    return user_permissions