Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions .cargo/audit.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# cargo-audit configuration — supply-chain CVE scanning policy.
#
# cargo-audit auto-reads this file from `.cargo/audit.toml`. Run it locally
# with `just audit`, which uses the exact same flags as the CI `cargo-audit`
# job so local and CI results match.
#
# Failure policy (set via CLI flags in `just audit` and CI, NOT here, because
# cargo-audit's `[output]` config table requires a complete field set):
#
# cargo audit --deny unmaintained --deny unsound
#
# That fails the build on any vulnerability (always denied by default), any
# unmaintained advisory, or any unsound advisory that is NOT explicitly listed
# in `[advisories] ignore` below. A new advisory of these kinds fails CI until
# it is either fixed (bump the offending dependency) or triaged into the ignore
# list with a justification. This is what keeps the policy from being
# "warnings-only".
#
# Yanked crates are reported as informational warnings only, not build
# failures: a plain yanked crate carries no RustSec advisory ID, so it cannot
# be individually justified/ignored here (ignores are keyed by advisory ID).
# Anything genuinely dangerous about a yanked crate surfaces as a separate
# vulnerability / unmaintained / unsound advisory, which IS denied. Currently
# yanked (informational only): core2 0.4.0 (also covered by RUSTSEC-2026-0105
# below) and uds_windows 1.2.0 (Windows-only zbus transport, `cfg(windows)`,
# never compiled on facelock's Linux targets).
#
# Every ignore entry MUST carry an inline justification. Do not blanket-ignore.
# When a fix ships (a dependency bump that drops the advisory), delete the
# ignore rather than leaving it to rot.

[advisories]
ignore = [
# quick-xml 0.39.x — quadratic parse time / unbounded namespace allocation
# DoS. Fixed in >=0.41.0, but our only path to quick-xml is the build-time
# proc-macro `wayland-scanner` (v0.31.10 pins quick-xml ^0.39, so
# `cargo update` cannot lift it). wayland-scanner parses the trusted Wayland
# protocol XML shipped inside the wayland-* crates at compile time; it never
# sees attacker-controlled runtime input, and no quick-xml code runs in the
# auth path or any shipped binary. Revisit when smithay-client-toolkit /
# wayland-scanner ship a release built on quick-xml >=0.41.
"RUSTSEC-2026-0194",
"RUSTSEC-2026-0195",

# core2 0.4.0 — unmaintained (all versions yanked). Transitive via
# image -> ravif -> rav1e -> bitstream-io, i.e. the AVIF *encoder*. facelock
# only decodes camera frames; the AVIF encode path is never exercised at
# runtime. No maintained successor is wired up upstream. Revisit when
# image / rav1e drop the core2 dependency.
"RUSTSEC-2026-0105",

# paste 1.0.15 — unmaintained proc-macro (build-time only). Transitive via
# rav1e. Runs only at compile time and ships no runtime code; rav1e has not
# migrated to a maintained replacement yet. Revisit when rav1e drops paste.
"RUSTSEC-2024-0436",
]
31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,37 @@ jobs:
target/release/libpam_facelock.so
retention-days: 1

cargo-audit:
name: Supply-chain Audit (cargo-audit)
runs-on: ubuntu-latest
container: archlinux:base-devel
# Override the workflow-level -Dwarnings: this job compiles cargo-audit's
# own third-party dependency tree, which we don't control. A future
# warning upstream shouldn't fail this job for reasons unrelated to the
# audit itself. The real build/test/clippy jobs above keep -Dwarnings.
env:
RUSTFLAGS: ""
steps:
- name: Install system dependencies
run: |
pacman -Syu --noconfirm \
git \
rust

- uses: actions/checkout@v6

- name: Cache cargo registry and cargo-audit build
uses: Swatinem/rust-cache@v2

- name: Install cargo-audit
run: cargo install cargo-audit --locked
Comment on lines +90 to +91

# Ignore policy (with justifications) lives in .cargo/audit.toml.
# Deny policy matches `just audit`: fail on any vulnerability (default),
# unmaintained, or unsound advisory that is not explicitly ignored.
- name: Run cargo audit
run: cargo audit --deny unmaintained --deny unsound

tpm-tests:
name: TPM Tests (swtpm)
runs-on: ubuntu-latest
Expand Down
15 changes: 14 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,19 @@ The PAM module (`pam-facelock`) must stay lightweight: **libc, toml, serde, zbus

Each crate has a defined dependency boundary. See `AGENTS.md` for the full table.

### Supply-chain auditing

```bash
just audit # cargo audit --deny unmaintained --deny unsound
```

`just audit` scans the full `Cargo.lock` for RustSec advisories and mirrors the
CI `cargo-audit` job. It fails on any vulnerability, unmaintained, or unsound
advisory that is not explicitly ignored. The ignore list, with a justification
per entry, lives in `.cargo/audit.toml`; add a new entry (with a reason) only
when an advisory is genuinely non-exploitable here and cannot yet be fixed by a
dependency bump. Requires `cargo install cargo-audit --locked`.

## Testing

### Tier 1: Unit tests (no hardware)
Expand Down Expand Up @@ -88,7 +101,7 @@ Only after tiers 3--4 pass. Always keep a root shell open. Start with `sudo` onl
### All checks at once

```bash
just check # runs test + clippy + fmt
just check # runs test + clippy + fmt + audit
```

## Security considerations
Expand Down
42 changes: 21 additions & 21 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,14 @@ fmt-check:
fmt:
cargo fmt --all

# Run all checks (test + lint + format)
check: test lint fmt-check
# Scan the dependency tree for RustSec advisories (mirrors the CI cargo-audit job).
# Ignore policy lives in .cargo/audit.toml; deny policy is set here so CI matches.
# Requires cargo-audit: cargo install cargo-audit --locked
audit:
cargo audit --deny unmaintained --deny unsound

# Run all checks (test + lint + format + audit)
check: test lint fmt-check audit

# Build the PAM test container image (uses host-built release binaries)
_build-test-container: build-release
Expand Down
Loading