fix: prevent secret variable leaks in summary, verbose and key ordering

- mask secret values in `task --summary` (commands and vars listing)
- mask resolved value of dynamic (sh) secrets in verbose logs
- use masked command for platform-skipped verbose log
- allow `secret` key in any position in a var definition (not only first)
- add `value` to the JSON schema var definition
- skip masking pass when no secret is present and dedup mask helpers
- document that the `secret` flag is not propagated to derived variables
This commit is contained in:
Valentin Maerten
2026-06-29 12:36:56 +02:00
parent 8545e02e5e
commit da90ecd083
12 changed files with 175 additions and 60 deletions

View File

@@ -51,11 +51,29 @@ tasks:
- defer: echo "Cleanup with secret={{.DEFERRED_SECRET}} and app={{.APP_NAME}}"
- echo "Main command executed"
test-dynamic-secret-verbose:
desc: Test that dynamic (sh) secrets are masked even in verbose logs
cmds:
- echo "Password is {{.PASSWORD}}"
test-secret-key-order:
desc: Test that "secret" may be declared before the value/sh key
vars:
SECRET_FIRST:
secret: true
value: "order-independent-secret"
SH_SECRET_FIRST:
secret: true
sh: "echo 'sh-order-independent-secret'"
cmds:
- echo "Value={{.SECRET_FIRST}} Sh={{.SH_SECRET_FIRST}}"
test-env-secret-limitation:
desc: Test showing that env vars with secret flag are NOT masked (limitation)
env:
SECRET_TOKEN:
value: "env-secret-token-123"
secret: true
PUBLIC_ENV: "public-value"
cmds:
# Templates {{.VAR}} don't work with env - they're empty

View File

@@ -0,0 +1,5 @@
task: dynamic variable: "echo 'my-super-secret-password'" result: "*****"
task: "test-dynamic-secret-verbose" started
task: [test-dynamic-secret-verbose] echo "Password is *****"
Password is my-super-secret-password
task: "test-dynamic-secret-verbose" finished

View File

@@ -0,0 +1,2 @@
task: [test-secret-key-order] echo "Value=***** Sh=*****"
Value=order-independent-secret Sh=sh-order-independent-secret

View File

@@ -0,0 +1,15 @@
task: test-secret-masking
Test that secret variables are masked in logs
vars:
APP_NAME: "myapp"
API_KEY: *****
PASSWORD: *****
PUBLIC_URL: "https://example.com"
commands:
- echo "Deploying myapp to https://example.com"
- echo "Using API key *****"
- echo "Password is *****"
- echo "Public app name is myapp"