GitLab Secrets Manager

This page contains information related to upcoming products, features, and functionality. It is important to note that the information presented is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. The development, release, and timing of any products, features, or functionality may be subject to change or delay and remain at the sole discretion of GitLab Inc.
Status Authors Coach DRIs Owning Stage Created
proposed alberts-gitlab iamricecake grzesiek fabiopitino jocelynjane shampton sec govern 2023-08-07

Summary

GitLab users need a secure and easy-to-use solution to store their sensitive credentials that should be kept confidential (“secret”). GitLab Secrets Manager is the desired system that provides GitLab users to meet that need without having to access third party tools.

Motivation

The current de-facto approach used by many to store a sensitive credential in GitLab is using a Masked Variable or a File Variable. However, data stored in variables (masked or file variables) can be inadvertently exposed even with masking. A more secure solution would be to use native integration with external secret managers such as HashiCorp Vault or Azure Key Vault.

Integration with external secret managers requires GitLab to maintain the integration with the third-party products and to assist customers in troubleshooting configuration issues. In addition, customer’s engineering teams using these external secret managers may need to maintain these systems themselves, adding to the operational burden.

Having a GitLab native secret manager would provide customers a secure method to store and access secrets without the overhead of third party tools and to leverage the tight integration with other GitLab features.

Goals

Provide GitLab users with a way to:

  • Securely store secrets in GitLab
  • Use the stored secrets in GitLab components (for example, CI Runner)
  • Use the stored secrets in external environments (for example, production infrastructure).
  • Manage access to secrets across a root namespace, subgroups and projects.

Use Cases

To help design the architecture, we need to understand how users, in their roles, would operate and use the system. Here are significant use case scenarios that can help drive our design decisions:

  1. As a Compliance Manager or Security Ops engineer, I want to use dynamic secrets to provide an additional layer of security for my system.
  2. As a Compliance Manager or Security Ops engineer, I want to use automatic secret rotation to provide an additional layer of security for my system.
  3. As a Compliance Manager or Security Ops engineer, I want to set secrets expiration policies to provide an additional layer of security for my system.
  4. As a Developer, I want sensitive credentials to be fully encrypted so I am not accidentally leaking this information in my deliverables.
  5. As a Developer, I want to use secrets to store sensitive credentials to avoid storing this information inside of my code.
  6. As a GitLab Admin and as a GitLab Group Owner, I want to have the ability to disable secrets management feature altogether if my organization requires the use of a 3rd party tool.
  7. As a Compliance Manager or Security Ops engineer, I need to have audit tools which will show me the status of the secrets, their usage so I can identify any suspicious behavior and ensure our security and compliance of our sensitive credentials.
  8. As a Compliance Manager, I need to audit log of secrets usage and management to ensure my organization is following compliance policy.
  9. As a DevOps Engineer, I want the deployment process to fetch secrets necessary for deployment directly from a secrets manager.
  10. As a Customer of a regulated industry, I need a secrets manager with HSM support so I can meet FIPS requirements.
  11. As a US Public Sector customer, I need a secrets manager that is FedRAMP certified to meet security requirements.
  12. As a Customer with an air-gapped system, I need a secrets managers that can be installed on-prem and managed on-site to meet network requirements.
  13. As a Secret Owner, I need to quickly update or rotate the secret in case there has been a vulnerability to ensure the security of my software supply chain.
  14. As a Secret Owner, I need the ability to rollback change to a secret in the event of an accidental change.
  15. As a Security Engineer, I want to ensure all secrets are properly deleted/destroyed if they are no longer needed.

Non-functional requirements

  • Security
  • Compliance
  • Auditability

Non-Goals

This blueprint does not cover the following:

  • Secrets such as access tokens created within GitLab to allow external resources to access GitLab, e.g personal access tokens.

Decisions

Superseded

These documents are part of the initial iteration of this blueprint.

Proposal

The secrets manager feature will be available on both SaaS and Self-Managed installations and will consist of two core components:

  1. GitLab Rails
  2. OpenBao Server
