Skip to content

Rules Reference

AreasBase

missil.AreasBase

AreasBase(bearer)

Base class for declaring business areas as typed attributes.

Subclass it and annotate each field as :class:Area. On instantiation, all annotated fields are automatically created and accessible as typed attributes:

import missil

bearer = missil.TokenBearer("Authorization", SECRET_KEY, "permissions")


class AppAreas(missil.AreasBase):
    finances: missil.Area
    it: missil.Area


areas = AppAreas(bearer)


@app.get("/report", dependencies=[areas.finances.READ])
def report(): ...

Annotations typed as anything other than :class:Area are silently ignored, so you can freely add non-area class attributes to your subclass.

Instantiate all declared Area fields.

PARAMETER DESCRIPTION
bearer

JWT token source shared by all areas in this group.

TYPE: TokenSource

Source code in missil/rules.py
def __init__(self, bearer: TokenSource) -> None:
    """
    Instantiate all declared Area fields.

    Parameters
    ----------
    bearer : TokenSource
        JWT token source shared by all areas in this group.
    """
    try:
        hints = get_type_hints(type(self))
    except Exception:
        hints = getattr(type(self), "__annotations__", {})

    for name, annotation in hints.items():
        if annotation is Area:
            setattr(self, name, Area(name, bearer))

Area

missil.Area

Area(name, bearer)

Business area grouping READ and WRITE access rules.

An Area instance holds pre-built AccessRule objects for each access level, ready to be injected as FastAPI endpoint dependencies:

bearer = ...
finances = Area("finances", bearer)


@app.get("/finances/read", dependencies=[finances.READ])
def finances_read() -> dict[str, str]: ...

Create a business area.

PARAMETER DESCRIPTION
name

Business area name.

TYPE: str

bearer

JWT token source. See Bearers module.

TYPE: TokenSource

Source code in missil/rules.py
def __init__(self, name: str, bearer: TokenSource) -> None:
    """
    Create a business area.

    Parameters
    ----------
    name : str
        Business area name.
    bearer : TokenSource
        JWT token source. See Bearers module.
    """
    self.name: str = name
    self.bearer = bearer
    self.READ = AccessRule(self.name, READ, self.bearer)
    self.WRITE = AccessRule(self.name, WRITE, self.bearer)
    self.ADMIN = AccessRule(self.name, ADMIN, self.bearer)

name instance-attribute

name = name

bearer instance-attribute

bearer = bearer

READ instance-attribute

READ = AccessRule(name, READ, bearer)

WRITE instance-attribute

WRITE = AccessRule(name, WRITE, bearer)

ADMIN instance-attribute

ADMIN = AccessRule(name, ADMIN, bearer)

AccessRule

missil.AccessRule

AccessRule(area, level, bearer, use_cache=True)

Bases: Depends

FastAPI dependency that enforces an endpoint-level access rule.

Grant or deny user access to an endpoint.

Access is granted by verifying that the JWT token claims include the requested business area at the required access level.

PARAMETER DESCRIPTION
area

Business area name, e.g. 'finances' or 'human_resources'.

TYPE: str

level

Required access level: READ = 0 / WRITE = 1.

TYPE: int

bearer

JWT token source. See Bearers module.

TYPE: TokenSource

use_cache

FastAPI Depends cache parameter, by default True.

TYPE: bool DEFAULT: True

Source code in missil/rules.py
def __init__(
    self,
    area: str,
    level: int,
    bearer: TokenSource,
    use_cache: bool = True,
):
    """
    Grant or deny user access to an endpoint.

    Access is granted by verifying that the JWT token claims include
    the requested business area at the required access level.

    Parameters
    ----------
    area : str
        Business area name, e.g. 'finances' or 'human_resources'.
    level : int
        Required access level: READ = 0 / WRITE = 1.
    bearer : TokenSource
        JWT token source. See Bearers module.
    use_cache : bool, optional
        FastAPI Depends cache parameter, by default True.
    """
    # FastAPIDependsClass became a frozen dataclass in FastAPI 0.115+;
    # object.__setattr__ is the standard way to set fields on frozen instances.
    # Note: "dependency" is intentionally not set here — it's provided by the
    # property below. "scope" uses the dataclass default (None).
    object.__setattr__(self, "area", area)
    object.__setattr__(self, "level", level)
    object.__setattr__(self, "bearer", bearer)
    object.__setattr__(self, "use_cache", use_cache)
    object.__setattr__(self, "scope", None)
    object.__setattr__(self, "dependency", self._make_dependency())

