Skip to content

ci: pinned actions, least-privilege token, secret scan - #492

Open
SashaMIT wants to merge 3 commits into
mainfrom
roadmap/BASE-SEC-01-secret-scan
Open

SashaMIT wants to merge 3 commits into
mainfrom
roadmap/BASE-SEC-01-secret-scan

Conversation

@SashaMIT

Copy link
Copy Markdown
Contributor

Hardens the CI supply chain: pinned actions, a read-only default token, and a secret scan.

What changes

  • Pinned actions: every uses: is pinned to the same version by commit SHA (tag kept as a comment), plus a job that rejects unpinned ones.
  • Least privilege: GITHUB_TOKEN is read-only by default, with write scopes granted per job where a workflow needs them. Checkout no longer persists credentials.
  • Secret scan: gitleaks 8.30.1, checksum-pinned, scans the working tree plus the commits each push or pull request adds. Allow-list entries need a stated reason. The one known false positive, a redaction-test fixture, has an inline marker so it moves with the code.

Dependency auditing and release SBOM/provenance steps aren't part of this PR; they come with the dependency and release-build work.

Impact

  • No runtime or product change.
  • Workflows run the same action versions, now pinned.
  • The only source edit is a trailing comment on one test line; rustfmt is clean.

Evidence

  • gitleaks with the shared configuration: 0 findings on this branch.
  • Allow-list check: 0 entries without a reason. Pinned-actions check: 50 uses, 0 unpinned.

— agent:cursor/elacity-web (opened via SashaMIT)

assurance and others added 3 commits October 26, 2026 00:57
…npinned uses

Every remote action reference now names a full 40-hex commit SHA with its release tag in a
trailing comment (35 references pinned, resolved with git ls-remote; peeled tags for
annotated tags). The SHA is the commit the tag points at today, so the code that runs is
unchanged. A mutable tag lets whoever controls the upstream tag change the code that runs
with this repository's token and secrets.

New supply-chain workflow job actions-pinned runs .github/scripts/check-actions-pinned.sh,
which fails on any uses: that is not a full SHA (local ./ actions and docker://...@sha256
digests are allowed).

Also corrects four trailing comments in release-package.yml: actions/upload-artifact@330a01c4
is the v5.0.0 commit, not v4 (comment-only, no behaviour change). The three existing
dtolnay/rust-toolchain@7e38f4b4 pins are left as they are (an upstream master merge commit,
verified to be in the upstream history; the toolchain comes from with: toolchain).

Backlog: BASE-SEC-09 (P3-SUP F10, P4-RV-SUP SU-11).
…d checkout credentials

Every workflow now declares a top-level permissions block of contents: read; a job that needs
more widens it on the job itself with a one-line reason. Jobs that ran on the repository's
default token scope (possibly read-write) now get read-only. 7 checkout step(s) set
persist-credentials: false so the token is not left in .git/config for later steps,
build tools or uploaded source to pick up; none of those jobs push with git.

Backlog: BASE-SEC-09 (P3-SUP F10, P4-RV-SUP SU-11).
Adds the secret-scan job to the supply-chain workflow: gitleaks 8.30.1
(checksum-pinned) over the working tree and over the commits each push
or pull request adds, with the shared Elacity rules in .gitleaks.toml.
Allow-list entries must state a reason (checked by
.github/scripts/check-gitleaks-allowlist.py). The one known false
positive, a redaction-test fixture, carries an inline marker so it moves
with the code instead of a line-number fingerprint.

Taken from the tested SEC-03 change without its dependency-audit job and
release SBOM/attestation steps; those land with the dependency and
release-build work.

Agent: agent:cursor/elacity-web
Roadmap-Item: BASE-SEC-01
Co-authored-by: Cursor <cursoragent@cursor.com>
@andersalm

Copy link
Copy Markdown
Contributor

Sash, I compared this PR with develop. My suggestion: keep it unmerged until 0.8.0-alpha.25 is signed, and rebuild it from develop as a draft PR. You can start the rebuild now. (OMP, for Anders)

This PR targets main. Work lands on develop first, and main changes only at a release. The workflows it edits are also the workflows that qualify the 0.8.0 candidate (#93), so they stay unchanged until the signing is done. If you need it sooner, say so here and we agree a plan with Anders.

The three failed jobs on 2ba4a6dab (run 40219246264) are a network problem, not a problem in this change. Each job timed out while it downloaded Kubo from dist.ipfs.tech. Main still downloads Kubo from there (.github/workflows/ci.yml, components.json, scripts/seed-kubo-cache.sh). On develop, scripts/ci-kubo-cache.py and scripts/seed-kubo-cache.sh read the GitHub release URLs in scripts/release-upstream-recipes.json. dist.ipfs.tech also timed out from our Mac at 20:12Z.

Develop already has most of this PR:

  • Pinned actions: your check-actions-pinned.sh finds 109 uses: references on develop and 0 unpinned. Also, test_ci_actions_and_sccache_release_are_immutable in scripts/ci-release-policy-test.py already fails on a mutable action in ci.yml, release-package.yml and the cache action. It does not read canary-holder-linux.yml. I suggest that you extend that test to every workflow file, so one check owns this rule.
  • Read-only token: each of the three workflows on develop sets permissions: contents: read at the top. 14 of the 23 checkouts set persist-credentials: false. The other 9 are in ci.yml.
  • Version comments: the release-package.yml edit here changes only comments. Develop uses the same upload-artifact SHA with two comments (# v4 7 times, # v5 12 times) and one older SHA. The rebuilt PR can give each SHA one comment.

The rebuilt PR then needs these changes:

  1. The gitleaks job and the allow-list reason check. With this PR's .gitleaks.toml, gitleaks 8.30.1 finds 3 hits on develop's tree. All three are redaction-test fixtures under the elacity-uri-embedded-password rule: elastos/crates/elastos-vz/src/bin/browser-vz-engine-supervisor.rs:6964 (the line you already marked), scripts/ci-release-policy-test.py:3410 and elastos/crates/elastos-server/src/update_controller/tests.rs:1113.
  2. The did:key and secret_type allow-list entries use regexTarget = "line". A line that holds one of them then also hides any other generic-rule finding on that line. Please match the value instead of the line, and add a negative test: a fixture line with a did:key and a fake token still fails the scan.
  3. persist-credentials: false on the 9 other checkouts in ci.yml.
  4. In supply-chain.yml, the push trigger names develop instead of main, so the scan also runs when develop moves.

#311 holds this CI work (its decision D2 turned on GitHub secret scanning and push protection on 11 Oct), and nobody is assigned to it yet. Please link the rebuilt PR there and take this part. When the PR leaves draft, I request Irzhy's review of the token and workflow changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants