Environment Variable Leak Conversation Audit

Alignment status: review. This report audits local Claude and Codex conversation history, related task records, and current repo artifacts to determine what workflow issues led to environment variables or credential-bearing values being exposed. No resolved secret values are reproduced here.

156,963conversation text records scanned
0JSONL parse errors
10,061Claude compact history lines
678Claude project transcript files
1,988Codex compact history lines
712Codex rollout files

Table Of Contents

Verdict

Main finding: The environment-variable leak was not caused by one isolated accidental paste. It came from a workflow design that normalized direct database credentials as an operational prerequisite, then allowed validation output and documentation handoffs to carry resolved values into tracked files and conversations.

Confirmed incident: the repo records a tracked-file leak in docs/kanban-test-results.md. The cleanup commit is 72fdc1ad (fix: remove leaked Neon database credential from tracked file). I did not open the removed patch hunk because it could reveal the deleted credential. Supporting task history says the credential was scrubbed and the Neon password was rotated.

Primary cause: legacy kanban skills used a standalone direct-DB script that required POKETOWORK_DATABASE_URL for normal work. That design made a production database URL part of the agent workflow instead of keeping it behind an authenticated app-layer API. Later Phase 10 work migrated standard usage to poketo kanban and made the direct script fallback/admin-only.

Scope And Method

The scan included compact user histories and richer conversation transcripts because environment-variable exposure can happen in assistant messages, tool outputs, or generated docs rather than only in user prompts.

SourceRecordsPurposeNotes
~/.claude/history.jsonl10,061 linesCompact Claude user prompts and pasted visible contentUsed for user correction history and prompt themes.
~/.claude/projects/**/*.jsonl678 filesClaude user, assistant, and tool-result transcriptsSkipped system, file snapshots, attachments, and title records for leak-pattern counts.
~/.codex/history.jsonl1,988 linesCompact Codex prompt historyUsed for user prompt context.
~/.codex/sessions/**/*.jsonl712 rollout files, 203,470 rollout lines, 735 metadata recordsCodex rich session records, including assistant messages and tool outputsSkipped identifiable system/developer/reasoning records.
Repo artifactsFocused files and commitsDurable corroborationRead task history, phase docs, current safe docs, and commit metadata. Did not print deleted credential patch content.

The first-pass scanner found 13,314 raw secret-like candidates and 2,890 deduplicated candidate matches. Many were false positives such as code variables named key, token, or animation state. The report therefore relies on confirmed repo records, high-confidence credential shapes, and correction history rather than treating every candidate as a leak.

Confirmed Leak Chain

StepEvidenceWhat HappenedCause
Direct-DB workflow became standard Archived poketo-headless-auth-migration.md says active Claude/Codex kanban skills required POKETOWORK_DATABASE_URL and that operations went straight to Neon. Agent kanban work depended on a raw database URL rather than a scoped API token or app-layer auth. Credential-bearing infrastructure was embedded in normal agent operations.
Validation docs used resolved setup syntax docs/kanban-test-results.md tracked kanban validation and originally included an env export line. Current safe version now uses poketo auth login and POKETO_API_KEY. A resolved Neon credential was written to a tracked result file during validation documentation. Documentation treated a live setup command as content to preserve, without a placeholder-only rule or secret scan gate.
Expert review caught it tasks/history.md records: "Critical: database credential in tracked docs/kanban-test-results.md". The leak was identified as a critical review finding. Detection happened after the file was tracked, not before staging or committing.
Credential was removed Commit 72fdc1ad is titled fix: remove leaked Neon database credential from tracked file and changed docs/kanban-test-results.md. The tracked file was scrubbed. The removed patch content was intentionally not inspected in this audit. Cleanup fixed the artifact but did not by itself remove the workflow that made the credential necessary.
Credential was rotated docs/phases/phase-5.md says "Credential scrubbed from docs/kanban-test-results.md, Neon password rotated". The known exposed database password was rotated after removal. Rotation was the right incident response, but prevention needed workflow changes.
Workflow was redesigned tasks/phases/phase-10.md says no kanban skill requires POKETOWORK_DATABASE_URL for standard usage and that standard workflows use poketo kanban. Direct DB access was demoted to legacy fallback/admin-only. The durable prevention was replacing raw DB access with an authenticated app-layer route.

Recurring Patterns

