Skip to content

CI hardening: pin third-party actions, scope sbom.yml permissions, clear the reusable-workflow TODO #30

Description

@imran-siddique

Went through every workflow in the org after the round of coding-agent CI disclosures. The headline is good: nothing stores a secret beyond GITHUB_TOKEN, publishing is all OIDC trusted publishing, both pull_request_target workflows avoid checking out PR head, and every write-capable workflow triggers on push to main, tags, releases or schedule. There is no untrusted-input path into a privileged job.

Three things I would still tighten. None of them is a live exposure, they are all "if an upstream action gets compromised, how much does it get".

1. anchore/sbom-action@v0 runs unpinned in a job with id-token: write.

sbom.yml in cmcp, ca2a and trace-spec sets contents: write and id-token: write at the top level, then calls a third-party action on a floating major tag. A floating tag means whoever controls that tag controls what runs, and here what runs can mint an OIDC token and write to the repo. Unlikely, and it is the single worst case in the org, so it should be a SHA.

2. Action pinning is inconsistent generally.

Some workflows pin to a full SHA with a comment explaining why, which is exactly right. Others use actions/checkout@v7, actions/setup-python@v7, actions/upload-artifact@v7. First-party actions are a much smaller worry than third party, so I would not treat this as urgent, but we run Scorecard in every repo and it grades this, so we are marking ourselves down for something we half-do already.

Suggest: pin all third-party actions to SHA, decide one way or the other on first-party, and write the decision down so it stops drifting per repo.

3. reusable-python-security.yml has a TODO that shipped.

- uses: actions/checkout@v4                 # TODO: pin to commit SHA before merge

It is a reusable workflow, so it propagates to whatever calls it. Also v4 while everything else is on v7.

4. Minor: scope the permissions down in sbom.yml.

contents: write and id-token: write are set at file level, so every job gets both. Only the job that needs them should have them.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions