Compare commits
1 Commits
lint-polic
...
b8d21d1592
| Author | SHA1 | Date | |
|---|---|---|---|
| b8d21d1592 |
@@ -1,3 +1,36 @@
|
||||
# .dockerignore uses Go filepath.Match, NOT .gitignore semantics: `*`
|
||||
# does not cross `/`, and a pattern without a leading `**/` is anchored
|
||||
# at the build-context root. Every depth-independent pattern therefore
|
||||
# needs the `**/` prefix — without it `config/.env` and
|
||||
# `certs/server.key` still ship while the file reads as solved. Entries
|
||||
# that are genuinely root-anchored stay unprefixed. Extend this file
|
||||
# with the repo's own host-built artifacts (compiled binaries, test
|
||||
# binaries, coverage output); those are per-repo and belong here because
|
||||
# a host build otherwise drops them into the context.
|
||||
|
||||
# Repository metadata: exactly one, at the context root.
|
||||
.git
|
||||
node_modules
|
||||
.DS_Store
|
||||
|
||||
# Environment and secrets. These are the reason the prefixes matter: a
|
||||
# developer's local copy is invisible to every git-based check.
|
||||
**/.env
|
||||
**/.env.*
|
||||
**/*.pem
|
||||
**/*.key
|
||||
|
||||
# Dependencies: restored inside the image, never copied in.
|
||||
**/node_modules
|
||||
|
||||
# OS metadata.
|
||||
**/.DS_Store
|
||||
**/Thumbs.db
|
||||
|
||||
# Editor state. Never a build input, and it churns under a developer's
|
||||
# hands, so it invalidates COPY for reasons unrelated to the source.
|
||||
**/*.swp
|
||||
**/*.swo
|
||||
**/*~
|
||||
**/*.bak
|
||||
**/.idea
|
||||
**/.vscode
|
||||
**/*.sublime-*
|
||||
|
||||
11
TODO.md
11
TODO.md
@@ -21,6 +21,17 @@ fmt-check, and commit.
|
||||
|
||||
# Completed Steps
|
||||
|
||||
- 2026-08-09: Closed the secret exposure in the canonical `.dockerignore`: a
|
||||
developer's local `.env`, `*.pem` or `*.key` was reaching the Docker build
|
||||
context under `COPY . .`, invisible to every git-based check because
|
||||
`.gitignore` covers it. The patterns are written to `.dockerignore`'s own
|
||||
`filepath.Match` semantics — `**/`-prefixed so they hold at every depth, which
|
||||
also fixes nested `node_modules` — rather than transplanted from `.gitignore`,
|
||||
whose unprefixed form protects only the repository root while reading as
|
||||
solved. `REPO_POLICIES.md` and both repo checklists now state that asymmetry
|
||||
and require verification by enumerating the image rather than by reading the
|
||||
patterns. Verified with a probe image before, against the naive unprefixed
|
||||
form, and after.
|
||||
- 2026-08-09: Made the pinned golangci-lint actually propagate: REPO_POLICIES.md
|
||||
now carries the canonical `script/bootstrap` snippet for Go repos, which
|
||||
installs when the installed version does not match the pin (the old
|
||||
|
||||
@@ -37,6 +37,13 @@ with your task.
|
||||
`CHECK_EPOCH` rule in `REPO_POLICIES.md`. Without them the check layer is
|
||||
served from cache on an unchanged tree and the build reports a green it
|
||||
never ran.
|
||||
- [ ] Every depth-independent pattern in `.dockerignore` carries a `**/` prefix;
|
||||
only genuinely root-anchored entries such as `.git` are unprefixed, and
|
||||
`.gitignore`'s patterns have not been transplanted unmodified.
|
||||
`.dockerignore` anchors an unprefixed pattern at the context root, so the
|
||||
transplanted form leaves `config/.env` and `certs/server.key` in the build
|
||||
context while reading as solved — see the `.dockerignore` rule in
|
||||
`REPO_POLICIES.md`.
|
||||
- [ ] Gitea Actions workflow in `.gitea/workflows/` runs `script/cibuild` on
|
||||
push — reference
|
||||
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.gitea/workflows/check.yml`
|
||||
|
||||
@@ -52,6 +52,12 @@ Template files can be fetched from:
|
||||
`https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md`
|
||||
- [ ] `Dockerfile` and `.dockerignore` — fetch `.dockerignore` from
|
||||
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.dockerignore`
|
||||
- Extend `.dockerignore` with the repo's own host-built artifacts, giving
|
||||
every depth-independent pattern a `**/` prefix. Do not transplant
|
||||
`.gitignore`'s patterns: `.dockerignore` anchors an unprefixed pattern at
|
||||
the context root, so the copied form leaves `config/.env` in the build
|
||||
context while reading as solved. See the `.dockerignore` rule in
|
||||
`REPO_POLICIES.md`.
|
||||
- All Dockerfiles must run `make check` as a build step, and every stage
|
||||
containing a check-running `RUN` must declare `ARG CHECK_EPOCH` with the
|
||||
`RUN [ -n "$CHECK_EPOCH" ] || exit 1` guard immediately below it — see the
|
||||
|
||||
@@ -331,7 +331,39 @@ style conventions are in separate documents:
|
||||
editor files (`.swp`, `*~`), language build artifacts, and `node_modules/`.
|
||||
Fetch the standard `.gitignore` from
|
||||
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.gitignore` when setting up
|
||||
a new repo.
|
||||
a new repo. These patterns are written to `.gitignore`'s own semantics, in
|
||||
which an unanchored pattern already matches at every depth. They are not a
|
||||
`.dockerignore` and must not be transplanted into one unmodified — see the
|
||||
next rule.
|
||||
|
||||
- **`.dockerignore` does not use `.gitignore` semantics, and copying patterns
|
||||
across unmodified leaves secrets in the build context.** Docker matches with
|
||||
Go `filepath.Match`: `*` does not cross `/`, and a pattern without a leading
|
||||
`**/` is anchored at the build-context root. A `.dockerignore` listing `.env`,
|
||||
`*.pem` and `*.key` therefore excludes only the copies at the repository root;
|
||||
`config/.env` and `certs/server.key` still reach the context and can land in
|
||||
an image layer. That file is more dangerous than a short one with no secret
|
||||
patterns at all, because it reads as solved and stops anyone looking. Give
|
||||
every depth-independent pattern the `**/` prefix — `**/.env`, `**/.env.*`,
|
||||
`**/*.pem`, `**/*.key`, `**/node_modules` — and leave only genuinely
|
||||
root-anchored entries such as `.git` unprefixed. The inverse move is equally
|
||||
wrong: never apply `**/` to `.gitignore`, where it is redundant and produces a
|
||||
file that is wrong in a way that looks careful. Each file is written to its
|
||||
own semantics; neither is derived from the other. Fetch the standard
|
||||
`.dockerignore` from
|
||||
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.dockerignore` and extend
|
||||
it with the repo's own host-built artifacts — a host `make build` that leaves
|
||||
a compiled binary in the repo root puts that binary in the build context,
|
||||
where `.gitignore` hides it from every git-based check.
|
||||
|
||||
- **Verify `.dockerignore` by enumerating the image, not by reading the
|
||||
patterns.** Plant files at the root _and_ at least two directories deep, build
|
||||
a probe image that does `COPY . .`, and list what actually landed
|
||||
(`docker run --rm --entrypoint find IMAGE /app`). Reading the patterns and
|
||||
agreeing they look right is exactly what lets the root-only form through. The
|
||||
`transferring context` size is not a substitute: a nested secret is a few
|
||||
bytes, and BuildKit transfers only the delta from the previous build, so the
|
||||
reported size describes the transfer and not the contents of the image.
|
||||
|
||||
- **No build artifacts in version control.** Code-derived data (compiled
|
||||
bundles, minified output, generated assets) must never be committed to the
|
||||
|
||||
Reference in New Issue
Block a user