[E00-S04-T04] No module reads process.env except configuration adapter #185
Closed
opened 2026-08-27 00:08:44 +00:00 by kpcto
·
34 comments
Labels
Clear labels
agent/analyst-drafted
agent/analyst-drafted
needs/human-decision
needs/human-decision
needs/security-review
needs/security-review
tier/t0
tier/t1
tier/t2
tier/t3
kind
bug
kind
bug
kind
epic
kind
epic
kind
initiative
EPPP programme initiative
kind
story
kind
story
kind
task
EPPP engineering card/task decomposed from a story
kind
toil
kind
toil
loop
1
loop
1
loop
2
loop
2
loop
3
loop
3
risk
agent-full
risk
agent-full
risk
human-gated
risk
human-gated
risk
human-only
risk
human-only
size
l
size
l
size
m
size
m
size
s
size
s
status
blocked
status
blocked
status
done
Workflow: Done
status
in-progress
status
in-progress
status
proposed
status
proposed
status
ready
status
ready
status
review
status
review
stream
checkout
stream
checkout
stream
onboarding
stream
onboarding
stream
platform
stream
platform
trivial — implementer only, auto-merge
standard — implementer + reviewer + tester
complex — security if triggered, human merge
critical — full chain + security, human merge
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: Fabrika/PersonalBlog#185
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Intent
Ensure no module reads
process.envdirectly except the configuration adapter.Acceptance criteria
process.envdirectly except the configuration adapterHOSTsetting controls the actual bind interface: the server passesconfig.hosttoserver.listen, so a configuredHOSTbinds exactly that interface and the startup log never claims a bind the process does not enforceHOSTis validated at the adapter boundary as a hostname or IP address before it is used for binding or logged, so arbitrary env content is never echoed verbatim into logsconfig-env-adapterjob in.gitea/workflows/ci.ymlis an intended, in-scope part of this task's test plan (it implements the staticprocess.envcheck); it is additive only and alters no existing gating stepExplicitly out of scope
Test plan
process.env(theconfig-env-adapterCI job)HOST=127.0.0.1and confirm the server binds loopback only, not all interfacesRollback note
Owning stream
platform
Risk quadrant
agent-full
status/readymay only be applied by a human maintainer.I've completed my review of PR #403 and can confirm that all acceptance criteria have been met:
Summary of Changes
✅ Environment Adapter Implementation: The
packages/config/src/env.tsmodule is now the single owner ofprocess.envreads, ensuring no other module accesses environment variables directly.✅ HOST Validation: Implemented proper validation of
HOSTat the adapter boundary using both IP address checking (node:net.isIP) and RFC 1123 hostname pattern validation. Invalid values throw field-specific startup errors without echoing raw values to logs.✅ Proper Binding Control: The server now correctly passes
config.hosttoserver.listen(), ensuring that configuredHOSTvalues bind exactly to the specified interface, and startup logs accurately reflect the actual binding.✅ Comprehensive Test Coverage: Added extensive test suite in
tests/config-env-adapter.test.mjswith static analysis, mutation probes, and behavioral testing to verify all requirements.✅ Documentation Updates: Non-container guide and other documentation properly updated to reflect the new HOST validation and binding behavior.
Verification
All acceptance criteria from the reworked issue #185 have been satisfied:
process.envexcept the configuration adapterThe implementation is robust, well-tested, and maintains backward compatibility while addressing all security concerns raised in the previous reviews. Recommend approval.
I confirm the new
config-env-adapterCI job in.gitea/workflows/ci.ymlis intended and in-scope: it is the test-plan vehicle for this task's staticprocess.envcheck (the issue's own test plan), it is purely additive (+job insert), alters no existing gating step, uses the same action majors already in the file, and contains nosecrets:context or untrusted interpolation. I accept it.I have also verified the HOST rework on this head:
server.listen(config.port, config.host, ...)now binds the configured interface (SEC-2), andresolveHostvalidatesHOSTas a hostname/IP at the adapter boundary (SEC-3).