Skip to content

Security: adpena/molt

Security

docs/SECURITY.md

Molt Security & Hardening

Security claims apply to an explicitly verified target, backend, runtime profile, Python version and host configuration. The public stable contract and release acceptance matrix own the release obligations. Implemented policy and available audit tools alone do not establish those obligations.

Capability and host boundaries

The capability contract owns permission resolution and native and WASM host checks. Build and run default to the generated ambientless tier; explicit grants are resolved through that same policy. Capability checks apply at the operations that implement them. They do not isolate arbitrary native code, foreign extensions or host callbacks from the authority of their process.

Filesystem permission tokens authorize access. Path confinement requires the virtual mount or host adapter described by the capability contract; a path list reduced to a token does not establish confinement. WASM isolation depends on the selected engine and admitted host imports. An embedding host is responsible for the authority and validation of its callbacks.

Memory, extension and resource boundaries

Rust ownership, collection checks and object-layout invariants are part of the implementation. Unsafe Rust, FFI, allocator and generated-code paths require verification at their actual consumers. No blanket memory-safety or audited-unsafe claim follows from the implementation language.

Molt supplies a maintained runtime C API and a bounded Python.h source facade. The extension ABI contract separates source recompilation, stable ABI declarations and CPython binary compatibility. Header or symbol coverage alone does not prove extension execution, lifetime safety or package support.

Resource controls describes the configuration and tracker API, including incomplete allocation coverage and independent thread-local budgets. Complete memory, time, allocation, recursion and operation-size enforcement remains V1-19 release work. Configuration is not evidence of an enforced aggregate budget. A deployment requiring hard limits must establish those limits through its operating system, engine or host.

Developer and compiler RSS guards supervise development subprocesses. Their accounting, cleanup and costs belong to that apparatus; they do not establish resource limits in an emitted user binary. Runtime enforcement must be qualified on the actual native and WASM execution cells.

Supply chain and reproducibility

Use the selected lockfiles and toolchain custody contract for dependency and executable admission. Locking dependencies does not establish signer identity or prevent vulnerabilities in admitted code. Capability-manifest digests and package checksums establish integrity only within their declared coverage; authenticity requires the release trust policy and validated signatures.

Dependencies, toolchains and Actions move only to releases that have been public for at least 7 days, so a compromised release has time to be found and withdrawn first. A release that fixes a published advisory moves at once. The release-age rule describes the resolver settings and tools that enforce it.

The Python tooling floor for virtualenv is 21.14.13, the first fix for GHSA-cx6f-vjhg-g3cc. Its bash activation script escapes prompt text even when prompt expansion is initially disabled. The existing exact release-age record admits that fix until it ages out on 2026-10-29; the persistent minimum remains after canonical pruning. tools/pin_freshness.py --audit checks the realized lock graph against advisories. An installed environment requires its own admission against that lock.

The Rust lock graphs use ctutils 0.4.4 or later for the constant-time primitives affected by RUSTSEC-2026-0385. tools/cargo_lock_audit.py prepares every locked workspace before checking them offline against one shared advisory snapshot. Failed checks retain advisory IDs, upgrade guidance and command diagnostics in their existing report.

The packaging contract owns immutable candidate assembly and provenance. The release workflow builds independent native and runtime generations and passes them to candidate assembly. Reproducibility requires their actual comparison and the complete release gates to pass for the selected source and toolchain. It is not an unconditional bit-identical-output promise.

Development secret gate

The local pre-commit hook runs tools/secret_guard.py --staged. It reads added lines from the entire selected Git index, including when invoked from a nested directory; unstaged file contents do not replace those inputs. Its fixed diff transport disables external diff drivers and text conversion. Malformed or incomplete hunks fail rather than accepting a partial scan.

The gate recognizes private-key headers, a finite set of provider signatures, bearer values and sensitive literal assignments. Source expressions are not literal credentials. Diagnostics and the optional security event contain only paths, line numbers and rule names or counts, never matched values. The existing exact-line secret-guard: allow marker and vendored RustPython path exemption remain explicit review-sensitive exceptions.

The generated intrinsic and WASM symbol maps may contain token in public identifiers. In those three projections, the generic assignment check admits only complete quoted identifier map entries whose value equals the key, or whose key and value differ solely by the fixed molt_ namespace. This rule does not admit unrelated values, assignments or concatenated expressions; provider and private-key detection remain independent. It trusts the exact public naming relation, without exempting the containing file.

The ABI declaration and public surface snapshot also use the field token for public names. Only the reviewed literals molt.object_callargs_v1 and molt.pyinit_module_v1 are admitted under that exact key in runtime/native_callable_abi.toml and config/public_contract_v1.surface.json. Every other assignment and independent signature on the line is still scanned. New literals require explicit security-policy review; editing the ABI registry cannot enroll an exception.

This line heuristic is not a complete language parser or a guarantee that no secrets exist. Multiline, computed, escaped and newly introduced credential formats need separate coverage. It requires no network, external detector or emitted-guest instrumentation. Broader security qualification remains in the release findings.

Verification

Differential tests use CPython as the semantic oracle. They must exercise the actual compiled consumer and compare observable behavior; they do not by themselves prove absence of security defects.

tools/runtime_safety.py provides sanitizer, Miri and fuzzing commands. The sanitizer workflow configures ASan and Miri lanes; its ASan runs disable leak detection and its TSan lane is unwired. The proof plan selects dependency and audit obligations. A configured command counts as evidence only after it passes with its exact source, toolchain, target and inputs. Unsupported or unexecuted cells remain open in the release findings.

Reporting a vulnerability

Please report vulnerabilities privately to the project owner, @adpena on GitHub, rather than opening a public issue. The project aims to acknowledge a report within 24 hours and provide a fix within 7 days; these are response goals, not a guaranteed remediation deadline.

There aren't any published security advisories