Skip to content

Commit 4f4df03

Browse files
committed
Add agent-executable workflow docs for CVE fixes
CVE workflow docs and commit templates for AI agents and human devs. Signed-off-by: Daniel Farrell <[email protected]>
1 parent 1a7c7ee commit 4f4df03

File tree

3 files changed

+359
-0
lines changed

3 files changed

+359
-0
lines changed

.agents/commit-templates.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Commit Message Templates
2+
3+
## Rules
4+
5+
- Imperative mood (Add, Fix, Update, not Added/Fixed/Updated)
6+
- Subject ≤50 chars, body lines ≤72 chars
7+
- Always sign-off: `git commit -s`
8+
9+
## Version Bumps
10+
11+
```text
12+
Bump <package> from <old-version> to <new-version>
13+
```
14+
15+
## CVE Fixes
16+
17+
**Single CVE:**
18+
```text
19+
Bump <abbreviated-package> for <CVE-ID>
20+
21+
Full package: <full-package-path>
22+
```
23+
24+
**Multiple CVEs (one package update):**
25+
26+
Use "for CVEs" in subject to stay ≤50 chars, list all in body.
27+
28+
```text
29+
Bump <abbreviated-package> for CVEs
30+
31+
Full package: <full-package-path>
32+
Fixes: <CVE-ID-1>, <CVE-ID-2>
33+
```
34+
35+
**Package abbreviations:**
36+
- `github.com/docker/docker``docker/docker`
37+
- `golang.org/x/oauth2``x/oauth2`
38+
- `helm.sh/helm/v3``helm/v3`
39+
- Keep `k8s.io/` prefix
40+
41+
**Examples:**
42+
```text
43+
Bump docker/docker for GHSA-4vq8-7jfc-9cvp
44+
45+
Full package: github.com/docker/docker
46+
```
47+
48+
```text
49+
Bump helm/v3 for CVEs
50+
51+
Full package: helm.sh/helm/v3
52+
Fixes: GHSA-f9f8-9pmf-xv68, GHSA-9h84-qmv7-982p
53+
```
54+
55+
## Code Changes
56+
57+
```text
58+
Add <feature>
59+
Fix <bug>
60+
Update <component>
61+
Remove <deprecated-feature>
62+
```

