Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the DevGuard GitHub Actions workflow suite to add Nix-based OCI image build pipelines and to streamline “full” scanning orchestration, while also standardizing the DevGuard scanner container reference.
Changes:
- Switch DevGuard scanner workflow steps from
ghcr.io/.../scanner:main-latestto:mainacross existing workflows. - Refactor the existing
full.ymlpipeline to call a new reusablecode-scanning.ymlworkflow (which fans out to SAST/secret/IaC/SCA). - Add new Nix workflows for building OCI images (
build-nix-image.yml) and “full” Nix pipelines (full-with-nix.yml,full-nix.yml), plus container lifecycle wrappers.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| .github/workflows/static-application-security-testing.yml | Updates scanner container ref to :main. |
| .github/workflows/software-composition-analysis.yml | Updates scanner container ref to :main. |
| .github/workflows/sign.yml | Updates scanner container ref to :main. |
| .github/workflows/secret-scanning.yml | Updates scanner container ref to :main. |
| .github/workflows/iac.yml | Updates scanner container ref to :main. |
| .github/workflows/full.yml | Replaces individual scanning job calls with a single call-code-scanning job. |
| .github/workflows/full-with-nix.yml | Introduces a single-arch “full” Nix pipeline that composes scanning/build/scan/deploy/sign/attest. |
| .github/workflows/full-nix.yml | Introduces a multi-arch Nix pipeline with per-arch build/scan/deploy plus manifest creation. |
| .github/workflows/deploy.yml | Adds an artifact-suffix input and updates scanner container ref to :main; removes “branch-latest” push step. |
| .github/workflows/dependency-risk-identification.yml | Updates scanner container ref to :main. |
| .github/workflows/container-scanning.yml | Updates scanner container ref to :main. |
| .github/workflows/container-lifecycle.yml | Adds a new lifecycle workflow combining build + scan + deploy + sign + attest. |
| .github/workflows/container-lifecycle-nix.yml | Adds a Nix-based lifecycle workflow combining Nix build + scan + deploy + sign + attest. |
| .github/workflows/code-scanning.yml | New reusable workflow to orchestrate secret scanning, SAST, IaC scanning, and SCA. |
| .github/workflows/code-risk-identification.yml | Updates scanner container ref to :main. |
| .github/workflows/build-nix-image.yml | New reusable workflow that builds an OCI image via Nix, emits tag/digest/PURL artifacts, and optionally pushes to a Nix cache. |
| .github/workflows/build-image.yml | Updates In-Toto scanner container ref to :main. |
| .github/workflows/attest.yml | Updates scanner container ref to :main for SBOM/VeX/SARIF/provenance attest steps. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| image-suffix: | ||
| type: string | ||
| required: false | ||
| default: 'container' | ||
| description: "The name of the artifact you are building. This is useful when a single pipeline builds more than a single artifact like a container with a shell inside and one without. If you build a single artifact - leave it empty." | ||
| artifact-suffix: | ||
| type: string | ||
| required: false | ||
| default: '' | ||
| description: "Suffix used to look up build artifacts by name. Defaults to image-suffix when not set." |
There was a problem hiding this comment.
artifact-suffix is defined but never used when downloading artifacts (the workflow still hard-codes ${{ inputs.image-suffix }} in artifact names). Either wire artifact-suffix into the artifact name: fields (and default it to inputs.image-suffix when empty) or remove the input to avoid confusing callers.
| jobs: | ||
| call-code-scanning: | ||
| uses: l3montree-dev/devguard-action/.github/workflows/code-scanning.yml@main | ||
| with: | ||
| asset-name: ${{ inputs.asset-name }} | ||
| api-url: ${{ inputs.api-url }} | ||
| path: ${{ inputs.path }} | ||
| web-ui: ${{ inputs.web-ui }} | ||
| fail-on-risk: ${{ inputs.fail-on-risk }} | ||
| fail-on-cvss: ${{ inputs.fail-on-cvss }} | ||
| continue-on-open-code-risk: ${{ inputs.continue-on-open-code-risk }} | ||
| secrets: | ||
| devguard-token: ${{ secrets.devguard-token }} | ||
|
|
||
| build-image: | ||
| uses: l3montree-dev/devguard-action/.github/workflows/build-nix-image.yml@main | ||
| permissions: | ||
| contents: read | ||
| with: | ||
| nix-target: ${{ inputs.nix-target }} | ||
| image-name: ${{ inputs.image-name }} | ||
| artifact-name-suffix: ${{ inputs.artifact-name-suffix }} | ||
| asset-name: ${{ inputs.asset-name }} | ||
| api-url: ${{ inputs.api-url }} | ||
| secrets: | ||
| devguard-token: ${{ secrets.devguard-token }} | ||
|
|
||
| container-scanning: | ||
| uses: l3montree-dev/devguard-action/.github/workflows/container-scanning.yml@main | ||
| permissions: |
There was a problem hiding this comment.
This reusable workflow calls other workflows via l3montree-dev/devguard-action/...@main. When a consumer pins full-with-nix.yml to a tag/SHA, these internal calls will still resolve to main, which breaks reproducibility and can introduce unexpected behavior. Prefer uses: ./.github/workflows/... so the whole pipeline runs from the same ref as the entry workflow (or at least use the same ref as the caller).
| jobs: | ||
| build-amd64: | ||
| uses: l3montree-dev/devguard-action/.github/workflows/build-nix-image.yml@nix | ||
| permissions: | ||
| contents: read | ||
| with: | ||
| nix-target: ${{ inputs.nix-target-amd64 }} | ||
| image-name: ${{ inputs.image-name }} | ||
| artifact-name-suffix: ${{ inputs.artifact-name-suffix }}-amd64 | ||
| asset-name: ${{ inputs.asset-name }} | ||
| api-url: ${{ inputs.api-url }} | ||
| arch: amd64 | ||
| runner: ${{ inputs.runner-amd64 }} | ||
| nix-cache-substituter: ${{ inputs.nix-cache-substituter }} | ||
| nix-cache-public-key: ${{ inputs.nix-cache-public-key }} | ||
| nix-cache-s3-endpoint: ${{ inputs.nix-cache-s3-endpoint }} | ||
| nix-cache-s3-bucket: ${{ inputs.nix-cache-s3-bucket }} | ||
| nix-cache-region: ${{ inputs.nix-cache-region }} | ||
| secrets: | ||
| devguard-token: ${{ secrets.devguard-token }} | ||
| nix-cache-secret-key: ${{ secrets.nix-cache-secret-key }} | ||
| nix-cache-aws-access-key-id: ${{ secrets.nix-cache-aws-access-key-id }} | ||
| nix-cache-aws-secret-access-key: ${{ secrets.nix-cache-aws-secret-access-key }} | ||
|
|
||
| build-arm64: | ||
| uses: l3montree-dev/devguard-action/.github/workflows/build-nix-image.yml@nix | ||
| permissions: |
There was a problem hiding this comment.
full-nix.yml references sub-workflows using l3montree-dev/devguard-action/...@nix (a branch ref). This makes runs non-deterministic and can unexpectedly change behavior without the consumer updating their pinned version. Consider using local ./.github/workflows/... references (preferred) or pinning to a release tag/SHA.
| - name: Write Nix cache secret key | ||
| if: ${{ inputs.nix-cache-s3-endpoint != '' }} | ||
| run: | | ||
| echo "${{ secrets.nix-cache-secret-key }}" > /tmp/nix-cache-priv-key.pem | ||
|
|
There was a problem hiding this comment.
The Nix cache private key is written to /tmp/nix-cache-priv-key.pem without setting restrictive permissions, and the step runs whenever nix-cache-s3-endpoint is set even if the secret key is empty. Consider validating required secrets when pushing is enabled and chmod 600 the key file (and optionally delete it after use) to reduce risk and avoid hard-to-debug failures.
| jobs: | ||
| build-amd64: | ||
| uses: l3montree-dev/devguard-action/.github/workflows/build-nix-image.yml@nix | ||
| permissions: | ||
| contents: read | ||
| with: | ||
| nix-target: ${{ inputs.nix-target-amd64 }} | ||
| image-name: ${{ inputs.image-name }} | ||
| artifact-name-suffix: ${{ inputs.artifact-name-suffix }}-amd64 | ||
| asset-name: ${{ inputs.asset-name }} | ||
| api-url: ${{ inputs.api-url }} | ||
| arch: amd64 | ||
| runner: ${{ inputs.runner-amd64 }} |
There was a problem hiding this comment.
Despite being named “Full Nix Multi-Arch Pipeline”, this workflow does not run the code scanning suite (SAST/secret scanning/IaC/SCA) that full.yml and full-with-nix.yml include via code-scanning.yml. If the intent is feature-parity with the existing “full” pipeline, add a call-code-scanning job and include it in the needs: for deploy/sign/attest so security gates are applied consistently.
No description provided.