flowchart LR
c([Consumer]) --interacts with-->glab[GitLab Rails]--with backend-->o[OpenBao]

A consumer can be:

  1. A user who interacts manually with a client library, API, or UI.
  2. An integration, for example, Vault integration on Runner.

GitLab Rails

GitLab Rails would be the main interface that users would interact with when managing secrets using the Secrets Manager feature.

This component is a facade to OpenBao server.

Retrieve user secrets

To retrieve secrets for a given user and display them in GitLab UI we will create a new table to persist secrets metadata. Otherwise we can’t pull all the secrets belonging to a user as there is no OpenBao endpoint to achieve this.

Here a SQL example of how this could look like:

CREATE TABLE secrets (
   id bigint NOT NULL,
   environment_id bigint,
   project_id bigint,
   group_id bigint,
   created_at timestamp with time zone NOT NULL,
   updated_at timestamp with time zone NOT NULL,
   revoked_at timestamp with time zone,
   expiration_date date,
   name text,
   description text,
   branch_name text
)

Based on this metadata, we will be able to determine the secret path in OpenBao by using the name provided by the user: kv-v2/data/projects/<project_id>/<secret#name>.

OpenBao Server

OpenBao Server will be a new component in the GitLab overall architecture. This component provides all the secrets management capabilities including storing the secrets themselves.

Use Case Studies

Further investigations required

  1. Authentication of clients other than GitLab Runner. GitLab Runner authenticates using JWT, for other types of clients, we need a secure and reliable method to authenticate requests to decrypt a secret.
  2. How to namespace data, roles and policies to specific tenant.
  3. How to allow organizations to seal/unseal secrets vault on demand.
  4. Infrastructure setup, including how OpenBao will be installed for self-managed instances.
  5. How to best implement sharing of secrets between multiple groups in GitLab.
  6. Establish our protocol and processes for incidents that may require sealing the secrets vault.
  7. How to support protected and environment specific rules for secrets.
  8. How to audit secret changes. Do we want to use audit socket?
  9. Do we want to structure project secret paths to be under namespaces to increase isolation between tenants?
  10. Should the secrets be revoked if a project or subgroup is moved under a different top-level group/organization?

Alternative Solutions

Other solutions we have explored:

  • Separating secrets from CI/CD variables as a separate model with limited access, to avoid unintended exposure of the secret.
  • Secure Files

References

The following links provide additional information that may be relevant to secret management concepts.

Who

DRIs:

Role Who
Author Erick Bajao, Senior Engineer
Recommender Fabio Pitino, Principal Engineer
Product Leadership Jocelyn Eillis , Product Manager
Engineering Leadership Scott Hampton, Engineering Manager
Lead Engineer Erick Bajao, Senior Backend Engineer
Senior Engineer Maxime Orefice, Senior Backend Engineer
Engineer Shabini Rajadas, Backend Engineer

