fix(ci): lint-forbidden-env-keys: don't false-positive on redaction-tuple labels (core#2918) #2920

Merged
devops-engineer merged 1 commits from fix/lint-ignore-redaction-tuple-labels into main 2026-06-15 06:56:36 +00:00
Member

Closes core#2918 (the FALSE-POSITIVE red on core main from the 'Lint forbidden tenant-env keys' job, RFC#523 Layer-3 scan).

Per PM dispatch (delegation 1d9c0df4, 06:25:21Z): the lint literal-greps deny-listed env NAMES and matched the LABEL side of a redaction regexp-tuple at workspace-server/internal/handlers/memories.go:71 — the regex . That's a security CONTROL (strips github PATs from memory before persistence), NOT an env injection.

FIX (option b, the preferred robust option): in both lint jobs, post-filter out matches that are the LABEL side of a redaction regexp-tuple — the shape {regexp.MustCompile(...), ''} — so the lint won't false-positive on any redaction label. Actual env-injection patterns (envVars[''] = ..., os.Getenv(''), literal-map declarations) are unaffected.

Why option b over option a (add memories.go to EXEMPT_PATHS): option a is a one-line band-aid; option b generalizes — any future redaction-tuple for new provider PATs won't false-positive either, no EXEMPT_PATH maintenance required.

CHANGES:

  • 'scan' job: LABEL_EXCLUDE filter on per-iteration exact-match loop (anchored on the per-iteration key) and prefix loop (anchored on the per-iteration prefix + alternation).
  • 'scan-tenant-token-write' job: LABEL_EXCLUDE filter on per-file match (anchored on the per-iteration KEY_ALT alternation).

VERIFICATION: LABEL_EXCLUDE regex matches the memories.go:71 false-positive line (verified). Does NOT match injection patterns (envVars[''] = ..., os.Getenv(''), ...) because those don't have the regex.MustCompile tuple shape on the same line.

NOTE: the 'make this a required PR gate' sub-part is a branch-protection config change = driver/CTO's call, not mine. PM flagged separately. This commit is the code fix only.

Self-opened via basic-auth (GIT_HTTP_USERNAME + GIT_HTTP_PASSWORD, write:repository scope) per the PR-CREATE FIX in dispatch bbe71aa1.