area instance-attribute

area

level instance-attribute

level

bearer instance-attribute

bearer

Role

missil.Role

Role(*rules, use_cache=True)

Bases: Depends

A named group of AccessRules that must all be satisfied for access to be granted.

Use a Role to avoid repeating the same set of rules across multiple endpoints. Access is granted only when every constituent AccessRule passes:

bearer = missil.TokenBearer("Authorization", SECRET_KEY, "permissions")


class AppAreas(missil.AreasBase):
    finances: missil.Area
    it: missil.Area


areas = AppAreas(bearer)

analyst = missil.Role(areas.finances.READ, areas.it.READ)


@app.get("/dashboard", dependencies=[analyst])
def dashboard(): ...

If any rule fails, FastAPI raises HTTP 403 before the endpoint is reached.

Create a role from one or more AccessRules.

PARAMETER DESCRIPTION
*rules

The access rules that must all pass for this role to be satisfied.

TYPE: AccessRule DEFAULT: ()

use_cache

FastAPI Depends cache parameter, by default True.

TYPE: bool DEFAULT: True

Source code in missil/rules.py
def __init__(self, *rules: "AccessRule", use_cache: bool = True) -> None:
    """
    Create a role from one or more AccessRules.

    Parameters
    ----------
    *rules : AccessRule
        The access rules that must all pass for this role to be satisfied.
    use_cache : bool, optional
        FastAPI Depends cache parameter, by default True.
    """
    object.__setattr__(self, "rules", rules)
    object.__setattr__(self, "use_cache", use_cache)
    object.__setattr__(self, "scope", None)
    object.__setattr__(self, "dependency", self._make_dependency())

rules instance-attribute

rules

make_area

Deprecated

Use missil.Area(name, bearer) directly instead. See the Migration Guide.

missil.make_area

make_area(bearer, area)

Create a single business area.

Deprecated

Use Area directly instead:

finances = missil.Area("finances", bearer)
PARAMETER DESCRIPTION
bearer

JWT token source. See Bearers module.

TYPE: TokenSource

area

Business area name.

TYPE: str

RETURNS DESCRIPTION
Area

Business area with READ and WRITE rules.

Source code in missil/rules.py
def make_area(bearer: TokenSource, area: str) -> Area:
    """
    Create a single business area.

    !!! danger "Deprecated"
        Use `Area` directly instead:

        ```python
        finances = missil.Area("finances", bearer)
        ```

    Parameters
    ----------
    bearer : TokenSource
        JWT token source. See Bearers module.
    area : str
        Business area name.

    Returns
    -------
    Area
        Business area with READ and WRITE rules.
    """
    warnings.warn(
        "make_area() is deprecated and will be removed in a future version. "
        "Use Area(name, bearer) directly instead.",
        DeprecationWarning,
        stacklevel=2,
    )
    return Area(area, bearer)

make_areas

Deprecated

Use AreasBase instead. See the Migration Guide.

missil.make_areas

make_areas(bearer, *areas)

Create a Missil ruleset from a token source and business area names.

Deprecated

Use AreasBase instead:

class AppAreas(missil.AreasBase):
    finances: missil.Area
    it: missil.Area


areas = AppAreas(bearer)
PARAMETER DESCRIPTION
bearer

JWT token source. See Bearers module.

TYPE: TokenSource

*areas

Business area names to protect.

TYPE: str DEFAULT: ()

RETURNS DESCRIPTION
dict[str, Area]

Mapping of area name to Area.

Source code in missil/rules.py
def make_areas(bearer: TokenSource, *areas: str) -> dict[str, Area]:
    """
    Create a Missil ruleset from a token source and business area names.

    !!! danger "Deprecated"
        Use `AreasBase` instead:

        ```python
        class AppAreas(missil.AreasBase):
            finances: missil.Area
            it: missil.Area


        areas = AppAreas(bearer)
        ```

    Parameters
    ----------
    bearer : TokenSource
        JWT token source. See Bearers module.
    *areas : str
        Business area names to protect.

    Returns
    -------
    dict[str, Area]
        Mapping of area name to Area.
    """
    warnings.warn(
        "make_areas() is deprecated and will be removed in a future version. "
        "Use AreasBase instead.",
        DeprecationWarning,
        stacklevel=2,
    )
    return {area: Area(area, bearer) for area in areas}