PatternObserved CountWhat The Count MeansInterpretation
POKETOWORK_DATABASE_URL mentions488 transcript recordsMostly April 2026 Codex session records, many repeated tool outputs or post-fix discussions.The variable was a recurring workflow dependency and cleanup topic, not an incidental one-time string.
Candidate env assignments2,124 deduplicated candidatesRegex candidates across all transcripts; includes false positives and public/non-secret values.Agent sessions often contain env-shaped syntax, so output channels need redaction rather than relying on manual judgment.
Candidate sensitive fields715 deduplicated candidatesFields named token, secret, database URL, connection string, and related variants.Many are examples, placeholders, or code identifiers, but the volume shows that secret-shaped text is common enough to require automated policy.
URL credentials44 deduplicated candidatesConnection strings or URLs with user/password structure; some are local/test placeholders.This is the highest-risk shape and should be blocked from docs, final answers, and commits unless redacted.
Token prefix matches7 deduplicated candidatesProvider-token-shaped strings found in transcripts.Low count but high severity; final answers and tracked files should fail closed on these patterns.
User warnings/correctionsAt least 5 distinct compact promptsExamples include "do not look at the .env.local value" and "did you read the secret? Did you leak them?"The user had already established the boundary; the workflow needed to enforce it automatically.

Evidence Matrix

ClaimEvidenceInferenceConfidenceDecision Impact
The main confirmed leak was a tracked Neon database credential. tasks/history.md names a critical database credential in docs/kanban-test-results.md; commit 72fdc1ad removed a leaked Neon credential from that tracked file. Repo history explicitly labels the incident and its cleanup boundary. High Do not treat this as only a chat-output problem. The prevention gate must cover docs and commits.
The leak was enabled by a direct-DB kanban architecture. Archived headless-auth spec says standard kanban usage required POKETOWORK_DATABASE_URL, direct Neon writes, and local session config. When a raw production DB URL is a normal prerequisite, agents will naturally read, export, test, document, and mention it. High Keep direct DB scripts fallback/admin-only and make app-layer auth the default.
Documentation and final handoff paths lacked an enforced placeholder rule. tasks/lessons.md now says to write placeholder syntax and never paste current secret values from env files, shell context, command output, or model-visible context. The lesson exists because a prior handoff copied a resolved value. It also names the missing behavior. High Implement a pre-commit/pre-final-answer secret scan for docs and handoffs.
Tool outputs were a recurring leak vector. Transcript scan found high-confidence credential shapes mostly in function_call_output and related tool-output records; rg, installer, and validation outputs repeatedly surfaced env requirements. Even if a command is meant to validate, its output can become model-visible and then be copied into docs or final answers. Medium-high Run secret-aware wrappers or output filters around commands that can print env, dotenv, config, or connection strings.
The user had repeatedly clarified the secret boundary. Compact history includes prompts on 2026-03-02, 2026-04-01, 2026-04-14, and 2026-05-03 warning not to inspect or leak env values. The issue was not lack of user intent. It was lack of reliable enforcement under normal agent operations. High Standing instructions should be backed by automation, not memory.
Current standard kanban workflow is materially safer. tasks/phases/phase-10.md says standard workflows use poketo kanban with poketo auth login or POKETO_API_KEY, and no kanban skill requires the DB URL for standard usage. The key architecture fix has already happened for the primary known incident path. High Remaining work should focus on regression gates and fallback/admin-only boundaries.

Root Causes

1. Production credential as routine workflow input

The kanban workflow originally required POKETOWORK_DATABASE_URL for standard operations. That put a raw database credential into the same operational lane as board discovery, card creation, validation, and test documentation.

2. Direct script bypassed app-layer auth and scoping

The archived migration brief says the standalone script executed direct SQL via Neon and bypassed application permission checks. This made the DB URL both powerful and operationally necessary.

3. Validation artifacts copied live setup state

The validation results doc preserved how tests were run. Before cleanup, that included a resolved credential-bearing export instead of a placeholder. This is the direct tracked-file leak path.

4. Secret scanning happened after review, not before commit

The credential was caught by expert review and then removed. The evidence implies there was no reliable gate at the moment docs were written, staged, or committed.

5. Tool output was treated as safe source material

Session transcripts show commands like installers, search, test runners, and validation outputs repeatedly printing env names, setup instructions, and sometimes credential-shaped values. Tool output then became model-visible source material for summaries and docs.

6. User warnings were not converted into automatic controls