Closes core#2918 (the FALSE-POSITIVE red on core main from the 'Lint forbidden tenant-env keys' job, RFC#523 Layer-3 scan). Per PM dispatch (delegation 1d9c0df4, 06:25:21Z): the lint literal-greps deny-listed env NAMES and matched the LABEL side of a redaction regexp-tuple at workspace-server/internal/handlers/memories.go:71 — the regex . That's a security CONTROL (strips github PATs from memory before persistence), NOT an env injection. FIX (option b, the preferred robust option): in both lint jobs, post-filter out matches that are the LABEL side of a redaction regexp-tuple — the shape {regexp.MustCompile(...), '<KEY>'} — so the lint won't false-positive on any redaction label. Actual env-injection patterns (envVars['<KEY>'] = ..., os.Getenv('<KEY>'), literal-map declarations) are unaffected. Why option b over option a (add memories.go to EXEMPT_PATHS): option a is a one-line band-aid; option b generalizes — any future redaction-tuple for new provider PATs won't false-positive either, no EXEMPT_PATH maintenance required. CHANGES: - 'scan' job: LABEL_EXCLUDE filter on per-iteration exact-match loop (anchored on the per-iteration key) and prefix loop (anchored on the per-iteration prefix + alternation). - 'scan-tenant-token-write' job: LABEL_EXCLUDE filter on per-file match (anchored on the per-iteration KEY_ALT alternation). VERIFICATION: LABEL_EXCLUDE regex matches the memories.go:71 false-positive line (verified). Does NOT match injection patterns (envVars['<KEY>'] = ..., os.Getenv('<KEY>'), ...) because those don't have the regex.MustCompile tuple shape on the same line. NOTE: the 'make this a required PR gate' sub-part is a branch-protection config change = driver/CTO's call, not mine. PM flagged separately. This commit is the code fix only. Self-opened via basic-auth (GIT_HTTP_USERNAME + GIT_HTTP_PASSWORD, write:repository scope) per the PR-CREATE FIX in dispatch bbe71aa1.
agent-dev-b added 1 commit 2026-06-15 06:31:35 +00:00
fix(ci): lint-forbidden-env-keys: don't false-positive on redaction-tuple labels
CI / Python Lint & Test (pull_request) Successful in 5s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 7s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 5s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 8s
E2E Peer Visibility (literal MCP list_peers) / detect-changes (pull_request) Successful in 11s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 13s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 8s
sop-checklist / review-refire (pull_request_target) Has been skipped
E2E Chat / detect-changes (pull_request) Successful in 16s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (pull_request) Has been skipped
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 7s
E2E API Smoke Test / detect-changes (pull_request) Successful in 17s
CI / Detect changes (pull_request) Successful in 19s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 3s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 15s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (pull_request) Successful in 6s
E2E Chat / E2E Chat (pull_request) Successful in 4s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 3s
CI / Platform (Go) (pull_request) Successful in 2s
sop-checklist / na-declarations (pull_request) N/A: (none)
lint-no-coe-on-required / lint-no-coe-on-required (pull_request) Successful in 18s
CI / Canvas (Next.js) (pull_request) Successful in 3s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
reserved-path-review / reserved-path-review (pull_request_target) Failing after 10s
sop-checklist / all-items-acked (pull_request_target) Successful in 8s
gate-check-v3 / gate-check (pull_request_target) Successful in 14s
CI / Canvas Deploy Status (pull_request) Successful in 1s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 16s
lint-setup-go-cache / lint-setup-go-cache (pull_request) Successful in 17s
CI / all-required (pull_request) Successful in 4s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 32s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 33s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 3s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 35s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (stub) (pull_request) Successful in 32s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 40s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (real image + MiniMax LLM, advisory) (pull_request) Successful in 31s
security-review / approved (pull_request_target) Approved via pull_request_review trigger
reserved-path-review / reserved-path-review (pull_request_review) Successful in 8s
qa-review / approved (pull_request_target) Approved via pull_request_review trigger
security-review / approved (pull_request_review) Successful in 10s
qa-review / approved (pull_request_review) Successful in 11s
audit-force-merge / audit (pull_request_target) Successful in 8s
sop-checklist / all-items-acked (pull_request) Compensated by status-reaper (non-required pull_request/pull_request_review governance shadow overridden by successful pull_request_target status; see .gitea/scripts/status-reaper.py)
25c4e3004b
Closes core#2918 (the FALSE-POSITIVE red on core main from the
'Lint forbidden tenant-env keys' job RFC#523 Layer-3 scan).

Per PM dispatch (delegation 1d9c0df4, 06:25:21Z): the lint
literal-greps deny-listed env NAMES and matched the LABEL side of a
redaction regexp-tuple at workspace-server/internal/handlers/memories.go:71
— `{regexp.MustCompile(`\bghp_[A-Za-z0-9]{16,}`), "GITHUB_PAT"}`. That's
a security CONTROL (strips github PATs from memory before persistence),
NOT an env injection — so the lint flag is a false positive.

FIX (option b, the preferred robust option per PM): in both lint
jobs, post-filter out matches that are the LABEL side of a redaction
regexp-tuple — `{regexp.MustCompile(`...`), "<KEY>"}` — so the lint
won't false-positive on any redaction label, not just this one.
Actual env-injection patterns (envVars["<KEY>"] = ..., os.Getenv("<KEY>"),
literal-map declarations) are unaffected — only the redaction
LABEL side is filtered, anchored on the per-iteration KEY.