GitLab Secrets Manager ADR 001: Use envelope encryption
Context To store secrets securely in the GitLab Secrets Manager, we need a system that can prevent unencrypted secrets from being leaked in the event of a security breach to a GitLab system. Decision Use envelope encryption. GitLab Rails will store the encrypted secret at rest, along with an encrypted data key. In order to decrypt the secret, GitLab Rails will need to make a decryption request to the GCP key manager through GitLab Secrets Service and obtain the decrypted data key.
GitLab Secrets Manager ADR 002: Use GCP Key Management Service
Context Following from ADR 001: Use envelope encryption, we need to find a solution to securely store asymmetric keys belonging to each vault. Decision We decided to rely on Google CLoud Platform (GCP) Key Management Service (KMS) to manage the asymmetric keys used by the GitLab Secrets Manager vaults. Using GCP provides a few advantages: Avoid implementing our own secure storage of cryptographic keys. Support for Hardware Security Modules (HSM). sequenceDiagram participant A as Client participant B as GitLab Rails participant C as GitLab Secrets Service participant D as GCP Key Management Service Note over B,D: Initialize vault for project/group/organization B->>C: Initialize vault - create key pair Note over D: Incurs cost per key C->>D: Create new asymmetric key D->>C: Returns public key C->>B: Returns vault public key B->>B: Stores vault public key Note over A,C: Creating a new secret A->>B: Create new secret B->>B: Generate new symmetric data key B->>B: Encrypts secret with data key B->>B: Encrypts data key with vault public key B->>B: Stores envelope (encrypted secret + encrypted data key) B-->>B: Discards plain-text data key B->>A: Success Note over A,D: Retrieving a secret A->>B: Get secret B->>B: Retrieves envelope (encrypted secret + encrypted data key) B->>C: Decrypt data key Note over D: Incurs cost per decryption request C->>D: Decrypt data key D->>C: Returns plain-text data key C->>B: Returns plain-text data key B->>B: Decrypts secret B-->>B: Discards plain-text data key B->>A: Returns secret For security purpose, we decided to use Hardware Security Module (HSM) to protect the keys in GCP KMS.
GitLab Secrets Manager ADR 003: Implement Secrets Manager in Go
Following ADR-002 highlighting the need to integrate with GCP services, we do need to decide what tech stack is going to be used to build GitLab Secrets Manager Service (GSMS). Context At GitLab, we usually build satellite services around GitLab Rails in Go. This is especially a good choice of technology for services that may heavily leverage concurrency and caching, where cache could be invalidated / refreshed asynchronously. Go-based GCP KMS client library also seems to expose a reliable interface to access KMS.
GitLab Secrets Manager ADR 004: Sateless Key Management Service
In ADR-002 we decided that we want to use Google’s Cloud Key Management Service to store private encryption keys. This will allow us to meet various compliance requirements easier. In this ADR we are going to describe the desired architecture of GitLab Secrets Management Service, making it a stateless service, that is not connected to a persistent datastore, other than an ephemeral local storage. Context Decision Make GitLab Secrets Management Service a stateless application, not being connected to a global data storage, like a relational or NoSQL database.
GitLab Secrets Manager ADR 004: Use OpenBao as the secrets management service
Context To store and maintain secrets securely in the GitLab Secrets Manager, we want to rely on a robust system that can provide the necessary features that we need. Decision Use OpenBao, a fork of HashiCorp Vault, as the secrets management service. This component will provide all the mechanism to securely store and manage secrets. In terms of user-initiated modifications of secrets, GitLab Rails will act as an abstraction layer and will delegate all tasks to this component.
GitLab Secrets Manager ADR 005: Non-hierarchical key structure for secrets in OpenBao
Context In GitLab, we have a hierarchical structure for projects and their parent namespaces wherein names can be identical in certain parts of the paths. We want to ensure that there are no conflicts with secrets paths across the hierarchy and across all customers when we store then in OpenBao. Decision While secrets are defined in a hierarchical fashion in the GitLab UI, the secret key paths are structured in a flat manner.
GitLab Secrets Manager ADR 006: Use AppRole authentication method between Rails and OpenBao
Context Given GitLab Rails acts as a facade over OpenBao, it directly communicates with the OpenBao API on behalf of users. This means the GitLab Rails component will be granted access to read and write secrets and related configuration data for all projects and organizations to and from OpenBao. We must ensure that every request made by Rails to OpenBao is securely authenticated while staying performant. Authentication options We evaluated 2 OpenBao authentication methods for GitLab Rails:
Use case study: using secrets in a CI job
Objectives To map out how users can use their native GitLab secrets in their CI jobs. Given OpenBao is a fork of HashiCorp Vault, we want to confirm its compatibility with our Vault integration in Runner. At a high level, gain a better understanding of how to structure OpenBao policies and JWT roles to be compatible with a project’s varied permissions per GitLab user role. Prerequisites The workflow requires that the templated policies for each combination of capabilities (e.
Last modified August 23, 2024: Ensure frontmatter is consistent (e47101dc)