docs: document env var persistence risk in CEL context (#414)#416
Merged
docs: document env var persistence risk in CEL context (#414)#416
Conversation
Process environment variables exposed via the `env` namespace in CEL
expressions are not filtered or redacted. If a user references `env.VAR`
as a model attribute, the value is written to `.swamp/data/` and is
visible in `swamp data get` output — with no warning. This is especially
risky for secrets that happen to be present in the process environment
(AWS_SECRET_ACCESS_KEY, GITHUB_TOKEN, database passwords, etc.).
Add documentation in two places:
- design/expressions.md: new '## Environment Variables' section placed
after '## Sensitive Data'. Covers basic usage, a blockquote security
warning explaining that env values are persisted to disk, and a
wrong/right example comparing env.API_KEY (wrong) with
vault.get('my-vault', 'API_KEY') (right).
- src/domain/expressions/model_resolver.ts: expand the JSDoc on
buildEnvContext() to warn that the full process environment is returned
unfiltered and that sensitive vars accessed in CEL will be persisted.
Expand the ExpressionContext.env field comment with the same guidance
and a pointer to vault.get() as the safe alternative.
No runtime behaviour is changed. The vault.get() path already never
persists secret values in model output data and is the correct approach
for API keys, tokens, and passwords.
There was a problem hiding this comment.
Review: Approved ✅
This is a well-executed documentation PR that addresses issue #414 by warning users about the persistence risk of environment variables in CEL expressions.
What was reviewed:
- Code quality: No runtime changes; JSDoc comments are properly formatted
- CLAUDE.md compliance: ✅ No
anytypes, named exports, proper header - Domain-driven design: Documentation only, no domain logic concerns
- Test coverage: ✅ No behavior changes, no tests required
- Security: ✅ This PR improves security posture by documenting an existing risk
- Bugs/edge cases: No code changes, no new bugs
Strengths:
- Clear security warning with blockquote formatting
- Concrete "wrong vs. right" examples showing
env.API_KEYvsvault.get() - Lists sensitive env var examples (
AWS_SECRET_ACCESS_KEY,GITHUB_TOKEN) - Consistent documentation in both design doc and source code JSDoc
- Links back to the Sensitive Data section for additional context
No blocking issues. LGTM.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #414.
Process environment variables exposed via the
envnamespace in CEL expressions are not filtered or redacted. If a user referencesenv.VARas a model attribute, the value is written to.swamp/data/and is visible inswamp data getoutput — with no warning. This is especially risky for secrets present in the process environment (AWS_SECRET_ACCESS_KEY,GITHUB_TOKEN, database passwords, etc.).Changes
design/expressions.md: new## Environment Variablessection placed after## Sensitive Data. Covers basic usage, a blockquote security warning explaining thatenvvalues are unredacted and persisted to disk, and a wrong/right example comparingenv.API_KEY(wrong) withvault.get('my-vault', 'API_KEY')(right).src/domain/expressions/model_resolver.ts: expanded JSDoc onbuildEnvContext()to warn that the full process environment is returned unfiltered and that sensitive vars accessed in CEL will be persisted in model output data. Expanded theExpressionContext.envfield comment with the same guidance and a pointer tovault.get()as the safe alternative.No runtime behaviour is changed. The
vault.get()path already never persists secret values in model output data and is the correct approach for API keys, tokens, and passwords.Test plan
deno check— passes (no type changes)deno lint— passes (no lint-relevant changes)deno fmt— no formatting changes neededdeno run test— no behaviour changes, all tests should pass🤖 Generated with Claude Code