From df1ce805246c986f5a8a1791419ed8d5b3bc785b Mon Sep 17 00:00:00 2001 From: Miguel Martinez Date: Fri, 20 Feb 2026 13:10:44 +0100 Subject: [PATCH 1/3] fix(migrations): upgrade atlas base image to v1.1.3 Upgrades arigaio/atlas from v1.1.0 to v1.1.3 to address: - CVE-2025-68121 (Critical) - crypto/tls session resumption issue in stdlib go1.25.6 - CVE-2025-61732 (High) - cgo code smuggling via Go/C comment parsing in stdlib go1.25.6 Both CVEs are fixed in Go 1.25.7, which atlas v1.1.3 is built with. Signed-off-by: Miguel Martinez --- app/controlplane/Dockerfile.migrations | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controlplane/Dockerfile.migrations b/app/controlplane/Dockerfile.migrations index 4ad30f3c0..6bd458c20 100644 --- a/app/controlplane/Dockerfile.migrations +++ b/app/controlplane/Dockerfile.migrations @@ -1,9 +1,9 @@ # Container image built by go-releaser that's used to run migrations against the database during deployment # See https://atlasgo.io/guides/deploying/image -# from: arigaio/atlas:latest -# docker run arigaio/atlas@sha256:779e402cb5e93982271474834c4f0a89b5edf714b21dbc1770661e86e68db1ed version -# atlas version v1.1.0 -FROM arigaio/atlas@sha256:779e402cb5e93982271474834c4f0a89b5edf714b21dbc1770661e86e68db1ed as base +# from: arigaio/atlas:1.1.3 +# docker run arigaio/atlas@sha256:f0a0022a34e5ddffb634e75dfece214a86dfc1bb15151927c20cf3e6a84bac76 version +# atlas version v1.1.3 +FROM arigaio/atlas@sha256:f0a0022a34e5ddffb634e75dfece214a86dfc1bb15151927c20cf3e6a84bac76 as base FROM scratch # Update permissions to make it readable by the user From 003c9eda663e7652ddca378cc37319495e2be9fc Mon Sep 17 00:00:00 2001 From: Miguel Martinez Date: Fri, 20 Feb 2026 13:17:44 +0100 Subject: [PATCH 2/3] chore(skills): improve vulnerability-remediation skill Signed-off-by: Miguel Martinez --- .../skills/vulnerability-remediation/SKILL.md | 199 ++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 .claude/skills/vulnerability-remediation/SKILL.md diff --git a/.claude/skills/vulnerability-remediation/SKILL.md b/.claude/skills/vulnerability-remediation/SKILL.md new file mode 100644 index 000000000..9aeb23f68 --- /dev/null +++ b/.claude/skills/vulnerability-remediation/SKILL.md @@ -0,0 +1,199 @@ +--- +name: vulnerability-remediation +description: Reviews vulnerability policy violations for the chainloop project recorded in Chainloop and performs fixes in Dockerfiles or go.mod. Use when asked to fix vulnerabilities, review CVEs, or remediate security issues in chainloop. +--- + +# 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 A** — `get_frameworks_compliance`: +- `project_version_id`: the UUID from Step 1 +- `framework_ids`: `["0ceef195-6900-4166-8407-77eb84954ed3"]` (chainloop-best-practices) + +**Call B** — `list_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: + +```python +import json + +with open('') 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::/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: + ```bash + 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: + ```bash + grype arigaio/atlas: --only-fixed 2>&1 + grype arigaio/atlas: --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: + ```bash + docker pull arigaio/atlas: + docker inspect --format='{{index .RepoDigests 0}}' arigaio/atlas: + ``` +5. Update `app/controlplane/Dockerfile.migrations`: + ```dockerfile + # from: arigaio/atlas: + # docker run arigaio/atlas@sha256: version + # atlas version v + FROM arigaio/atlas@sha256: 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`: + ```bash + go get github.com/foo/bar@ + go mod tidy + ``` +3. Verify with grype: + ```bash + 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: + +```bash +# Before — should show the CVE rows +grype : --only-fixed 2>&1 + +# After — should show header only, no CVE rows +grype : --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: + ```bash + git branch --show-current + ``` + +2. Commit with signoff (no co-author): + ```bash + git add + git commit -s -m "fix(): " + git push -u origin + ``` + +3. Create the PR with `gh pr create`: + ```bash + gh pr create --title "fix(): " --body "$(cat <<'EOF' + ## Summary + + - + - Fixes () and () in + - + EOF + )" + ``` + +## Step 7: Report Results + +Summarise the findings and changes in this format: + +``` +## Vulnerability Remediation Summary + +**Project**: chainloop v +**Requirement**: no-vulnerabilities-high — was: FAIL + +### Fixed + +| CVE | Severity | Package | Old Version | Fix Applied | +|-----|----------|---------|-------------|-------------| +| CVE-XXXX-XXXXX | Critical | | | Upgraded to | + +### Files Changed +- `app/controlplane/Dockerfile.migrations` — atlas vX.X.X → vX.X.X + +### PR + +``` + +## 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 From 1326dd8edc5f6a9a390029150bfd2ea5c53ac864 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Date: Fri, 20 Feb 2026 14:44:04 +0100 Subject: [PATCH 3/3] chore(skills): add allowed-tools to vulnerability-remediation skill Signed-off-by: Miguel Martinez --- .claude/skills/vulnerability-remediation/SKILL.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.claude/skills/vulnerability-remediation/SKILL.md b/.claude/skills/vulnerability-remediation/SKILL.md index 9aeb23f68..33552a505 100644 --- a/.claude/skills/vulnerability-remediation/SKILL.md +++ b/.claude/skills/vulnerability-remediation/SKILL.md @@ -1,6 +1,15 @@ --- name: vulnerability-remediation description: Reviews vulnerability policy violations for the chainloop project recorded in Chainloop and performs fixes in Dockerfiles or go.mod. Use when asked to fix vulnerabilities, review CVEs, or remediate security issues in chainloop. +allowed-tools: + - Bash + - Read + - Edit + - Task + - mcp__claude_ai_Chainloop__list_products_with_versions + - mcp__claude_ai_Chainloop__get_frameworks_compliance + - mcp__claude_ai_Chainloop__list_pieces_of_evidence + - mcp__claude_ai_Chainloop__download_evidence_by_digest --- # Vulnerability Remediation for chainloop