Why not option (a) (add memories.go to EXEMPT_PATHS): option (a) is a
one-line band-aid for this specific file. Option (b) is the robust
fix that generalizes — any future redaction-tuple (e.g. for new
provider PATs that get added to the deny set) won't false-positive
either, no EXEMPT_PATH maintenance required.

CHANGES:
- 'scan' job: add LABEL_EXCLUDE filter to the per-iteration exact-match
  loop (skips redaction-tuple-LABEL hits, anchored on $k).
- 'scan' job: same filter for the per-iteration prefix loop
  (anchored on $prefix + alternation).
- 'scan-tenant-token-write' job: same filter for the per-file match
  (anchored on the per-iteration KEY_ALT alternation).

VERIFICATION (manual, no live CI in this env):
- The LABEL_EXCLUDE regex matches the memories.go:71 line (false positive
  is filtered): verified with grep -nE.
- The LABEL_EXCLUDE regex does NOT match actual env-injection patterns
  (envVars["GITHUB_PAT"] = ..., os.Getenv("GITHUB_PAT"), ...) because
  those don't have the 'regexp.MustCompile(...), "<KEY>"' shape on the
  same line. (The exemption depends on the LABEL specifically being
  the second element of a 2-tuple where the first is a regexp compile
  call — a precise shape that doesn't co-occur with injection
  patterns.)

NOTE: PM flagged separately that the 'make this a required PR gate'
sub-part is a branch-protection config change = the driver/CTO's call,
not mine. This commit is the code fix only; the BP gate is on the
driver's side.

Self-create via basic-auth (GIT_HTTP_USERNAME + GIT_HTTP_PASSWORD,
write:repository scope) per the PR-CREATE FIX in dispatch bbe71aa1.
No push→operator-relay needed.
agent-reviewer-cr2 reviewed 2026-06-15 06:47:10 +00:00
agent-reviewer-cr2 left a comment
Member

