Enable "Masked and hidden" visibility option for instance-level CI/CD variables in Admin UI
### Summary
The **"Masked and hidden"** visibility option is available for project-level and group-level CI/CD variables in the UI, but it is **not available for instance-level variables** in the Admin Area UI. However, the backend (REST API) already fully supports creating instance variables with `masked_and_hidden=true`.
This means the feature works via API but is intentionally disabled in the frontend for instance variables, creating an inconsistency.
### Steps to reproduce
1. Go to **Admin Area > CI/CD > Variables**
2. Click **Add variable**
3. Observe that the **Visibility** section only offers **Visible** and **Masked**, but **not "Masked and hidden"**
Compare with:
1. Go to any **Project > Settings > CI/CD > Variables**
2. Click **Add variable**
3. The **Visibility** section correctly offers **Visible**, **Masked**, and **Masked and hidden**
### Root cause
In [`ci_variable_shared.vue` (line ~165)](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_shared.vue#L165):
```javascript
areHiddenVariablesAvailable() {
// group and project variables can be hidden, instance variables cannot
return Boolean(this.entity);
},
```
The `entity` prop is not set by [`ci_admin_variables.vue`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/assets/javascripts/ci/ci_variable_list/components/ci_admin_variables.vue), so it defaults to an empty string `''`, causing `Boolean('')` to return `false`. This hides the "Masked and hidden" radio button in the variable drawer.
### Backend already supports this
Creating a masked and hidden instance variable via the API works without issues:
```bash
curl --request POST \
--header "PRIVATE-TOKEN: <admin-token>" \
"https://gitlab.example.com/api/v4/admin/ci/variables" \
--form "key=MY_SECRET_KEY" \
--form "value=my-secret-value" \
--form "masked_and_hidden=true"
```
This confirms that the database schema, model validations, and API layer are all ready for instance-level hidden variables.
### Proposed fix
**Option A** — Set the `entity` prop in `ci_admin_variables.vue`:
```diff
<ci-variable-shared
:are-scoped-variables-available="false"
component-name="InstanceVariables"
+ entity="instance"
:hide-environment-scope="true"
:mutation-data="$options.mutationData"
:refetch-after-mutation="true"
:query-data="$options.queryData"
/>
```
**Option B** — Decouple the logic in `ci_variable_shared.vue` so it no longer uses `entity` as a proxy:
```diff
areHiddenVariablesAvailable() {
- // group and project variables can be hidden, instance variables cannot
- return Boolean(this.entity);
+ return true;
},
```
Both options are minimal changes. Option A may be preferred as it also makes the `entity` prop consistent across all variable components.
### Related closed issues
- https://gitlab.com/gitlab-org/gitlab/-/issues/29674 (Frontend: Add "Masked and hidden" option — explicitly scoped out instance variables)
- https://gitlab.com/gitlab-org/gitlab/-/issues/390305 (Backend: Create database column for hidden variables — completed)
### Environment
Reproducible on GitLab Self-Managed (tested on 18.8) and confirmed by reading the current `master` branch source code.
issue