History contains direct user warnings about not reading .env.local values and not leaking secrets. Those warnings reduced ambiguity but did not create mechanical checks. The later lesson fixed the instruction layer; the remaining gap is enforcement.

Sanitized Examples

2026-03-02 user prompt: "woah, you should not be looking at environment variables, they're secret right"
2026-04-01 user prompt: "ok I've added the env vars. Remember they're meant to be secret, do not look at them."
2026-04-06 user prompt: "can you identify how many times secrets were leaked and what we can do to prevent this from happening in the future? Can you also inventory what needs to be rotated?"
2026-04-14 user prompt: "will the test leak any env vars?"
2026-05-03 user prompt: "did you read the secret? Did you leak them?"

Representative redacted leak shape found in history: DATABASE_URL=<redacted postgres URL with credentials>. Representative safe replacement now present in current docs: poketo auth login or export POKETO_API_KEY="pk_...". The report intentionally does not include old resolved values.

Recommendations

RankPatternRecommendation TypeSuggested Owner SurfaceValidation Expectation
1Docs and handoffs can preserve resolved env valuesSkill + standing instructionship, ship-end, exec, report-producing skillsLayer1 fixture fails when docs/final handoffs include URL credentials, provider tokens, or sensitive env assignments.
2Tool output can become source material without redactionPlugin/integration or wrapperCommand execution and transcript summarization pathsFocused smoke test runs a command emitting fake secrets and proves outputs are redacted before documentation or final answer use.
3Fallback direct-DB scripts can drift back into default docsStanding convention + regression testpoketowork-kanban packTest rejects active standard-use docs requiring POKETOWORK_DATABASE_URL or kanban.mjs.
4Agents may inspect .env* when user only asked for required variable namesSkill behavior ruleAll coding/debug/review skillsFixture distinguishes reading .env.example from reading .env.local; real env reads require explicit approval and value redaction.
5Secret detection is currently scattered across lessons and human reviewRepository hygiene commandValidation scriptsSecret scan checks current tracked files plus staged diff before commit; deleted historical hunk inspection is avoided unless intentionally authorized.

Recommended next command: $targeted-skill-builder secret-safe documentation and tool-output gate for ship/exec workflows. Likely owner surface: shared execution/shipping contracts plus validation scripts. Minimum validation: a layer1 contract test with fake secret fixtures and a focused command-output redaction smoke.

Highest Impact Automations

  1. Secret-safe docs/handoff gate. Before any report, test result, task doc, final answer, or commit, scan for URL credentials, sensitive env assignments, provider token prefixes, and password-like query params.
  2. Tool-output redaction filter. Treat command output as untrusted when it contains env/config/dotenv text. Redact before summarizing or writing it.
  3. Env-file access boundary. Default to .env.example, schema validation code, or variable names. Reading live .env files should require explicit user intent and should never print values.
  4. Direct-DB fallback quarantine. Keep kanban.mjs fallback/admin-only, with active docs and skills using poketo kanban.
  5. Historical leak handling rule. When a prior commit removed a credential, report commit/path metadata only. Do not run patch-view commands that could reprint deleted secret content unless the user explicitly asks for forensic history rewriting.

Assumptions And Gaps

Assumption: Conversation history and repo artifacts are sufficient to identify the main leak path. This is strong because task history and commit metadata explicitly name the tracked credential leak.

Gap: I did not inspect the deleted patch hunk from commit 72fdc1ad, so I cannot classify the exact credential string beyond what repo records state: a Neon database credential in docs/kanban-test-results.md. That omission is intentional to avoid re-disclosure.

Gap: The broad scanner counted candidate secret-shaped matches, not confirmed secrets. Counts should be used to prioritize guardrails, not to infer exact rotation inventory.

Residual risk: Git history may still contain the old value unless history was rewritten outside the observed artifacts. The evidence only proves scrub + rotation, not complete historical erasure.

Review Gates

Evidence Coverage

Is the evidence sufficient to treat the tracked kanban docs leak as the primary confirmed incident?

Assumptions And Confidence

How should this report treat candidate secret-like counts?

Recommended Path

Which remediation should be prioritized?

Proposed File Changes

Are the durable artifacts for this audit acceptable?

Post-Approval Route

After approval, how should this report route next work?

Compile Feedback And Answers

Use feedback YAML for concerns before answering all gates. Use final answers only when the report is ready for agent review.