Security & supply chain

GitLab Secrets Manager hits GA in 19.5 and scopes credentials to the job

GitLab Secrets Manager hits GA in 19.5 and scopes credentials to the job

Open the CI/CD settings of any GitLab project older than two years and count the masked variables. (Go on. I'll wait.) Each one is a raw value sitting in a settings page, readable by whatever jobs the old protection flags allow, and good luck proving which job actually read it last Tuesday. GitLab now wants those variables retired. Secrets Manager is generally available in GitLab 19.5 for Premium and Ultimate, on GitLab.com and GitLab Self-Managed. GitLab Dedicated support is listed as coming soon.

When we covered the public beta in August, it was a preview. Now it is a product, and it comes with a price tag.

What exactly shipped

The store runs on OpenBao, the open-source fork of HashiCorp Vault, and GitLab says values are encrypted at rest with AES-256-GCM. It is a paid add-on billed through GitLab Credits: one credit per secret stored per month, and one credit per 2,500 read operations.

The CI side works like this, per GitLab's announcement:

  • A job declares the secrets it needs with the secrets: keyword in .gitlab-ci.yml.
  • GitLab injects a value only into jobs that declare it and fall inside its scope. Scope conditions take wildcards on branch and environment, and they combine, so one rule can demand both a protected branch and a production/* environment.
  • The job gets a path to a temporary file instead of the value itself. Values are masked in logs and discarded when the job finishes.
  • Jobs fetch from OpenBao with short-lived tokens bound to that job's identity.

Where the trust boundary moved

Isn't this just Vault with a tanuki on it? Partly, and GitLab doesn't hide the OpenBao underneath. The difference is who decides access. Secrets Manager reuses GitLab's namespace isolation: projects inherit secrets from their parent groups, and owners grant read, write and delete through the membership model you already maintain. There is no second permission model to drift out of sync with the first one (the usual way a "temporary" Vault policy turns permanent).

Then the audit trail. GitLab streams every create, read, update and delete event to your audit event destinations, and every CI/CD read carries the pipeline and job ID, tied back to the commit, the user and the merge request. When a token shows up somewhere it shouldn't, you can work backwards from the read event to the MR that triggered it. A plain CI/CD variable never gave you that.

Moving a pipeline over

The path today is manual. Create the secret at the group or project level, give it the narrowest branch and environment scope you can live with, then add a secrets: block to the jobs that need it. Since the job receives a file path, check every script and tool that expected the raw value in an environment variable. That's where the first migration bug usually turns up.

Read this before you migrate

  • No migration tooling yet. GitLab says a migration workflow for CI/CD variables is in development. Until it lands, every variable you move is a manual change and a chance to fat-finger a scope rule.
  • The runtime side is not GA. The consumers beyond CI (External Secrets Operator for Kubernetes, Terraform and OpenTofu data sources, the OpenBao and Vault CLIs over a Vault-compatible API, and the Secrets Manager API) are still listed as beta or in development.
  • Reads are metered. Billing per 2,500 reads is cheap until a wide matrix build fetches the same credential in every cell. Scope tightly and the bill shrinks along with the blast radius.
  • Masking does not stop exfiltration. A job that is allowed to read the file can still send it anywhere it has network access. The scope rule is the real control. The log mask is cosmetic.

How other CI platforms divide up secrets

Every CI platform has some answer to "which job gets which credential". They draw the boundary in different places:

  • GitHub Actions has repository, organization and environment secrets. Environment protection rules (required reviewers, deployment branch rules) decide which runs can see an environment's secrets, and OIDC federation to cloud providers lets you skip storing long-lived cloud keys at all.
  • Jenkins uses the Credentials plugin with folder-scoped credentials and withCredentials bindings. It is very flexible. Tracing which build used which credential is left to whatever plugins and logging you add yourself.
  • CircleCI groups secrets into contexts that can be restricted to security groups, and it issues OIDC tokens to jobs for cloud federation.
  • A standalone Vault or OpenBao cluster with JWT auth against your CI's identity tokens is the better fit when several CI systems, or non-CI workloads, share the same credentials. You get one store with many consumers, and it doesn't care which CI vendor you leave next year.
  • Buddy lets you define variables at the workspace, project, pipeline or single-action level and mark them as encrypted so they are masked in logs. That suits teams that use Buddy as the delivery layer across more than one Git host and want a deploy credential visible to one action instead of the whole pipeline.

To be fair to GitLab, if your repositories, runners and permissions already live there, its native manager is the better fit. Reusing the permission model you already have is the entire selling point, and none of the alternatives above can offer that.

My verdict: worth adopting for any job that touches production, once you have budgeted the reads and accepted a manual migration. Just remember what the feature promises. It decides which jobs get the secret. Whatever that job does with it afterwards is still your problem.

Source: GitLab Blog (about.gitlab.com)

Related
Security & supply chain

GitLab's per-user email token can push code and trigger pipelines

Researcher Joe Leon of Aikido Security disclosed that GitLab's incoming-email addresses embed a long-lived, cross-project token that lets anyone holding the address submit patches, run CI/CD and reach the account's secrets.

September 26, 2026
Security & supply chain

GitLab Secrets Manager reaches beyond CI jobs to ESO, Terraform, and an API

GitLab has pushed its Secrets Manager into public beta with three new consumers beyond CI jobs: External Secrets Operator for Kubernetes, a Terraform/OpenTofu data source, and a Vault-compatible API. OpenBao powers it under the hood.

August 6, 2026
Security & supply chain

GitLab's Dependency Firewall moves package policy in front of the build

GitLab has put Dependency Firewall into early access, a policy layer that blocks malicious, vulnerable or non-compliant packages before they reach a build. It shifts dependency checks from after install to before it, which is where credential-stealing packages do their damage.

October 15, 2026

Turn this into your pipeline. Build it on Buddy.

Start free