Stu Mason
Stu Mason

Activity

Pull Request Opened

PR #182 opened: fix(env_vars): mask value and real_value by default, opt-in reveal

Summary

Closes #159.

env_vars list responses previously included plaintext value (and real_value on the full projection), exposing secrets to any MCP client / LLM that called the tool. Now masked with '***' by default; callers opt in with reveal: true on the list action when they explicitly need the value (e.g. "what is FOO set to right now?").

Per @daniel-rudaev's option 1 in #159 and @StuMason's scope notes (masking at the boundary, both EnvVarSummary and EnvironmentVariable shapes, opt-in reveal on list, metadata untouched).

Changes

  • Added MASKED_VALUE sentinel + maskEnvVar() / maskEnvVarSummary() helpers in coolify-client.ts. Applied at the boundary on the list endpoints — masking doesn't run inside the projection step, so both summary and full projections share one default policy.
  • listApplicationEnvVars(uuid, { summary?, reveal? }) and listServiceEnvVars(uuid, { reveal? })reveal defaults false.
  • env_vars MCP tool: added reveal: z.boolean().optional() to the schema and plumbed through to both list branches. Updated tool description.
  • bulkEnvUpdate was already safe — returns BatchOperationResult with { uuid, name, error? } only, never echoed env var values. No code change there, noted in CHANGELOG for completeness.
  • diagnoseApplication calls listApplicationEnvVars without options, so its env-var aggregator now consumes masked data — but the diagnostic only projects key / is_buildtime / is_runtime (never value), so user-visible output is identical.
  • Tests:
    • 5 new tests covering masked default + reveal=true paths for both list methods, on both summary and full projections, plus real_value masking.
    • 2 existing tests rewritten — they asserted the leaked plaintext value. Those assertions were the bug surface.

Breaking (behavioural)

Callers that relied on value being present in env_vars list responses must now pass reveal: true. This is documented as a Security entry in CHANGELOG.

Test plan

  • npm test — 297/297 passing
  • npm run lint — clean
  • npm run build — clean
  • Client coverage: 98.79% lines, 86.74% branches
  • Both reveal: true and reveal: false paths exercised for codecov patch coverage
+233
additions
-14
deletions
4
files changed