Files
terdut-server/CLAUDE.md
T
Niklas Ye 79f5db2636
CI / chart (push) Successful in 0s
CI / security (push) Successful in 19s
CI / test (push) Successful in 25s
Scan the source and the working tree too, not just the image
The image scan added yesterday reads the built artifact. It cannot see a
vulnerable dependency the binary never calls into, and it cannot see a
credential in a file that never reaches the image — this one is FROM scratch
and contains a single binary, so almost nothing in the repo is in it. Those
are two different questions and they need two different tools, which is why
riksdata and rd-web have run govulncheck and gitleaks all along.

Both run on every push and pull request rather than only on a tag, since
neither needs anything published.

Checked by hand before wiring in, as with the image scan. govulncheck
reports no vulnerabilities the code can reach, and gitleaks finds nothing in
the tree.

What govulncheck does report is worth writing down, because it is the
argument for having it. It found three advisories in chi and reports none of
them, all three being IP spoofing in middleware.RealIP, which router.go does
not use — it uses Logger and Recoverer. The analysis is symbol-level rather
than dependency-level, so adding middleware.RealIP would turn this red on
the next push. That is precisely when someone should be made to look, and it
is a plausible thing to reach for here, since the API sits behind a gateway
and real client addresses are exactly what RealIP is for. The fourth finding
is an integer overflow in golang.org/x/sys/windows, which a linux/scratch
image will not be calling.

Both gates were checked for the failure direction as well. gitleaks exits 1
on a private key block. Worth knowing when testing it: it allowlists
well-known example credentials, so the AWS key from Amazon's own
documentation does not trip it and proves nothing.

Neither reads git history. gitleaks runs with --no-git, which scans the
working tree, so it stops a secret on the way in and says nothing about what
is already committed.

Claude-Session: https://claude.ai/code/session_01S7R4gWTz5wh5xCY4nCSJjN
2026-09-02 10:11:13 +02:00

44 lines
2.3 KiB
Markdown

## Release
Say **"Release"** (or "Release X.Y.Z") and the `release` skill runs it: commit, push, tag,
wait for the pipeline, then open the wrapper-chart PR against `Ryuvia/charts`. It stops
there — merging and the Flux reconcile stay manual, deliberately.
Preconditions and the plan, without side effects:
```sh
~/.claude/skills/release/scripts/release-preflight # state + suggested version
~/.claude/skills/release/scripts/release-preflight vX.Y.Z # validate that release
```
Config is `.release.conf` here plus `make release-vars`. The process itself lives in
`~/.claude/skills/release/`; why it is shaped this way is in README.md §Releasing.
Two things about this repo specifically:
- **The image is scanned after it is published, not before.** `scan-image` runs trivy
against the pushed image, because trivy cannot read a locally built one on this runner.
A red scan therefore unpublishes nothing — it means: do not bump the wrapper chart in
`Ryuvia/charts` to this version. Added 2026-09-02; every release up to and including
v0.9.3 was published with no CVE check at all.
- **The wrapper chart has two `tag:` lines** — the app image and the python backup sidecar —
so `chart-bump` needs `--image "$IMAGE"` to know which one moves.
## Checks
`make fmt lint test helm-lint` **is** what the pipeline runs — `ci.yaml` and `release.yaml`
call these targets rather than restating them, the way riksdata and rd-web do. A green gate
here and a green pipeline are the same code, not two descriptions of it. `test` adds `-race`,
which the workflows do not have to ask for since they call the target; see the comment on it
for why.
`make release` (build + push the multi-arch image, package + push the chart) is what
`release.yaml` invokes. Do not run it by hand — it refuses `VERSION=dev` for that reason, and
publishing happens by pushing a tag.
Three scans, and they see different things: `security-go` (govulncheck) reads the source and
its module graph and reports only vulnerabilities the code can actually reach;
`security-secrets` (gitleaks) reads the working tree, not the history, so it catches a secret
on the way in rather than auditing what is already committed; `security-image` (trivy) reads
the published artifact and therefore only runs on a tag. The first two gate every push.