Trust model¶
This page expands the trust model briefly described in SECURITY.md. Read both.
What this wrapper guarantees¶
- Hash-pinned upstream fetch.
linpeas-pin.jsonrecords an SRI hash for the upstreamlinpeas.shasset. Nix refuses to build on hash mismatch — a swapped or corrupted upstream asset fails the build. - Pin-shape validation at flake eval.
flake.nixasserts thatpin.versionmatches[0-9]{8}-[0-9a-f]{7,40}and thatpin.urlstarts withhttps://github.com/peass-ng/PEASS-ng/releases/download/. An attacker-controlled pin file cannot smuggle arbitrary URLs into the derivation. - GitHub Releases API digest cross-check.
scripts/bump-linpeas.shreads the upstream release-asset.digestfield over the API and refuses to bump if it is missing, non-sha256:, or does not match the downloaded file. This is not silent on missing data — bump aborts. - Asset URL prefix validation. Same script refuses to record any asset URL outside the expected
peass-ng/PEASS-ng/releases/download/prefix. - Daily upstream parity check.
verify-latest-release.ymlre-fetches the pinnedlinpeas.shdaily and re-checks the SRI hash. Detects upstream tag replacement (intentional or compromised). - SLSA build-provenance + SBOM attestations. Each release attaches build-provenance attestations binding the pin file, the bundle, and the per-arch OCI images to the
release-on-bump.ymlworkflow run, plus SPDX-JSON SBOMs (bundle + per-arch images) generated byanchore/sbom-actionand attested viaactions/attest-sbom. Verifiable withgh attestation verify— see Verification.
What this wrapper does not guarantee¶
- Content trust on upstream
linpeas.sh. Upstream PEASS-ng ships no GPG, cosign, or SLSA signatures. The SRI hash binds you to some upstream asset, but it cannot prove that upstream's release is benign. If upstream is compromised, this wrapper will faithfully ship the compromise. - Reproducibility of upstream. The wrapper is reproducible. The wrapped script is whatever upstream chose to publish.
- Site-level signing. The Pages site you are reading is documentation, not a verifiable artifact. Do not treat dashboard text as a substitute for
gh attestation verify.
Auto-merge surface¶
Three automations may auto-merge PRs into main when CI passes:
update-linpeas.yml— daily 09:00 UTC pin bumps. Opens a PR authored bygithub-actions[bot], gated by all required CI checks, auto-merged on green.update-flake-lock.yml— weekly nixpkgs input bump. Split into acontents: readcompute-lockjob (runsnix flake update) and apush-and-mergejob that mints alinpeas-flake-bumperGitHub App installation token and uses only GitHub-owned action SHAs. The third-partyDeterminateSystems/update-flake-lockaction was removed so the bump credential never enters a third-party action's env. Same CI gating.- Renovate — Friday batch for GitHub Action SHA pins, the pinned Nix installer version, and tracked flake inputs (
nixpkgsstable branch,cachix/git-hooks.nix). All PRs honor a non-emptyminimumReleaseAge(7 days) and per-managerautomergescopes; therenovate-invariantsCI lint enforces both. Same gating.
A compromise of the linpeas-flake-bumper GitHub App installation token used by update-linpeas.yml would let an attacker open a PR with arbitrary changes. The App is installed only on this repository with Contents: Read and write + Pull requests: Read and write permissions; the installation token is minted per job, lives one hour, and revokes at job end. The auto-merge bot would still gate on CI — so any malicious change would have to also pass all required checks (build, smoke, attestation re-verify, SRI cross-check). See docs/security/repo-config.md for the full credential model.
See SECURITY.md for the secret rotation policy.
Currently pinned¶
| Field | Value |
|---|---|
| Pin version | 20260510-cd4bd619 |
| Pin URL | https://github.com/peass-ng/PEASS-ng/releases/download/20260510-cd4bd619/linpeas.sh |
| Upstream latest | 20260510-cd4bd619 |
| Drift | 0 days |
| Last parity check | success (2026-05-19T13:07:58Z) |
Bump credentials blast-radius¶
- Bump workflows authenticate as the
linpeas-flake-bumperGitHub App, not as a PAT. The App is installed only onrvenutolo/linPEAS-flakewithContents: Read and write+Pull requests: Read and writepermissions (Metadata: Readis implicit). NoWorkflowspermission. Switching back to any PAT-based flow is a regression — web-flow signing of RESTPUT /contentsrequires an App installation token, empirically confirmed (plan 04). - Storage:
vars.BUMP_APP_CLIENT_ID— public, GitHub App Client ID (e.g.Iv23...). Preferred over App ID (numeric) per theactions/create-github-app-tokenv3 deprecation.secrets.BUMP_APP_PRIVATE_KEY— App's PEM private key. Rotate on suspected compromise; no forced cadence.- Tokens minted via
actions/create-github-app-tokenare scoped to one job, valid one hour, and revoked at job end. They live only as${{ steps.app-token.outputs.token }}passed viaGH_TOKEN. Never reach.git/config; there must never be agit pushusing them. Commits land via RESTPUT /repos/{owner}/{repo}/contents/{path}→ web-flow-signed by GitHub. BUMP_APP_PRIVATE_KEYonly enters env inpush-and-mergejobs, nevercompute-pin/compute-lock. Those compute jobs must remainpermissions: contents: read, must not reference the secret, and must keep untrusted Nix actions inside their own boundary.docs/security/required-checks.mdmirrors theprotect-mainbranch ruleset's required-check set. Update in same change as GitHub-side list changes.- No
paths:/paths-ignore:filter on any workflow listed indocs/security/required-checks.md. Enforced byrequired-checks-no-pathsCI job.
PR-triggered workflow secret allowlist¶
PR-triggered workflows (on: pull_request or on: pull_request_target) MUST NOT reference any secrets.* other than secrets.GITHUB_TOKEN. Enforced by scripts/check-pr-workflows-no-secrets.sh via pr-workflows-no-secrets required CI job.
Exception for a non-GITHUB_TOKEN secret requires documenting here BEFORE relaxing the script.
harden-runner¶
step-security/harden-runner is the first step in every job in every workflow. egress-policy: audit.
- Do not remove from any job.
- Keep as first step, before
actions/checkout,cachix/install-nix-action, or any network step. eBPF monitor must install before any I/O. - Do not add to composite actions — caller job already has it.