OSS Security & Correctness Requirements¶
This document is a checklist of security/correctness requirements that OSS CI and release processes enforce or recommend.
It is written as “requirements to implement/maintain”, not as a claim about future features. Where the repo already enforces something, the evidence points to the corresponding workflow/tests. Not every requirement runs on every push/PR—some jobs are conditional (labels, base branch, or workflow_dispatch). See .github/workflows/ci.yml for exact if: conditions.
1) CI correctness gates (baseline)¶
Every PR and mainline change runs the baseline quality gates in the ci job:
- Python lint:
uv run ruff check . - Python formatting check:
uv run ruff format --check . - Python typecheck:
uv run mypy src/akc - Python tests:
uv run pytest
Rust checks run in a separate job with working-directory: rust:
cargo fmt --all -- --checkcargo clippy --all-targets --all-features -- -D warningscargo test --allcargo vet --locked(supply chain) plus an exemptions count guard
Additional jobs on typical PRs include: policy-test (OSPS guardrails script), rust_bwrap, rust_windows, docker_hardening, wasm_lane (matrix), and others—see .github/workflows/ci.yml.
Evidence: .github/workflows/ci.yml
2) Untrusted input handling in CI (least privilege)¶
CI must assume PR code is untrusted. Requirements:
- PR workflows run with least privilege (avoid secrets access; no privileged tokens in the PR job unless explicitly needed).
- Use GitHub Actions
pull_requestcontexts with restrictive permissions. - Avoid patterns that route secrets to untrusted steps.
Evidence: .github/workflows/ci.yml (workflow permissions: default to contents: read); scripts/ci_policy_test.py (invoked by policy-test job)
3) Tenant isolation invariants (security correctness)¶
AKC’s security model requires tenant isolation:
- Every request must carry
tenant_idandrun_id. - Artifacts must be namespaced by tenant and stored under tenant-scoped directories.
- No cross-tenant caching or cross-tenant reads/writes.
CI/release requirements:
- Run sandbox isolation tests, including hardened
bwraplane tests (Linux) and Windows tenant isolation tests. - Treat any failure in tenant isolation tests as a release-blocking correctness/safety failure.
Evidence:
- Security model:
docs/security.md - CI tenant sandbox tests:
.github/workflows/ci.yml(rust_bwrap,rust_windows) - Tenant isolation tests in Rust:
rust/crates/akc_executor/tests/tenant_isolation.rs
4) Execution sandbox posture and enforcement checks¶
Execution must be defense-in-depth and policy-gated:
- Network must be denied unless explicitly allowed by policy and test configuration.
- Command execution must be allowlisted.
- Environment must be scrubbed.
- Filesystem access must be validated and confined by backend (strong on Linux
bwrap, best-effort on native/macOS).
CI/release requirements:
- Ensure sandbox posture tests cover the critical lanes.
- Ensure executor changes include or update the relevant tenant isolation / sandbox regression tests.
Evidence: docs/security.md — compile loop: execution surfaces (dev subprocess vs strong Docker vs Rust), .github/workflows/ci.yml
5) Patch safety and verifier gate requirements¶
Correctness and security require a deterministic verifier gate that can veto promotion:
- The verifier must validate patch format (unified diff headers) and reject suspicious paths:
- absolute paths, traversal (
..), drive prefixes, NUL bytes, and empty/undefined paths. - modifications to internal emitted artifacts (e.g.
.akc/). - When strict, any verifier finding must veto promotion (after tests pass).
CI/release requirements:
- The verifier’s unit tests must be run on every PR (via the baseline
cijob’spytest). - Any change to verifier behavior must include updated tests and evidence artifacts documenting the change.
Evidence:
- Verifier implementation:
src/akc/compile/verifier.py - Verifier unit tests:
tests/unit/test_compile_verifier_unit.py
6) Artifact confinement and “under root” safety¶
Evidence artifacts must be safe to consume and safe to write:
- Artifact write paths must stay under the configured emitter root.
- Tenant scoping must be respected for all artifacts.
- Path traversal/symlink-like escaping must be rejected.
CI/release requirements:
- Run emitter and output contract tests every PR.
- Keep the artifact contract stable and treat changes as schema/boundary updates requiring explicit review.
Evidence:
- Emitter implementation:
src/akc/outputs/emitters.py - Emitter tests:
tests/unit/test_outputs_emitters.py
7) Evidence completeness requirements¶
For each successful compile run, evidence artifacts must be emitted so that a later viewer/auditor can reconstruct what happened:
- A bundle manifest (
manifest.json) that ties together artifacts. - Structured evidence under
.akc/tests/*including stdout/stderr and exit codes where available. - Optional structured verification records under
.akc/verification/*.jsonwhen verifier feedback exists.
CI/release requirements:
- Tests must validate that emission occurs with correct scoping and stable bundle semantics.
Evidence:
- Compile session emission:
src/akc/compile/session.py - Manifest emitter contract:
src/akc/outputs/emitters.py - Path/layout documentation:
docs/artifact-contracts.md
8) Supply-chain hardening and provenance (release processes)¶
Release and extended CI gates should produce verifiable supply-chain evidence:
- Rust integrity checks run in CI (
cargo vet) before relying on Rust artifacts; seerust/supply-chain/config.toml. - Release workflow runs
pip-auditwith CycloneDX output on exported requirements before publishing; installs useuv sync --frozen --extra dev. - SLSA provenance for release subjects is generated via
slsa-framework/slsa-github-generator(generic SLSA3 workflow) in.github/workflows/release.yml, with subjects including Rust binaries and Python wheels/sdists from therust-integrityjob.
CI/release requirements:
- Release workflow modifications must preserve provenance generation where present.
- Treat skipping provenance or vulnerability gates as an explicit, documented exception.
- Note: The default
cijob does not runpip-auditon every PR. Apip-audit+ SBOM step runs in theruntime_mutating_opt_injob (PR labelmutating-runtimeor manualworkflow_dispatch) and always in the release workflow. Contributors can runuv run pip-auditlocally using dev extras.
Evidence:
- Rust supply chain checks:
.github/workflows/ci.yml(cargo vet, exemptions guard) - Python vulnerability scanning:
.github/workflows/ci.yml(runtime_mutating_opt_instep “Security gate”),.github/workflows/release.yml(pip-audit+uv export) - SLSA provenance:
.github/workflows/release.yml(slsa-provenancejob →generator_generic_slsa3.yml)
9) Viewer contract alignment (security boundary)¶
The viewer is read-only: it must not execute patches, run generated code from evidence, call the executor on behalf of the user, or access secrets. Implementation today:
- CLI:
akc view(src/akc/cli/view.py, registered insrc/akc/cli/__init__.py) - Library:
src/akc/viewer/(TUI, static HTML, export bundle) - Tests:
tests/unit/test_viewer_export.py
CI/release requirements:
- Viewer changes should keep read-only semantics; extend tests when adding surfaces that touch filesystem or rendering.
Evidence:
- Viewer non-execution threat model:
docs/security.md - Viewer contract:
docs/viewer-trust-boundary.md docs/viewer.md(user-facing overview)
10) Phase 1 OSS hygiene (OSPS Level 1: security reporting + release hygiene)¶
This phase aligns the repo with OpenSSF OSPS concepts for security reporting and release hygiene:
10.1) Security reporting docs¶
- SECURITY.md defines the private vulnerability disclosure process.
security-insights.ymlprovides a machine-readable, OSPS-aligned summary of security reporting and release hygiene (aligned to the OpenSSF Security Insights schema).- CONTRIBUTING.md points contributors to the security reporting process for security-sensitive bugs.
10.2) CI guardrails for untrusted PRs (least privilege)¶
- All untrusted PR code must run under low-privilege defaults:
- GitHub Actions
pull_requestcontext (notpull_request_target). - Workflow-level permissions remain restrictive (
contents: read). - The
policy-testjob runsscripts/ci_policy_test.py, which statically checks.github/workflows/*.ymlfor: nopull_request_target; nosecrets.*inpull_requestworkflows; no write permissions on PR workflows; artifact uploads on PR workflows only when provenance-related signals appear (slsa-github-generator, attest, cosign, sigstore).
10.3) Branch protection expectations (required checks)¶
Branch protection for default and release branches should require the CI checks that implement baseline hygiene. Exact names appear in GitHub’s UI; typical jobs include:
CI / ciCI / Rust checksCI / Linux bwrap hardened isolationCI / Windows sandboxCI / Docker hardening regression gateCI / WASM lane regression (<os>)(matrix)CI / Policy test (OSPS untrusted PR guardrails)
Add or adjust required checks when new blocking jobs are introduced.
11) WASM policy quick reference (deterministic limits + stable failures)¶
When lane=wasm, policy and regression checks should treat the following as stable contract points:
- Resource limit semantics:
wall_time_msis a real elapsed-time deadline on supported platforms via Wasmtime epoch interruption.cpu_fuelis a first-class deterministic CPU budget:cpu_fuel_budget = clamp(cpu_fuel, 1, 2_000_000_000)- when both are set, timeout and CPU exhaustion remain distinct failure classes.
memory_bytesapplies an explicit Wasmtime linear-memory cap when set.-
stdout_max_bytes/stderr_max_bytesare deterministic in-memory capture caps (default1 MiBeach). -
Machine-readable error envelope:
-
first stderr line is:
AKC_WASM_ERROR code=<CODE> exit_code=<N> message=<TEXT>
-
Stable WASM failure classes (recommended policy keys):
- timeout:
code=WASM_TIMEOUT,exit_code=124 - cpu/fuel exhaustion:
code=WASM_CPU_FUEL_EXHAUSTED,exit_code=137 - memory limit exceeded:
code=WASM_MEMORY_LIMIT_EXCEEDED,exit_code=138 -
unsupported platform capability:
code=WASM_UNSUPPORTED_PLATFORM_CAPABILITY,exit_code=78 -
Platform fail-closed behavior:
- Windows + requested WASM wall-time limit is currently unsupported and must fail with:
WASM_UNSUPPORTED_PLATFORM_CAPABILITY/78
- do not silently downgrade unsupported strict guarantees in policy-enforced runs.
CI/release requirements:
- WASM regression tests must validate deterministic classification for timeout/fuel/memory/capability failures.
- WASM regression tests must validate filesystem contract enforcement, including:
- no implicit filesystem access without
preopen_dirs - write denial on read-only preopens
- write allowance only when
allowed_write_pathsis a subset ofpreopen_dirs - Policy tests should assert code/exit pairs above remain stable across executor changes.
- Policy tests should assert WASM execution context includes backend, network flag, preopen list, limits tuple, and platform capability profile for
executor.run. - Policy tests should assert WASM execution context separately exposes writable preopens and read-only preopens.
- Prod policy tests should assert deny behavior for:
- unsupported strict platform controls
- disallowed preopen path patterns
- disallowed writable preopen path patterns
- network-enabled WASM runs without an explicit exception
- CLI and bridge regression tests should validate that
--sandbox-cpu-fueland protocollimits.cpu_fuelmap to stable failure classification.
Evidence:
- WASM lane implementation:
rust/crates/akc_executor/src/backend/wasm.rs - Exit code constants:
rust/crates/akc_executor/src/lib.rs - Bridge parsing/logging surface:
src/akc/compile/rust_bridge.py - WASM regression tests:
rust/crates/akc_executor/tests/wasm_lane.rs
12) Docker strong hardening requirements and rollout¶
When the CLI uses --sandbox strong, Docker is the default strong lane. OSS security requirements must treat the Docker hardening contract as an explicit, test-backed surface rather than implicit runtime behavior.
Required documented defaults:
- network denied by default
- read-only root filesystem enabled by default
no-new-privilegesenabled by defaultcap-drop ALLenabled by default- non-root user
65532:65532by default /tmpmounted as tmpfs by default- memory cap
1024 MiBby default - PID cap
256by default - stdout/stderr capture cap
2048 KiBper stream by default
Required optional controls:
--docker-user--docker-tmpfs--docker-seccomp-profile--docker-apparmor-profile--docker-ulimit-nofile--docker-ulimit-nproc--docker-cpus
Required fail-closed behavior:
- Docker-only hardening flags must be rejected outside
--sandbox strong. - Docker-only hardening flags must be rejected when the strong lane is fixed to WASM.
- Docker-only hardening flags must be rejected when
autofallback would drop them because Docker is unavailable. - Invalid tmpfs/user/seccomp/AppArmor/ulimit values must fail before container launch.
- Absolute seccomp profile paths must exist and be files.
- AppArmor profiles must fail closed on unsupported hosts.
Required policy surface:
- OPA input for
executor.runin Docker mode must include: - network mode / exception
- read-only rootfs flag
- no-new-privileges flag
- cap-drop-all flag
- user presence and non-root classification
- seccomp/AppArmor profile identifiers
- memory / PID / CPU / ulimit settings
- tmpfs mounts
- Production policy profiles should deny Docker execution when required hardening controls are absent or weakened, including seccomp/AppArmor posture,
/tmptmpfs availability, memory/PID/ulimit ceilings, or network enablement without an explicit exception.
Required rollout stages:
- Audit policy only.
Use
--policy-mode audit_onlyto verify emitted Docker policy context and collect expected denials without blocking merges or releases. - Enforce policy in CI and release branches.
Protected branches and release workflows must run an actual Docker strong compile in
--policy-mode enforceso hardening regressions are release-blocking. - Enforce as default in the production profile.
Production-facing guidance and automation should default to
--sandbox strong --strong-lane-preference dockerwith the prod Rego policy profile in enforce mode.
CI/release requirements:
- Unit tests must validate Docker command assembly and invalid hardening rejection.
- Integration tests must validate runtime behavior for:
- non-root execution
- read-only rootfs denial outside tmpfs
- writable tmpfs path
- network isolation
- CI must run a Docker strong compile against the prod Rego profile so executor/policy drift is caught outside of unit tests (
docker_hardeningjob in.github/workflows/ci.yml; release workflow includes a similar enforced compile). - CI/release branch protection should treat Docker hardening regressions as blocking once the rollout reaches stage 2.
- Documentation in
docs/security.mdanddocs/getting-started.mdmust stay aligned with the implemented defaults and tests.
Evidence:
- Docker executor implementation:
src/akc/compile/executors.py - CLI Docker preflight/validation:
src/akc/cli/compile.py - Docker policy context emission:
src/akc/compile/controller.py - Docker unit tests:
tests/unit/test_compile_executors.py,tests/unit/test_cli_compile.py - Docker integration tests:
tests/integration/test_docker_runtime_hardening.py