Skip to content

policy

๐Ÿค– AI-Generated Content

This documentation was generated with AI assistance and is still being audited. Some, or potentially a lot, of this information may be inaccurate. Learn more.

flavor.config.policy

FlavorPack launch-time policy: schema, parsing, and merge logic.

Classes

EffectivePolicy

Merged policy: the stricter of package + operator wins per field.

EnforcementMode

Bases: StrEnum

How a policy check violation is handled.

EnforcementPolicy

Per-check enforcement modes. Omitted checks inherit from default.

Functions
mode_for
mode_for(check: str) -> EnforcementMode

Return the enforcement mode for a given check name.

Source code in flavor/config/policy.py
def mode_for(self, check: str) -> EnforcementMode:
    """Return the enforcement mode for a given check name."""
    val = getattr(self, check, None)
    return val if val is not None else self.default

OperatorPolicy

Operator overlay from policy.json.

PackagePolicy

Constraints declared by the package builder in pyproject.toml.

Functions

enforce_policy

enforce_policy(
    policy: EffectivePolicy,
    build_timestamp: int,
    has_sbom: bool,
    key_trusted: bool,
) -> list[str]

Enforce the effective launch policy for the current runtime environment.

Returns a list of warning messages for checks in 'warn' mode. Raises ValueError for checks in 'deny' mode. Checks in 'allow' mode are silently skipped.

Source code in flavor/config/policy.py
def enforce_policy(
    policy: EffectivePolicy,
    build_timestamp: int,
    has_sbom: bool,
    key_trusted: bool,
) -> list[str]:
    """Enforce the effective launch policy for the current runtime environment.

    Returns a list of warning messages for checks in 'warn' mode.
    Raises ValueError for checks in 'deny' mode.
    Checks in 'allow' mode are silently skipped.
    """
    warnings: list[str] = []
    enf = policy.enforcement
    current_platform = get_current_platform()

    # 1. Platform check
    if policy.platforms and current_platform not in policy.platforms:
        _apply_enforcement(
            enf.mode_for("platform_mismatch"),
            f"platform not permitted: {current_platform} not in {policy.platforms}",
            warnings,
        )

    # 2. OS keychain check
    if policy.use_os_keychain:
        _apply_enforcement(
            enf.mode_for("os_keychain"),
            "use_os_keychain is not supported by this launcher",
            warnings,
        )

    # 3. Root / Administrator check
    if policy.refuse_root and is_privileged_user():
        _apply_enforcement(
            enf.mode_for("root_execution"),
            "refused to run as root or Administrator",
            warnings,
        )

    # 4. Age check
    if policy.max_age_days is not None and build_timestamp > 0:
        age_days = int((datetime.now(UTC).timestamp() - build_timestamp) / 86400)
        if age_days > policy.max_age_days:
            _apply_enforcement(
                enf.mode_for("expired_package"),
                f"package is {age_days} days old โ€” policy requires max {policy.max_age_days} days",
                warnings,
            )

    # 5. Environment variable check
    missing = [var for var in policy.require_env if not os.environ.get(var)]
    if missing:
        _apply_enforcement(
            enf.mode_for("missing_env"),
            f"required environment variable not set: {missing[0]}",
            warnings,
        )

    # 6. SBOM check
    if policy.require_sbom and not has_sbom:
        _apply_enforcement(
            enf.mode_for("missing_sbom"),
            "package built without attestation slot โ€” operator policy requires SBOM",
            warnings,
        )

    # 7. Trusted key check
    if policy.require_trusted_key and not key_trusted:
        _apply_enforcement(
            enf.mode_for("untrusted_key"),
            "operator policy requires a trusted signing key โ€” package key is not in the trusted store",
            warnings,
        )

    return warnings

get_current_platform

get_current_platform() -> str

Return the normalized FlavorPack platform string for the current host.

