Introduce hidden attribute to group and project variables
Related to issue: #390305 (closed)
Feature flag rollout issue: #451326 (only when the frontend - #29674 is ready)
What does this MR do and why?
- Adds a feature flag
ci_hidden_variables
- Introduces hidden attributes to group and project variables.
- Reveals the hidden attribute in REST and GraphQL
- Handles a new parameter
masked_and_hidden
on REST API on variable creation. Setting it totrue
creates a new variable with masked and hidden attributes. - Adds a new validation on REST API variables update action. It disallows to change of hidden attributes. It disallows to change of the masked attribute if the hidden attribute is set to true. Validation works only if FF is enabled.
- Suppresses the variable's value if the hidden attribute is true on REST and graphQL endpoints if the FF
ci_hidden_variables
is enabled
MR acceptance checklist
Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
Screenshots or screen recordings
Screenshots are required for UI changes, and strongly recommended for all other merge requests.
How to set up and validate locally
- Enable a FF
ruby Feature.enable(:ci_hidden_variables)
- Generate a private token
- Run a curl script
Get list of project variables
curl --request GET --header "PRIVATE-TOKEN: token" "http://gdk.test:3000/api/v4/projects/54/variables"
Response:
[{"variable_type":"env_var","key":"test_project_var","value":null,"protected":true,"hidden":true,"masked":false,"raw":false,"environment_scope":"*","description":null},{"variable_type":"env_var","key":"t1","value":"t2","protected":true,"hidden":false,"masked":false,"raw":false,"environment_scope":"*","description":"ttt"},{"variable_type":"env_var","key":"masked","value":"masked_value","protected":true,"hidden":false,"masked":true,"raw":false,"environment_scope":"*","description":"masked"}]
Create a project variable
curl --request POST --header "PRIVATE-TOKEN: token" "http://gdk.test:3000/api/v4/projects/32/variables" --form "key=hidden_var6" --form "value=my-hidden-value" --form "masked_and_hidden=true"
Response:
{"variable_type":"env_var","key":"hidden_var6","value":null,"protected":false,"hidden":true,"masked":true,"raw":false,"environment_scope":"*","description":null}
Unable to update a hidden attribute on a project variable
curl --request PUT --header "PRIVATE-TOKEN: oz22XJKwJjchwNsBzYPy" "http://gdk.test:3000/api/v4/projects/38/variables/hidden_var3" --form "hidden=true"
Response:
{"variable_type":"env_var","key":"hidden_var3","value":"my-hidden-value2","protected":false,"hidden":false,"masked":false,"raw":false,"environment_scope":"*","description":"hidden_var"
List group variables
curl --request GET --header "PRIVATE-TOKEN: token" "http://gdk.test:3000/api/v4/groups/75/variables"
Response:
[{"variable_type":"env_var","key":"test","value":"test","protected":true,"hidden":false,"masked":false,"raw":false,"environment_scope":"*","description":null},{"variable_type":"env_var","key":"newvar","value":"vvvv","protected":true,"hidden":false,"masked":false,"raw":false,"environment_scope":"newscope","description":null},{"variable_type":"env_var","key":"newvvv","value":"vvv","protected":true,"hidden":false,"masked":false,"raw":false,"environment_scope":"production","description":null},{"variable_type":"env_var","key":"hidden_var","value":null,"protected":false,"hidden":true,"masked":false,"raw":false,"environment_scope":"*","description":null},{"variable_type":"env_var","key":"dmitry_group_var","value":"group_var","protected":true,"hidden":false,"masked":false,"raw":false,"environment_scope":"*","description":null},{"variable_type":"env_var","key":"hidden_var5","value":null,"protected":false,"hidden":true,"masked":true,"raw":false,"environment_scope":"*","description":null}]
Create a group variable
curl --request POST --header "PRIVATE-TOKEN: token" "http://gdk.test:3000/api/v4/groups/75/variables" --form "key=hidden_var5" --form "value=my-hidden-value" --form "masked_and_hidden=true"
Response:
{"variable_type":"env_var","key":"hidden_var5","value":null,"protected":false,"hidden":true,"masked":true,"raw":false,"environment_scope":"*","description":null}%
Unable to update a hidden attribute on a group variable
curl --request PUT --header "PRIVATE-TOKEN: token" "http://gdk.test:3000/api/v4/groups/75/variables/hidden_var" --form "hidden=false"
Response:
{"variable_type":"env_var","key":"hidden_var","value":"my-hidden-value","protected":false,"hidden":true,"masked":false,"raw":false,"environment_scope":"*","description":null}%
GraphQL
Project variables
query fetchProjectVariables {
project(fullPath: "dmitry/test_project_vars") {
ciVariables {
nodes {
key
value
hidden
}
}
}
}
response:
{
"data": {
"project": {
"ciVariables": {
"nodes": [
{
"key": "masked",
"value": "masked_value",
"hidden": false
},
{
"key": "t1",
"value": "t2",
"hidden": false
},
{
"key": "test_project_var",
"value": null,
"hidden": true
}
]
}
}
}
}
Group variables
query fetchGroupVariables {
group(fullPath: "dmitry") {
ciVariables {
nodes {
key
value
hidden
}
}
}
}
{
"data": {
"group": {
"ciVariables": {
"nodes": [
{
"key": "hidden_var5",
"value": null,
"hidden": true
},
{
"key": "dmitry_group_var",
"value": "group_var",
"hidden": false
},
]
}
}
}
}
Expose project variables on runner execution
.gitlab-ci.yml
hidden_vars:
script:
- echo $hidden_var11|base64
- echo $proj_var
Edited by Dmytro Biryukov