Masked CI/CD variables are not expanded when passed as inputs to CI Components
When passing a project-level CI/CD variable that is configured as Masked to a CI Component input, the component receives the literal variable name (e.g., $MY_VARIABLE) instead of the variable's value. If the "Masked" option is disabled for the same variable, the value is passed correctly.
Steps to reproduce
-
Create a simple CI Component (e.g., in a project
my-group/components):
spec:
inputs:
secret_value:
---
test_job:
image: alpine:latest
script:
- echo "The value is $[[ inputs.secret_value ]]"
# To verify if it's a literal string or value
- |
if [ "$[[ inputs.secret_value ]]" == "$MY_MASKED_VAR" ]; then
echo "FAIL: Input received literal variable name"
else
echo "SUCCESS: Input received expanded value"
fi
-
Configure CI/CD Variables in the consumer project:
- Go to Settings > CI/CD > Variables.
- Add a variable
MY_MASKED_VARwith valuesecurevalue123and check Masked. - Add a variable
MY_PLAIN_VARwith valueplainvalue123and uncheck Masked.
- Create .gitlab-ci.yml in the consumer project:
include:
- component: $CI_SERVER_FQDN/my-group/components/echo-test@main
inputs:
secret_value: $MY_MASKED_VAR
Actual behavior
The job fails or behaves unexpectedly because the input secret_value contains the literal string $MY_MASKED_VAR.
In the job logs, you might see:
The value is $MY_MASKED_VAR
FAIL: Input received literal variable name
(Note: Since it's a literal string starting with $, the shell might try to evaluate it again inside the script, often resulting in an empty string if not exported, or just the string itself depending on quoting).
Expected behavior
The input should receive the actual value of the variable (securevalue123), just like it does for non-masked variables.
Workaround
Unchecking the Masked flag in the CI/CD variable settings allows the value to be passed correctly to the component input.
Context
- GitLab Version: v18.5.4