-
-
Notifications
You must be signed in to change notification settings - Fork 763
Description
Description
Usecase
Consider a setup where many tasks needs same credentials for different operations.
Therefore, the logical thing is to have a task that reads creds that MUST NOT be persisted on disk from some secret manager, and passes them in-memory to all its dependents.
Current state
The only way I could find how to do it now - is have the "reader" task print something that the downstream stasks have to pass to eval - e.g. a step like - eval $(task creds).
version: '3'
tasks:
creds:
cmds:
- echo "export USR=me; export PWD=top-secret!!;"
operation1:
cmds:
- >
eval $(task creds);
some-cli-tool -u $USR -p $PWD some operation1
operation2:
deps: [creds]
cmds:
- >
eval $(task creds);
some-cli-tool -u $USR -p $PWD some operation2That is less than ideal.
Firstly because it is platform-dependent and shell dependent.
Second - if I want to debug something - I should print it to >&2 - and that's also a shell specific thing.
Third - the eval must happen on every command - it is not persisted even on the task level... If I want to pass it to env - it gets very clunky:
tasks:
creds:
cmds:
- vault read ...
operation1:
vars:
USR: { sh: task creds | jq.USR }
PWD: { sh: task creds | jq.PWD}
cmds:
- some-cli-tool-expects-ENV-vars operation3this negates all the reuse beause the operation<#>.vars is coppied between all the operations that depend on creds :(
Proposal
I would propose tasks to have "outputs", similar to how outputs work in GitHub actions, just less cumbersome...
e.g:
version: '3'
tasks:
creds:
vars:
JSON:
sh: aws sts get-parameter .... | jq -r .Parameter.Value
USR:
sh: echo {{.JSON}} | jq .USR
output: true # makes $USR available on context of dependent tasks
PWD:
sh: echo {{.JSON}} | jq .PWD
output: { as: SVC_API_KEY } # makes it available on context of dependent tasks as `SVC_API_KEY`
operation1:
deps: [creds]
cmds:
- some-cli-tool -u $USR some operation1 # assumes SVC_API_KEYMind that on operation1 - it explicitly uses $USR and not {{.USR}} so that the value is not spat to screen.
It would be nice to support secret mode if the scope allows it:
creds:
vars:
JSON:
sh: aws sts get-parameter .... | jq -r .Parameter.Value
USR:
sh: echo {{.JSON}} | jq .USR
output: true # make it available on contexts of dependent tasks
PWD:
sh: echo {{.JSON}} | jq .PWD
output: true
secret: true # truncates the secret from being print, replacing it with `<secret>`
# more suggested forms that worth considering to be supported:
# (but if it makes the scope too big - it can be dealt in a separate feature PR)
# secret: { replace: '..shh!!' } - when print to logs - replaces each secret with `...shh!!` (you control the string)
# secret: { mask: '*' } - replaces every character with a `*`, so the length of the secret is visible
# secret: { peek: 4, replace: true } - keeps the first `peek` character visible
# and replaces all the rest with `replace` so the output confirms you got the right secret,
# but it is never spat raw.
# secret: { peek: 4, replace: '<truncated>' } - same like previous, but you control the replacement string
# secret: { peek: 4, mask: '*' } - keeps the first `peek` character visible and replaces the rest of characters with `mask`
# so the secret can be identified also by the length as an additional confirmation
# but it is never spat raw.