Commit Graph
4 Commits
Author SHA1 Message Date
k.rennerandClaude Opus 4.7 9f48960589 revert(security-fix-agent): drop image-tag-bump role
ci/woodpecker/push/build-ci-images Pipeline was successful
Container image tag updates are Flux's job — the homelab cluster
already runs image-reflector-controller and image-automation-
controller (in flux-system/gotk-components.yaml). Setting up
ImageRepository / ImagePolicy / ImageUpdateAutomation resources
is the right home for "bump postgres:15.17 → 15.18 when a new
image is published"; doing it from a CVE-driven scan agent
duplicates that pipeline and competes with it.

Reverting:
  - Agent prompt: drop the `## Image tag bumps` section; image
    findings now go straight to the Skipped list with a "Flux
    image-automation owns this" reason.
  - Woodpecker yml: drop Bash(crane *) from the agent's tool
    allowlist (no longer used) and the `pull: true` workaround
    that existed only to pick up crane's mid-day rebuild.
  - ci-claude Containerfile: remove the crane install. The image
    is back to Node + Claude Code + git/jq/curl basics.

The agent is now scoped exclusively to IaC misconfigurations
(Trivy fs scan results). Image vulns surface in the log + summary
for visibility but no PR action.

Note: there are currently zero ImageRepository / ImagePolicy /
ImageUpdateAutomation resources in kubernetes/ — the controllers
are running idle. Wiring them up for the actual images is a
separate workstream.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 15:09:06 +02:00
k.rennerandClaude Opus 4.7 cf98c3f044 fix(namespaces): move influxdb namespace into infrastructure/namespaces
ci/woodpecker/manual/security-scan Pipeline failed
ci/woodpecker/cron/security-scan Pipeline failed
ci/woodpecker/cron/e2e Pipeline failed
The seed KS owns influxdb-seed-ssh Secret in the influxdb namespace, but
the namespace was previously created by apps/influxdb/namespace.yaml —
which dependsOn seed → seed never reconciles → circular.

Hoist the namespace into infrastructure/namespaces/namespaces.yaml
(consistent with all the other app namespaces) and drop it from the
apps/influxdb Kustomization.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 13:48:06 +02:00
k.rennerandClaude Opus 4.7 671eada6de fix(security-fix-agent): explicit working-directory hint
ci/woodpecker/manual/security-scan Pipeline was successful
Pipeline 856's agent run found the Trivy JSON files via the
pipeline's own jq summary (IaC=0, Image=645 findings) but the
agent itself reported "No Trivy scan files (/tmp/trivy-iac.json
...) were present" — it hallucinated the /tmp prefix and didn't
look in the workspace root.

Prompt now states explicitly that the JSONs are in the current
working directory (project root, not /tmp), and instructs the
agent's first action to be `Glob trivy-*.json` to enumerate what
exists. Adds a stop-condition for the genuinely-empty case so
the agent can't get into a "I'll assume they're somewhere else"
loop.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 12:20:04 +02:00
k.rennerandClaude Opus 4.7 13414df1b3 ci(security-scan): auto-fix agent that opens PRs for Trivy findings
ci/woodpecker/manual/security-scan Pipeline failed
The cron security-scan now ends in an autonomous fix loop:

  iac-scan       → trivy-iac.json
  image-scans    → trivy-image-N.json (per scanned image)
  security-fix-agent (master only):
    1. Gates on >=1 CRITICAL/HIGH finding across all JSON outputs.
    2. Creates branch security-fix/<date>-<short-sha>.
    3. Hands the workspace to Claude Code in headless --bare mode
       (subscription-backed via CLAUDE_CODE_OAUTH_TOKEN, no API key)
       with a narrow tool allowlist (Read/Edit/Write/Glob/Grep —
       no Bash). The agent reads the JSON, applies surgical fixes
       under ansible/, opentofu/, kubernetes/, ci/images/, and writes
       a Markdown summary to /tmp/security-fix-summary.md.
    4. If the agent produced a diff, the step commits as
       "Security Fix Agent <security-bot@renner.uno>" and pushes to
       Gitea, then opens a PR via the pulls API using a dedicated
       security_bot_token (NOT gitea_admin) so the PR is visibly
       machine-authored.

The step is gated to branch=master so it doesn't fire on its own
PR branches — those still trigger the scan workflow as a re-validation
gate, but skip the agent (no fork-bombing).

Trivy now writes JSON output (--format json -o), and findings appear
both in the JSON and as one-line summaries in the step log via jq.
The legacy --exit-code 1 was kept off so the workflow always reaches
the agent step on master; on PR branches the scans are informational
and a human reviews the agent's PR.

Required Woodpecker secrets (added by user, not by this commit):
  - claude_code_oauth_token (claude setup-token output)
  - security_bot_token      (Gitea PAT for the security-bot user)

Required Gitea setup (also out of band):
  - User "security-bot" with email security-bot@renner.uno
  - Write collaborator on gitea_admin/homelab

Agent constraints live in ci/agents/security-fix/prompt.md so they're
diffable + reviewable separately from the pipeline plumbing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 09:28:59 +02:00