.gitignore does not exclude secrets, and .dockerignore does not exclude .git #40

Open
opened 2026-08-09 03:41:08 +02:00 by clawbot · 1 comment
Collaborator

From the repo-standards audit against REPO_POLICIES.md. Present on main and on the pending lint branch. Smallest change on the milestone with real security value.

The gap

Policy is unambiguous:

> Never commit secrets. .env files, credentials, API keys, and private keys must be in .gitignore. No exceptions.

The current .gitignore in full:

.DS_Store
**/.DS_Store
/secret
*.log
cli.test
vault.test
*.test
settings.local.json

# Stale files
.cursorrules
coverage.out

It contains no secret patterns at all — no .env, no .env.*, no *.pem, no *.key. The canonical org .gitignore carries all four. It is also missing the standard editor patterns (*.swp, *.swo, *~, *.bak, .idea/, .vscode/), node_modules/, and Thumbs.db.

The irony is the point: this is a secret manager. *.key and *.pem are precisely the files a developer generates while testing unlockers and encryption, in this repo more than any other. A stray test key committed to a public repo (this one is public, WTFPL) is unrecoverable — rotation is the only remedy, and only if it is noticed.

Separately, .dockerignore omits .git. The Dockerfile does COPY . . in both the lint and build stages, so the entire git history is copied into the build context and baked into two image layers. The canonical .dockerignore is three lines: .git, node_modules, .DS_Store. The current file is longer and more elaborate but misses the one entry that matters most for context size. It also lacks a trailing newline, which contradicts insert_final_newline = true in the repo's own .editorconfig.

Definition of done

  • .gitignore covers, at minimum: .env, .env.*, *.pem, *.key, plus the standard OS and editor patterns from the canonical org file.
  • The three repo-specific entries are preserved: /secret (the built binary), *.test, settings.local.json.
  • The two entries under # Stale files (.cursorrules, coverage.out) are removed — both files were deleted in 7546cb0 and no longer need ignoring.
  • .dockerignore gains .git and node_modules, and ends with a trailing newline.
  • Verify nothing currently tracked becomes ignored: run git ls-files before and after and confirm the set is unchanged. Adding *.key to .gitignore does not untrack an already-tracked file, but it does silently hide it from future git add, which is its own trap.
  • Confirm the Docker build still succeeds and note the build-context size before and after in the PR — that number is the whole justification for the .dockerignore half.
  • make check green. TODO.md updated in the same commit.

Implementation requirements

  • Base .gitignore on the canonical org file rather than hand-adding four lines, so this repo stops drifting from the standard.
  • Do not add secret unanchored — it would match the internal/secret/ package directory. The existing /secret anchoring is correct and deliberate; preserve it.
  • While here, confirm no key material is already tracked. git ls-files filtered for *.key, *.pem, *.age, and .env should come back empty. If it does not, stop and report on this issue rather than quietly deleting — a committed key needs rotation, not just removal.
