feat(secrets): reject run-token tracker writes carrying secret values (#107) #114
No reviewers
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/coding-lab!114
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "afk/107"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Server-side leak guard on the tracker write path: every content-bearing write arriving through a run token —
labctl pr create,issue create,issue comment— is scanned against the repo's secret values (exact, base64 all alphabets, hex both cases, URL-encoded; the #104 matcher) and rejected with a 400 naming the secret, field, and form only so the agent can rewrite and retry. Nothing is silently redacted.Design
internal/tracker/secretscan— aTrackerdecorator installed by wrapping the resolver handed toagentapi.Newincmd/lab/main.go. It sits above the registry's forge/builtin fan-out, so both bindings get identical behavior from a single implementation.Config{Tracker: trackerReg}) and the AFK engine keep the bare registry, so PAT writes are never scanned (pinned byTestOperatorWriteNotSecretScanned).ForRunis forwarded per theinstrument.godecorator pattern, so builtin agent attribution survives the wrap.writeTrackerErrormaps*secretscan.BlockedError→ 400 ahead of the forge-502/builtin-500 folds; the branch does not log. The package itself never logs, so no value can reach a log line. Unit + integration tests assert the plaintext and every derived encoding appear in no response.Acceptance criteria → proof
TestSecretScan_PRExactValueBlocked,_IssueBase64TitleBlocked,_CommentURLEncodedBlocked(end-to-end through the HTTP handlers)TestSecretScan_CleanWritesSucceed(incl. the PR path'sCloses #Nappend),TestZeroSecretRepoDelegates,TestCleanWritesDelegateTestSecretScan_BuiltinBindingBlocked(real store-backed tracker, no row written) + forge fake tests aboveTestOperatorWriteNotSecretScannedTestErrorMessageLeaksNoValue, per-400assertNoLeakover all encodings; the scan path contains no loggingRide-along fix (first commit)
maincarried two migrations numbered0008(repo_secretsfrom #112,run_titlefrom #113), so goose failed at boot and every store-backed test failed withfound duplicate migration version 8.repo_secretsmerged first and keeps0008;run_titleis renumbered to0009in both dialects (ADR-0040 reference updated). Without this, nothing on this branch — or main — can be tested or booted.go build ./...,go vet,gofmtclean; fullgo test ./... -count=1green except the pre-existing sandbox-onlyinternal/tmuxxtmux-environment failures (fail identically on a clean tree).Closes #107
🤖 Generated with Claude Code
https://claude.ai/code/session_01Skb2pePwKkHmgCzTjysdBJ