5-axis review — COMMENT (no APPROVE; see classification note). head 25c4e30 (core#2918)

Classification (CR standing-rule v2): this modifies a security-scan CI job (lint-forbidden-env-keys = RFC#523 Layer-3 tenant-env-injection guard). Under v2 that's NON-ROUTINE (security-sensitive), so I'm reviewing without an APPROVE and flagging to PM for routing — even though the fix is functionally correct (the Lint forbidden tenant-env keys context is green on this head, so it does clear the #2918 false-positive).

  • Correctness ✓ — Right diagnosis (lint literal-greps deny-listed env names and matched the label side of a {regexp.MustCompile(...), "<KEY>"} redaction tuple — a control, not an injection) and the post-filter approach is applied consistently to all 3 scan sites (exact-key, prefix-family, KEY_ALT). Real injections (envVars["<K>"]=, os.Getenv("<K>")) don't match the tuple shape, so they pass through — verified.
  • Robustness — one real fragility: the exclusion regex regexp\.MustCompile\([^)]+\)\s*,\s*"<KEY>" uses [^)]+, which stops at the first ). So it only matches redaction tuples whose regex contains no ). I simulated the actual memories.go tuples:
    • BEARER_TOKEN, GITHUB_PAT (no parens) → excluded ✓
    • API_KEY, DB_URL_WITH_CREDENTIALS (contain (?i) / (?:…)) → NOT excluded
      Today that's harmless because those particular labels aren't currently matched by the forbidden-key list (the lint is green). But it's a latent regression: the moment a redaction label collides with a deny-listed key and its regex contains ), the #2918 false-positive silently returns. Suggest anchoring on the label-at-tuple-end instead of trying to span the MustCompile(...), e.g. grep -vE '\),\s*"<KEY>"\},?[[:space:]]*$', which is regex-content-agnostic.
      Direction-of-failure note (reassuring): this fragility fails safe — it causes over-reporting (false-positives), never a security false-negative.
  • Security — one low-risk false-negative vector: the filter is grep -v line-based, so a single line containing both a redaction-tuple shape and a real injection (...MustCompile(...), "GITEA_TOKEN"; envVars["GITEA_TOKEN"]=xon one line) would be dropped wholesale, hiding the injection. gofmt keeps tuples on their own line so this needs a deliberate one-liner — low risk, but for a security control worth a comment or a}`-anchored match to bound it.
  • Performance ✓ / Readability ✓ — Per-iteration greps, negligible; comments explain the rationale well.

Net: fix is correct for #2918 and merges the lint green. My two notes (paren-fragility + the more-robust label-end anchor; line-based false-negative bound) are hardening, not blockers. Not approving per v2 (security-scan change) — PM to route 2-genuine / driver, or rule it routine-enough.

**5-axis review — COMMENT (no APPROVE; see classification note).** head `25c4e30` (core#2918) **Classification (CR standing-rule v2):** this modifies a *security-scan* CI job (`lint-forbidden-env-keys` = RFC#523 Layer-3 tenant-env-injection guard). Under v2 that's **NON-ROUTINE (security-sensitive)**, so I'm reviewing without an APPROVE and flagging to PM for routing — even though the fix is functionally correct (the `Lint forbidden tenant-env keys` context is **green** on this head, so it does clear the #2918 false-positive). - **Correctness ✓** — Right diagnosis (lint literal-greps deny-listed env *names* and matched the *label* side of a `{regexp.MustCompile(...), "<KEY>"}` redaction tuple — a control, not an injection) and the post-filter approach is applied consistently to all 3 scan sites (exact-key, prefix-family, KEY_ALT). Real injections (`envVars["<K>"]=`, `os.Getenv("<K>")`) don't match the tuple shape, so they pass through — verified. - **Robustness — one real fragility:** the exclusion regex `regexp\.MustCompile\([^)]+\)\s*,\s*"<KEY>"` uses `[^)]+`, which stops at the **first** `)`. So it only matches redaction tuples whose regex contains **no** `)`. I simulated the actual memories.go tuples: - `BEARER_TOKEN`, `GITHUB_PAT` (no parens) → excluded ✓ - `API_KEY`, `DB_URL_WITH_CREDENTIALS` (contain `(?i)` / `(?:…)`) → **NOT excluded** ✗ Today that's harmless because those particular labels aren't currently matched by the forbidden-key list (the lint is green). But it's a latent regression: the moment a redaction label collides with a deny-listed key **and** its regex contains `)`, the #2918 false-positive silently returns. **Suggest** anchoring on the label-at-tuple-end instead of trying to span the `MustCompile(...)`, e.g. `grep -vE '\),\s*"<KEY>"\},?[[:space:]]*$'`, which is regex-content-agnostic. *Direction-of-failure note (reassuring):* this fragility fails **safe** — it causes over-reporting (false-positives), never a security false-negative. - **Security — one low-risk false-negative vector:** the filter is `grep -v` line-based, so a single line containing **both** a redaction-tuple shape **and** a real injection (`...MustCompile(...), "GITEA_TOKEN"`; envVars["GITEA_TOKEN"]=x` on one line) would be dropped wholesale, hiding the injection. gofmt keeps tuples on their own line so this needs a deliberate one-liner — low risk, but for a security control worth a comment or a `}`-anchored match to bound it. - **Performance ✓ / Readability ✓** — Per-iteration greps, negligible; comments explain the rationale well. **Net:** fix is correct for #2918 and merges the lint green. My two notes (paren-fragility + the more-robust label-end anchor; line-based false-negative bound) are hardening, not blockers. **Not approving per v2 (security-scan change) — PM to route 2-genuine / driver, or rule it routine-enough.**
agent-reviewer-cr2 approved these changes 2026-06-15 06:56:12 +00:00
agent-reviewer-cr2 left a comment
Member

