Open rkuhlercadent opened 4 years ago
I also confirm the bug.
A possible solution to this could be the workflowdispatch inputs to be enhanced with INPUT* environment variables as it is described in the documentation. This is also discussed in the Github Community.
Provided the env variables are automatically set, we can then use echo "::add-mask::$INPUT_MYVAR"
and the actual value will not be exposed in the logs.
Seems to be related to #475.
Any updates on this? This is a major blocker for my company. We planned to use the input parameter as passphrase to decrypt files needed in the workflow that are user-specific.
My use case is slightly different but I think my workaround will work for others as well.
curl would produce output that contained secret data; but it was data i needed to parse with jq
or fromJson
. add-mask wouldn't work just the same as everyone else here.
my workaround was to write to a file and just read from that for future actions:
- name: auth
run: curl -sL "https://.../licenseKey?licenseKey=${KEY}" -o /tmp/key.json
env:
KEY: ${{ secrets.KEY }}
and then later steps i can just get a value from the response like so. This'll be different depending on what you're parsing and how you need to pass the data between tasks.
run: |
idToken=$(jq -r '.idToken' /tmp/key.json)
do_something_with $idToken
Doing it this way kept the output clean.
my workarround create a shell variable from your input:
run: |
MY_SECRET=$(cat $GITHUB_EVENT_PATH | jq '.inputs.secret' | sed 's/"//g' )
echo "::add-mask::$MY_SECRET"
my workarround
Thank you! (MY_SECRET can be shortened to jq -r '.inputs.secret' $GITHUB_EVENT_PATH
)
For the record, inputs / environment variables following certain naming conventions are being masked automatically. Please reference the detailed description and code examples in the related issue https://github.com/actions/runner/issues/475#issuecomment-742271143.
Full example with inputs and outputs. Leaving for reference.
Workflow file:
name: Test masking inputs
on:
workflow_dispatch:
inputs:
secret:
description: "secret value"
required: true
token:
description: "token value"
required: true
secret_token:
description: "secret_token value"
required: true
jobs:
test_masking_inputs:
runs-on: ubuntu-20.04
steps:
- name: Test masking inputs
id: add_mask
run: |
INP_SECRET=$(jq -r '.inputs.secret' $GITHUB_EVENT_PATH)
INP_TOKEN=$(jq -r '.inputs.token' $GITHUB_EVENT_PATH)
INP_SECRET_TOKEN=$(jq -r '.inputs.secret_token' $GITHUB_EVENT_PATH)
echo Before mask
echo $INP_SECRET
echo $INP_TOKEN
echo $INP_SECRET_TOKEN
echo ::add-mask::$INP_SECRET
echo ::add-mask::$INP_TOKEN
echo ::add-mask::$INP_SECRET_TOKEN
echo After mask
echo $INP_SECRET
echo $INP_TOKEN
echo $INP_SECRET_TOKEN
echo Setting output
echo ::set-output name=secret::$INP_SECRET
echo ::set-output name=token::$INP_TOKEN
echo ::set-output name=secret_token::$INP_SECRET_TOKEN
echo Setting environment variables
echo SECRET="$INP_SECRET" >> $GITHUB_ENV
echo TOKEN="$INP_TOKEN" >> $GITHUB_ENV
echo SECRET_TOKEN="$INP_SECRET_TOKEN" >> $GITHUB_ENV
- name: Check output from another step
run: |
echo "${{ steps.add_mask.outputs.secret }}"
echo "${{ steps.add_mask.outputs.token }}"
echo "${{ steps.add_mask.outputs.secret_token }}"
- name: Check environment variables 1
run: |
echo "${{ env.SECRET }}"
echo "${{ env.TOKEN }}"
echo "${{ env.SECRET_TOKEN }}"
- name: Check environment variables 2
run: |
echo $SECRET
echo $TOKEN
echo $SECRET_TOKEN
Test masking inputs:
Before mask
(boo3)()
)wo%o()ho$o(
not_really..)(*^%%%%%%%^&*$
After mask
***
***
***
Setting output
Setting environment variables
Check output from another step (WRONG):
***
)wo%o()ho(
***
Check environment variables 1 (WRONG):
***
)wo%o()ho(
***
Check environment variables 2: (CORRECT?)
***
***
***
As I understand last case is the correct usage of masked input (use it as environment variable after placing it into GITHUB_ENV
during add_mask
step), as opposed to two previous steps where stars appear only because variable contains a SECRET
substring in its name.
The solutions that I'm seeing here result in the secret being written to event.json. I'm not entirely sure on the lifecycle of this file, but at least for a period of time your secret is written in plain text and possibly ends up in server logs. The event.json file is the POST payload that triggered the workflow.
An alternative solution would be to use a vault, such as HashiCorp Vault. Your input would be the secret id and the vault credentials would be stored as a repository secret (these are not sent as plain text, unlike using the input). Then, just make an API call to vault to retrieve the secret. Note that Github recommends registering retrieved secret values as a secret.
For more on hardening see the following: https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-secrets and examples are here: https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret
Hi @mykhailo-inv-disco,
This is actually masked well, but the output you are seeing and labeled wrong is actually due to the command being executed.
If you look at it, what it does is actually executing echo ")wo%o()ho$o("
. The output of that would be of course )wo%o()ho(
since it is inside the double quotes, and the $o would be used as a reference to a variable that is not set.
Hey everyone,
I labelled this issue as a feature request. Currently, we log everything that is executed, so using variables like in your workarounds is a good way to bypass this. We have added this issue to the enhancement backlog and it will be considered in the future 😊
This is still an issue - I've recently found a large number of workflows that should have had their secrets masked as they were correctly using add-mask
within the workflow - but because they were called with workflow-dispatch the values were being echoed to the log 🤦.
I'm aware that people probably shouldn't be entering things that might contain secrets as inputs - but we should be designing systems to be safe by default.
This issue was the most helpful resource I could find on how to solve this problem. Thanks everyone!
Thanks to the comments in here, I was able to get this working in a repo of mine recently. But, the solution was boilerplate heavy and I felt it was fragile/error-prone. I was hoping for a better solution.
This is not meant to be a self-promotion, but I did want to share I just created a GitHub Action to help make this easy. I thought other frustrated folks in here would find an Action useful.
Hello everyone,
Going through all the solutions here, and I'm wondering if anyone has faced this problem: The masked inputs are still printed in the reusable workflow?
Masking works fine with the approaches mentioned here for workflow dispatch, however, if you are using a reusable workflow from the caller workflow, it prints all the inputs by default:
It would have been ideal if there was a way to reset the inputs before they are passed to the reusable workflow or if we could limit the ones that are not required by the reusable workflow. I have tried several approaches but none seem to work. Any help is appreciated.
@prateekg1703 this started happening to us too!
It's really concerning that really basic stuff like this isn't handled properly in Actions. For example, if the secret comes from another step's output, it will print the value every single time. It just replaces the ${{ steps.blah.outputs.out... }} with its value in the action. The only thing that comes to mind is that the previous action creates a file in RUNNER_TEMP or GITHUB_WORKSPACE to share with the next step. It's all just hackery and brittle as thin ice.
Bumping this feature as it's a bit ridiculous that it's not currently possible Ideally we would have a secret input type that would do this automatically You can't even put the workaround into a reusable action for deduplication as the secret value will be visible in the logs when it's passed as input
Describe the bug Github actions workflow with inputs cannot be masked using add-mask.
To Reproduce
Expected behavior The value in add-mask does not appear at all in the workflow log output
Runner Version and Platform
Current runner version: '2.272.0' Operating System Ubuntu 18.04.4 LTS
What's not working?
The value in add-mask appears twice without masking
Job Log Output
add-mask test shell: /bin/bash -e {0} Run echo "::add-mask::password" echo "::add-mask::password" shell: /bin/bash -e {0}