Skip to content

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?

  1. Adds a feature flag ci_hidden_variables
  2. Introduces hidden attributes to group and project variables.
  3. Reveals the hidden attribute in REST and GraphQL
  4. Handles a new parameter masked_and_hidden on REST API on variable creation. Setting it to true creates a new variable with masked and hidden attributes.
  5. 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.
  6. 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.

image

image

How to set up and validate locally

  1. Enable a FF ruby Feature.enable(:ci_hidden_variables)
  2. Generate a private token
  3. 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

image

Edited by Dmytro Biryukov

Merge request reports