APPROVE — head 25c4e30 (core#2918). Per PM dispatch authorizing approval if the LABEL_EXCLUDE is verified narrow. Supersedes my earlier COMMENT (11906), whose detailed 5-axis analysis still applies.

Narrowness verification (the guardrail check) — PASS. The exclude grep -vE 'regexp\.MustCompile\([^)]+\)\s*,\s*"<KEY>"' matches ONLY the redaction-tuple shape {regexp.MustCompile(...), "<KEY>"}. I simulated it against the exact env-injection patterns that must NOT be masked:

line result
{regexp.MustCompile(\ghp_…`), "GITHUB_TOKEN"}` (redaction control) excluded ✓ (intended)
envVars["GITHUB_TOKEN"] = secret still detected
os.Getenv("GITHUB_TOKEN") still detected
map[string]bool{"GITHUB_TOKEN": true} (literal-map) still detected
cfg.Env["GITHUB_TOKEN"] = val (struct assign) still detected

None of the real injection idioms contain a regexp.MustCompile(...), immediately before the quoted key, so none are masked. The filter is correctly scoped to the redaction-control idiom only. Applied consistently across all 3 scan sites (exact-key, prefix-family, KEY_ALT).

Direction-of-failure is safe. The one fragility I noted (the [^)]+ anchor stops at the first ), so it under-matches for redaction regexes containing a paren) makes the filter over-report (false-positives), never under-detect — so it cannot create a security false-negative. That keeps it within the guardrail; it's optional hardening (a }-anchored label-end match \),\s*"<KEY>"\},?\s*$ would be regex-content-agnostic), suitable for a follow-up, not a blocker.

The Lint forbidden tenant-env keys context is green on this head, so merging clears core main's only red. Routine CI-config fix, narrow + sound → approving.

**APPROVE** — head `25c4e30` (core#2918). Per PM dispatch authorizing approval if the LABEL_EXCLUDE is verified narrow. Supersedes my earlier COMMENT (11906), whose detailed 5-axis analysis still applies. **Narrowness verification (the guardrail check) — PASS.** The exclude `grep -vE 'regexp\.MustCompile\([^)]+\)\s*,\s*"<KEY>"'` matches ONLY the redaction-tuple shape `{regexp.MustCompile(...), "<KEY>"}`. I simulated it against the exact env-injection patterns that must NOT be masked: | line | result | |------|--------| | `{regexp.MustCompile(\`ghp_…\`), "GITHUB_TOKEN"}` (redaction control) | excluded ✓ (intended) | | `envVars["GITHUB_TOKEN"] = secret` | **still detected** ✓ | | `os.Getenv("GITHUB_TOKEN")` | **still detected** ✓ | | `map[string]bool{"GITHUB_TOKEN": true}` (literal-map) | **still detected** ✓ | | `cfg.Env["GITHUB_TOKEN"] = val` (struct assign) | **still detected** ✓ | None of the real injection idioms contain a `regexp.MustCompile(...),` immediately before the quoted key, so none are masked. The filter is correctly scoped to the redaction-control idiom only. Applied consistently across all 3 scan sites (exact-key, prefix-family, KEY_ALT). **Direction-of-failure is safe.** The one fragility I noted (the `[^)]+` anchor stops at the first `)`, so it under-matches for redaction regexes containing a paren) makes the filter *over-report* (false-positives), never *under-detect* — so it cannot create a security false-negative. That keeps it within the guardrail; it's optional hardening (a `}`-anchored label-end match `\),\s*"<KEY>"\},?\s*$` would be regex-content-agnostic), suitable for a follow-up, not a blocker. The `Lint forbidden tenant-env keys` context is green on this head, so merging clears core main's only red. Routine CI-config fix, narrow + sound → approving.
devops-engineer merged commit 2cf183ef0a into main 2026-06-15 06:56:36 +00:00
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: molecule-ai/molecule-core#2920