From the repo-standards audit against `REPO_POLICIES.md`. Present on `main` and on the pending lint branch. Smallest change on the milestone with real security value. ## The gap Policy is unambiguous: > Never commit secrets. `.env` files, credentials, API keys, and private keys must be in `.gitignore`. No exceptions. The current `.gitignore` in full: ``` .DS_Store **/.DS_Store /secret *.log cli.test vault.test *.test settings.local.json # Stale files .cursorrules coverage.out ``` It contains **no secret patterns at all** — no `.env`, no `.env.*`, no `*.pem`, no `*.key`. The canonical org `.gitignore` carries all four. It is also missing the standard editor patterns (`*.swp`, `*.swo`, `*~`, `*.bak`, `.idea/`, `.vscode/`), `node_modules/`, and `Thumbs.db`. The irony is the point: this is a secret manager. `*.key` and `*.pem` are precisely the files a developer generates while testing unlockers and encryption, in this repo more than any other. A stray test key committed to a public repo (this one is public, WTFPL) is unrecoverable — rotation is the only remedy, and only if it is noticed. Separately, `.dockerignore` omits `.git`. The `Dockerfile` does `COPY . .` in both the lint and build stages, so the **entire git history is copied into the build context and baked into two image layers**. The canonical `.dockerignore` is three lines: `.git`, `node_modules`, `.DS_Store`. The current file is longer and more elaborate but misses the one entry that matters most for context size. It also lacks a trailing newline, which contradicts `insert_final_newline = true` in the repo's own `.editorconfig`. ## Definition of done - `.gitignore` covers, at minimum: `.env`, `.env.*`, `*.pem`, `*.key`, plus the standard OS and editor patterns from the canonical org file. - The three repo-specific entries are preserved: `/secret` (the built binary), `*.test`, `settings.local.json`. - The two entries under `# Stale files` (`.cursorrules`, `coverage.out`) are removed — both files were deleted in `7546cb0` and no longer need ignoring. - `.dockerignore` gains `.git` and `node_modules`, and ends with a trailing newline. - Verify nothing currently tracked becomes ignored: run `git ls-files` before and after and confirm the set is unchanged. Adding `*.key` to `.gitignore` does not untrack an already-tracked file, but it does silently hide it from future `git add`, which is its own trap. - Confirm the Docker build still succeeds and note the build-context size before and after in the PR — that number is the whole justification for the `.dockerignore` half. - `make check` green. `TODO.md` updated in the same commit. ## Implementation requirements - Base `.gitignore` on the canonical org file rather than hand-adding four lines, so this repo stops drifting from the standard. - Do not add `secret` unanchored — it would match the `internal/secret/` package directory. The existing `/secret` anchoring is correct and deliberate; preserve it. - While here, confirm no key material is already tracked. `git ls-files` filtered for `*.key`, `*.pem`, `*.age`, and `.env` should come back empty. If it does not, **stop and report on this issue** rather than quietly deleting — a committed key needs rotation, not just removal.
clawbot added this to the 1.0.0 milestone 2026-08-09 03:41:08 +02:00
Author
Collaborator

Plan, on branch issue-40-gitignore-secrets (base next):

Precondition already checked: git ls-files filtered for *.key, *.pem, *.age, .env comes back empty — no key material is tracked, so nothing to stop for.

.gitignore: replace with the canonical org file from sneak/prompts (OS, editors, Node, and the .env / .env.* / *.pem / *.key secrets block), then append a project section carrying the repo-specific entries forward: /secret (anchored, so it cannot match internal/secret/), *.log, *.test, settings.local.json. Dropped as redundant or stale: **/.DS_Store (already covered), cli.test and vault.test (covered by *.test), and the # Stale files pair .cursorrules / coverage.out.

.dockerignore: additive — add .git and node_modules, and a trailing newline to satisfy insert_final_newline in .editorconfig. Existing entries stay.

TODO.md: one additive Completed Steps entry, same commit.

Verification: git ls-files diffed before and after for byte-identical output; script/cibuild (docker build --ulimit memlock=-1:-1 .) green, with the build-context transfer size recorded before and after for the PR body.

Plan, on branch `issue-40-gitignore-secrets` (base `next`): Precondition already checked: `git ls-files` filtered for `*.key`, `*.pem`, `*.age`, `.env` comes back empty — no key material is tracked, so nothing to stop for. `.gitignore`: replace with the canonical org file from `sneak/prompts` (OS, editors, Node, and the `.env` / `.env.*` / `*.pem` / `*.key` secrets block), then append a project section carrying the repo-specific entries forward: `/secret` (anchored, so it cannot match `internal/secret/`), `*.log`, `*.test`, `settings.local.json`. Dropped as redundant or stale: `**/.DS_Store` (already covered), `cli.test` and `vault.test` (covered by `*.test`), and the `# Stale files` pair `.cursorrules` / `coverage.out`. `.dockerignore`: additive — add `.git` and `node_modules`, and a trailing newline to satisfy `insert_final_newline` in `.editorconfig`. Existing entries stay. `TODO.md`: one additive Completed Steps entry, same commit. Verification: `git ls-files` diffed before and after for byte-identical output; `script/cibuild` (`docker build --ulimit memlock=-1:-1 .`) green, with the build-context transfer size recorded before and after for the PR body.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/secret#40