Architecture
What this is
Falcon is a strict-deserialization typing layer. API surfaces that can deserialize
untrusted input are modeled as Unsafe[Any] in stubs/, and trust decisions are
explicit and reviewable through falcon-secure.
Current API policy
Trusted-input preconditions are explicit through
falcon_secure.trust: TrustedBytes, TrustedBinaryIO, and
TrustedPath.
pickle.loadsrequiresTrustedBytes.cloudpickle.loadsanddill.loadsrequireTrustedBytes.cloudpickle.loadanddill.loadrequireTrustedBinaryIO.joblib.load,pandas.read_pickle,pandas.io.pickle.read_pickle, andtorch.loadrequireTrustedPath.
typing.cast is the typed escape hatch and is intended for intentional policy
exceptions; each call is still governed by falcon-secure tag/reason policy.
# trust: is not a language feature, but a review convention consumed by the
audit command.
Checker/audit mechanics
falcon-secure initwrites checker wiring intopyproject.tomland configuresmypy_path(mypy) orstubPath(pyright) so overlay stubs are applied.strictprofile adds tighter checker checks and selected ruff rules.falcon-secure auditperforms AST scans for cast escape sites, audit tags, trusted-input promotions (trusted_*/verify_*helpers), and semantic gaps such as unsafenumpy.load(..., allow_pickle=True)usage.- CI enforcement is based on checker output plus audit policy configuration
(
allow_tags,deny_tags,require_reason,unknown_tag).
Lean role
lean/ is a formal model of the source-to-sink policy. It is not a proof of full
runtime soundness across CPython, checkers, or all third-party libraries; it
captures the intended invariants behind the stubs.
Limitations
- Not all third-party loader surfaces are trusted-input gated yet.
- Some unsafe configuration flows still need semantic policy checks (for example inherited/injected flags).
disjoint_baseis currently omitted from_pickle.pyifor current typing-tooling constraints.