Source code in flavor/config/policy.py
def get_current_platform() -> str:
    """Return the normalized FlavorPack platform string for the current host."""
    if sys.platform.startswith("linux"):
        os_name = "linux"
    elif sys.platform == "darwin":
        os_name = "darwin"
    elif sys.platform.startswith("freebsd"):
        os_name = "freebsd"
    elif sys.platform == "win32":
        os_name = "windows"
    else:
        os_name = sys.platform
    machine = platform.machine().lower()
    arch = "arm64" if machine in ("arm64", "aarch64") else "amd64"
    return f"{os_name}_{arch}"

is_privileged_user

is_privileged_user() -> bool

Return True when the current process is privileged/root.

Source code in flavor/config/policy.py
def is_privileged_user() -> bool:
    """Return True when the current process is privileged/root."""
    try:
        return os.geteuid() == 0  # type: ignore[attr-defined,unused-ignore]
    except AttributeError:
        return False

load_operator_policy

load_operator_policy(
    *, system: bool = True, user: bool = True
) -> OperatorPolicy

Load the operator policy file(s).

System policy is loaded first, then user policy overrides it. If neither file exists, returns a permissive default.

Source code in flavor/config/policy.py
def load_operator_policy(*, system: bool = True, user: bool = True) -> OperatorPolicy:
    """Load the operator policy file(s).

    System policy is loaded first, then user policy overrides it.
    If neither file exists, returns a permissive default.
    """
    merged: dict[str, Any] = {}

    if system:
        system_file = get_policy_file(system=True)
        if system_file.exists():
            merged.update(_load_policy_file(system_file))

    if user:
        user_file = get_policy_file(system=False)
        if user_file.exists():
            user_raw = _load_policy_file(user_file)
            for section, values in user_raw.items():
                if section == "version":
                    continue
                if isinstance(values, dict):
                    merged.setdefault(section, {}).update(values)
                else:
                    merged[section] = values

    return _parse_operator_policy(merged)

merge_policy

merge_policy(
    pkg: PackagePolicy, op: OperatorPolicy
) -> EffectivePolicy

Merge package-declared and operator policies. Stricter always wins.

Source code in flavor/config/policy.py
def merge_policy(pkg: PackagePolicy, op: OperatorPolicy) -> EffectivePolicy:
    """Merge package-declared and operator policies. Stricter always wins."""
    # Platforms: intersection of both non-empty lists
    if pkg.platforms and op.allow_platforms:
        platforms = [p for p in pkg.platforms if p in op.allow_platforms]
    elif op.allow_platforms:
        platforms = list(op.allow_platforms)
    else:
        platforms = list(pkg.platforms)

    refuse_root = pkg.refuse_root or op.refuse_root

    if pkg.max_age_days is not None and op.max_age_days is not None:
        max_age_days: int | None = min(pkg.max_age_days, op.max_age_days)
    elif pkg.max_age_days is not None:
        max_age_days = pkg.max_age_days
    else:
        max_age_days = op.max_age_days

    require_env = list(set(pkg.require_env))

    return EffectivePolicy(
        platforms=platforms,
        refuse_root=refuse_root,
        max_age_days=max_age_days,
        require_env=require_env,
        require_trusted_key=op.require_trusted_key,
        use_os_keychain=op.use_os_keychain,
        require_sbom=op.require_sbom,
        enforcement=op.enforcement,
    )

parse_package_policy

parse_package_policy(raw: dict[str, Any]) -> PackagePolicy

Parse [tool.flavor.policy] dict from pyproject.toml into a PackagePolicy.

Source code in flavor/config/policy.py
def parse_package_policy(raw: dict[str, Any]) -> PackagePolicy:
    """Parse [tool.flavor.policy] dict from pyproject.toml into a PackagePolicy."""
    return PackagePolicy(
        platforms=raw.get("platforms", []),
        refuse_root=bool(raw.get("refuse_root", False)),
        max_age_days=raw.get("max_age_days"),
        require_env=raw.get("require_env", []),
    )