skills/chainloop-dev/chainloop/vulnerability-remediation

vulnerability-remediation

SKILL.md

Vulnerability Remediation for chainloop

This skill reviews open vulnerability policy violations recorded in Chainloop for the chainloop project and applies fixes to the affected source files.

Step 1: Find the Latest Project Version

Use list_products_with_versions (no parameters needed — uses the current chainloop org) and locate the Chainloop Community Edition product. Find the chainloop project version entry and note its projectVersionId (UUID).

Step 2: Gather Compliance Results and Evidence in Parallel

Once the projectVersionId is known, make both of these calls at the same time:

Call Aget_frameworks_compliance:

  • project_version_id: the UUID from Step 1
  • framework_ids: ["0ceef195-6900-4166-8407-77eb84954ed3"] (chainloop-best-practices)

Call Blist_pieces_of_evidence:

  • project_name: chainloop
  • project_version_name: the version name from Step 1 (e.g. v1.77.0)
  • latest: true

Parsing the compliance result (Call A)

The response will be large — parse it programmatically using a Bash subagent:

import json

with open('<tool-result-file>') as f:
    raw = json.load(f)
data = json.loads(raw[0]['text'])

for req in data:
    if 'vulnerabilit' in req.get('name', '').lower():
        status = req.get('status', '')
        failed = [e for e in req.get('policyEvaluations', [])
                  if e.get('status') not in ('PASSED', 'SKIPPED')]
        print(f"Requirement: {req['name']} — Status: {status}")
        for e in failed:
            print(f"  FAILED: policy={e['name']} material={e.get('materialName','-')} status={e.get('status','-')}")

This gives you the list of failing material names (e.g. control-plane-migrations-report).

Step 3: Download the SARIF for Each Failing Material

From the list_pieces_of_evidence result (Call B above), find the item whose name matches the failing material name and whose kind is SARIF. Use its digest field directly — no need to decode attestations.

Call download_evidence_by_digest with:

  • digest: the digest of the matching SARIF item
  • download_content: true

The SARIF logicalLocations[].fullyQualifiedName field contains the full image reference, e.g.:

ghcr.io/chainloop-dev/chainloop/control-plane-migrations:v1.77.0@sha256:<digest>:/atlas

The binary path (e.g. /atlas, /app) tells you which binary inside the image is vulnerable.

Step 4: Identify the Fix

4a. Atlas / Migration Dockerfile vulnerabilities

Symptom: SARIF location is /atlas, image is control-plane-migrations

Source file: app/controlplane/Dockerfile.migrations

Fix procedure:

  1. Check the current atlas version in the comment at the top of the Dockerfile (e.g. # atlas version v1.1.0)
  2. Find the latest available version:
    curl -s "https://registry.hub.docker.com/v2/repositories/arigaio/atlas/tags?page_size=20&ordering=last_updated" \
      | python3 -c "import json,sys; [print(t['name']) for t in json.load(sys.stdin)['results'] if t['name'][0].isdigit() and '-' not in t['name']]"
    
  3. Run grype on the current and candidate versions to confirm the CVEs are present then gone:
    grype arigaio/atlas:<current-version> --only-fixed 2>&1
    grype arigaio/atlas:<new-version> --only-fixed 2>&1
    
    A clean run has only the header line and no CVE rows.
  4. Once a clean version is confirmed, pull it and get its digest:
    docker pull arigaio/atlas:<new-version>
    docker inspect --format='{{index .RepoDigests 0}}' arigaio/atlas:<new-version>
    
  5. Update app/controlplane/Dockerfile.migrations:
    # from: arigaio/atlas:<NEW_VERSION>
    # docker run arigaio/atlas@sha256:<NEW_DIGEST> version
    # atlas version v<NEW_VERSION>
    FROM arigaio/atlas@sha256:<NEW_DIGEST> as base
    

4b. Go stdlib / Go module vulnerabilities (backend)

Symptom: SARIF location is a Go binary (e.g. /app, /server), package is stdlib or a Go module

Fix options (in order of preference):

Option A — Upgrade Go version (for stdlib CVEs): Use the upgrading-golang skill to bump the Go version in go.mod and all Dockerfiles.

Option B — Upgrade a specific Go dependency (for third-party modules):

  1. Identify the affected module from the SARIF purls field (e.g. pkg:golang/github.com/foo/bar@v1.2.3)
  2. Update go.mod:
    go get github.com/foo/bar@<fixed-version>
    go mod tidy
    
  3. Verify with grype:
    grype dir:. --only-fixed 2>&1
    

Step 5: Verify the Fix with Grype

Always run grype before and after the change to confirm the CVEs are resolved:

# Before — should show the CVE rows
grype <image>:<current-version> --only-fixed 2>&1

# After — should show header only, no CVE rows
grype <image>:<new-version> --only-fixed 2>&1

A clean run has only the column header line and zero data rows.

Step 6: Commit and Create a PR

  1. Check which branch you are on — do not create a new branch if one already exists:

    git branch --show-current
    
  2. Commit with signoff (no co-author):

    git add <changed-files>
    git commit -s -m "fix(<scope>): <short description of the CVE fix>"
    git push -u origin <current-branch>
    
  3. Create the PR with gh pr create:

    gh pr create --title "fix(<scope>): <short description>" --body "$(cat <<'EOF'
    ## Summary
    
    - <bullet: what was upgraded and why>
    - Fixes <CVE-ID> (<Severity>) and <CVE-ID> (<Severity>) in <package>
    - <brief note on how the fix works, e.g. new version built with Go X.Y.Z>
    EOF
    )"
    

Step 7: Report Results

Summarise the findings and changes in this format:

## Vulnerability Remediation Summary

**Project**: chainloop v<version>
**Requirement**: no-vulnerabilities-high — was: FAIL

### Fixed

| CVE | Severity | Package | Old Version | Fix Applied |
|-----|----------|---------|-------------|-------------|
| CVE-XXXX-XXXXX | Critical | <pkg> | <old> | Upgraded <file> to <new> |

### Files Changed
- `app/controlplane/Dockerfile.migrations` — atlas vX.X.X → vX.X.X

### PR
<GitHub PR URL>

Key Reference Data

Item Value
Chainloop org chainloop
Project name chainloop
chainloop-best-practices framework ID 0ceef195-6900-4166-8407-77eb84954ed3
Continuous-scanning workflow ID c506a425-d307-4a59-9132-659ffd417b57
Migrations Dockerfile app/controlplane/Dockerfile.migrations
Backend go.mod go.mod (root)

Important Notes

  • Always pin Docker images by SHA256 digest, not tag alone
  • For Go stdlib CVEs, upgrading the atlas or golang builder image is usually sufficient — check via grype before touching go.mod
  • Run go mod tidy after any go.mod change
  • The compliance-scanning runs daily, so the policy status will update automatically after the fix is merged and a new image is built
Weekly Installs
16
GitHub Stars
535
First Seen
Mar 1, 2026
Installed on
opencode16
gemini-cli16
codebuddy16
github-copilot16
codex16
kimi-cli16