.agents/workflows/cve-fix.md

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
#### Fixing CVEs
2+
3+
**All commands should be run from the repository root directory.**
4+
5+
**Before starting, user must:**
6+
7+
Install grype:
8+
```bash
9+
grype version || curl -sSfL https://get.anchore.io/grype | sudo sh -s -- -b /usr/local/bin
10+
```
11+
12+
Fetch latest changes:
13+
```bash
14+
git fetch
15+
```
16+
17+
##### 0. Update Vulnerability Database
18+
19+
```bash
20+
grype db update
21+
```
22+
23+
##### 1. Update Branch and Create Fix Branch
24+
25+
```bash
26+
# Switch to target branch and update to latest
27+
git checkout release-0.X
28+
git merge --ff-only origin/release-0.X
29+
30+
# Create fix branch (add -v2, -v3 etc if branch exists; don't delete old versions)
31+
git checkout -b fix-0.X-cves-YYYY-MM-DD
32+
```
33+
34+
Replace `0.X`: `release-0.21``0.21`, `devel``devel`.
35+
36+
One commit per package (may fix multiple CVEs), one PR total.
37+
38+
##### 2. Scan
39+
40+
```bash
41+
grype . --config .grype.yaml -o table
42+
```
43+
44+
Ignore warning "no explicit name and version provided".
45+
46+
For each CVE, note:
47+
- Package (**NAME**)
48+
- Version (**FIXED-IN**)
49+
- CVE ID (**VULNERABILITY**)
50+
51+
**Note**: Same package may appear multiple times with different versions (e.g., quic-go v0.48.2 in coredns, v0.54.0 in main). Treat each as separate fix.
52+
53+
##### 3. Locate Package
54+
55+
```bash
56+
grep -Fl [package] go.mod coredns/go.mod tools/go.mod 2>/dev/null
57+
```
58+
59+
**Check for replace directives**:
60+
```bash
61+
grep "replace.*$(basename [package])" go.mod coredns/go.mod tools/go.mod 2>/dev/null
62+
```
63+
64+
If found, check git history why it was added. If obsolete, remove now. Otherwise update to safe version in Step 4:
65+
```bash
66+
# Check history
67+
git log -p --all -S "replace.*$(basename [package])" -- [module]/go.mod | head -50
68+
69+
# Remove if obsolete from go.mod (root)
70+
go mod edit -dropreplace=[package]
71+
72+
# Remove if obsolete from coredns/go.mod
73+
go -C coredns mod edit -dropreplace=[package]
74+
75+
# Remove if obsolete from tools/go.mod
76+
go -C tools mod edit -dropreplace=[package]
77+
```
78+
79+
**Check for parent-child dependencies:**
80+
81+
If multiple packages in the same module have CVEs, check if one depends on another: `go -C [module] mod graph | grep [package]`. If parent (e.g., CoreDNS depends on quic-go) also has CVE, fix parent first. Parent upgrade often brings newer child, eliminating separate fix.
82+
83+
##### 4. Update
84+
85+
**If Step 3 found package in single module:**
86+
87+
```bash
88+
# coredns/go.mod only
89+
go -C coredns get [package]@v[version] && go -C coredns mod tidy
90+
91+
# tools/go.mod only
92+
go -C tools get [package]@v[version] && go -C tools mod tidy
93+
94+
# go.mod only
95+
go get [package]@v[version] && go mod tidy
96+
```
97+
98+
If multiple CVEs have different FIXED-IN versions, use the highest.
99+
100+
**If Step 3 found package in multiple modules:**
101+
102+
Multi-module packages require verification between updates to avoid downgrades.
103+
104+
1. If package in main go.mod (and maybe submodules too):
105+
```bash
106+
go get [package]@v[version] && go mod tidy
107+
```
108+
Then proceed to Step 5, Step 6. If Step 6 shows CVE still present, update one submodule at a time, repeating Steps 5-6 after each update.
109+
110+
2. If package only in submodules (e.g., both coredns and tools):
111+
```bash
112+
go -C coredns get [package]@v[version] && go -C coredns mod tidy
113+
```
114+
Then proceed to Step 5, Step 6. If Step 6 shows CVE still present, update next submodule (tools), repeating Steps 5-6.
115+
116+
Submodules may have different (non-vulnerable) versions. Check `git diff` for unexpected downgrades (e.g., CoreDNS version changes).
117+
118+
**On stable release branches, if `go get` upgrades:**
119+
- Go minor version (1.X => 1.Y)
120+
- K8s minor version (v0.A => v0.B)
121+
122+
Revert changes. Low/Medium CVEs: skip to step 9. High/Critical: consult team.
123+
124+
Remove `toolchain` lines and extra blank lines added by `go mod tidy`:
125+
126+
```bash
127+
sed -i '/^toolchain/d' go.mod coredns/go.mod tools/go.mod
128+
sed -i '/^$/{N;/^\n$/s/\n//;}' go.mod coredns/go.mod tools/go.mod
129+
```
130+
131+
Verify changes:
132+
133+
```bash
134+
git diff
135+
```
136+
137+
Expected: Dependency file updates only.
138+
139+
##### 5. Clean Binaries
140+
141+
```bash
142+
make clean
143+
```
144+
145+
Removes build artifacts to avoid false positives.
146+
147+
Network errors: see Common Issues.
148+
149+
##### 6. Verify
150+
151+
```bash
152+
grype . --config .grype.yaml -o table
153+
```
154+
155+
CVE(s) for this package should no longer appear.
156+
157+
**If CVE persists**: Double-check you used the correct version from Step 2 FIXED-IN column. If version is correct but CVE persists, the replace directive should have been caught in Step 3 - recheck Step 3.
158+
159+
##### 7. Verify Build
160+
161+
```bash
162+
make unit
163+
```
164+
165+
**Note**: When fixing multiple packages, skip for each and run once at end.
166+
167+
Build errors may indicate incompatible dependency versions for this branch.
168+
169+
##### 8. Commit
170+
171+
```bash
172+
# Stage dependency files
173+
git add go.mod go.sum coredns/go.mod coredns/go.sum tools/go.mod tools/go.sum
174+
175+
# Verify what will be committed
176+
git diff --staged --stat
177+
```
178+
179+
Expected: Only go.mod/go.sum files (for modules that changed).
180+
181+
Follow commit templates in @.agents/commit-templates.md (CVE Fixes section). Use "in /[module]" format if only coredns or tools files changed.
182+
183+
After each commit, rescan to check for newly introduced CVEs:
184+
```bash
185+
grype . --config .grype.yaml -o table
186+
```
187+
188+
Repeat steps 3-8 for each remaining package with CVEs.
189+
190+
##### 9. When to Ignore CVEs
191+
192+
If fix requires breaking changes (Go version, K8s major version, incompatible APIs), consider:
193+
- CVE severity (Low/Medium vs High/Critical)
194+
- Cost/risk of breaking stable branch dependencies
195+
196+
Add to `.grype.yaml`:
197+
```yaml
198+
# Update requires [incompatibility]. [Severity] doesn't justify breaking changes.
199+
- vulnerability: GHSA-xxxx-xxxx-xxxx
200+
package:
201+
name: package.name/path
202+
```
203+
204+
Commit:
205+
```bash
206+
git commit -s -m "$(cat <<'EOF'
207+
Ignore [package] CVEs incompatible with release-X.Y
208+
209+
[Package] CVEs require versions with [incompatible dependency]
210+
incompatible with this branch's [current dependency].
211+
EOF
212+
)"
213+
```
214+
215+
##### 10. Final Verification
216+
217+
After fixing all packages:
218+
219+
```bash
220+
# Verify no vulnerabilities remain
221+
grype . --config .grype.yaml -o table
222+
223+
# Run build tests if not done in step 7
224+
make unit
225+
226+
# Review commits
227+
git log origin/release-0.X..HEAD
228+
229+
# Verify no unexpected changes
230+
git diff
231+
```
232+
233+
Expected: "No vulnerabilities found", tests pass, commits follow @.agents/commit-templates.md, and no output from diff.
234+
235+
##### 11. Create Pull Request (Optional)
236+
237+
**Agent: Generate PR commands and provide them directly to user in response text.**
238+
239+
Extract variables needed for PR command:
240+
241+
```bash
242+
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
243+
BASE_BRANCH=$(echo $CURRENT_BRANCH | sed 's/fix-\([0-9.]*\)-.*/release-\1/')
244+
COMMIT_COUNT=$(git log ${BASE_BRANCH}..HEAD --oneline | wc -l)
245+
PLURAL=$([[ $COMMIT_COUNT -eq 1 ]] && echo "" || echo "s")
246+
FORK_REMOTE=$(git remote -v | awk '!/submariner-io/ && /\(push\)/ { print $1; exit }')
247+
FORK_USER=$(git remote get-url ${FORK_REMOTE} 2>/dev/null | awk -F '[:/]' '{print $2}')
248+
```
249+
250+
Substitute variables and provide in response (not bash output):
251+
252+
```bash
253+
git push <FORK_REMOTE> <CURRENT_BRANCH> && \
254+
gh pr create \
255+
--title "Fix CVE<PLURAL> in <BASE_BRANCH>" \
256+
--body "See commit message<PLURAL> for details." \
257+
--base "<BASE_BRANCH>" \
258+
--head "<FORK_USER>:<CURRENT_BRANCH>" \
259+
--assignee "@me"
260+
```
261+
262+
User reviews commits, then copies and runs if desired.
263+
264+
##### Common Issues
265+
266+
- **CVE persists**: Verify you used correct FIXED-IN version; replace directives should have been caught in Step 3
267+
- **New CVE appears after fix**: Dependency downgrades can introduce CVEs; fix immediately (Step 8 rescan catches these)
268+
- **Tests fail**: Try different version; check CI logs
269+
- **Large dependency updates**: Some packages update many transitive deps; may break old branches; check Go/K8s compatibility
270+
- **make unit "no route to host"**: User must run `sudo systemctl restart docker` (agent can't use sudo)

CLAUDE.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# lighthouse
2+
3+
Development guidelines for the lighthouse repository.
4+
5+
## Commit Messages
6+
7+
@.agents/commit-templates.md
8+
9+
## Workflows
10+
11+
### Testing
12+
13+
#### Markdown
14+
15+
Run after editing any `.md` file, before committing:
16+
17+
```bash
18+
make markdownlint
19+
```
20+
21+
### CVE Fixes
22+
23+
@.agents/workflows/cve-fix.md
24+
25+
### Konflux Builds
26+
27+
(future - planned for separate effort)

0 commit comments

Comments
 (0)