Securing GitLab means building a security program at scale. The number of changes in the codebase is constantly increasing, along with the number of side projects.
Keeping track of all these moving parts can not rely only upon our current understanding and vision of the GitLab software architecture. Automation is a key aspect of our work, and GitLab is no exception.
The AppSec Inventory is a private GitLab project to identify and track all projects, components, and dependencies important for us.
The project is available at https://gitlab.com/gitlab-com/gl-security/engineering-and-research/inventory and accessible by all GitLab team members. The Inventory is build using this CLI tool.
Not all projects are important, and we certainly don't want to monitor projects that are POCs, demos, or tests. That's why we need to categorize the projects created by GitLab team members, to understand their nature, and make decisions at scale.
To quickly identify the purpose and characteristics of a project, a strict categorization is necessary.
The following categories can be used to decorate the projects we want to monitor.
||Used as a component of GitLab at some point|
||A library, package source, component (not necessary a
||Used to deploy GitLab.com|
||Deployed to a website (URL will be required)|
||Data classification standard|
||Interaction with 3rd parties|
||Temporary projects (should be removed at some point)|
||Available for GitLab team members only|
||Personal Access Token being used|
||Project should be removed|
||Should remain private indefinitely|
||Used to generate documentation|
Rules define actions to take, based on the project categories. These actions are performed by
gib and are currently hardcoded. We plan to make them dynamic in the future.
||Download vulnerability reports, Dependencies, and CI/CD configuration|
||SAST, Dependency Scanning and Secret Detection must be enabled|
||Dependency Scanning and Secret Detection must be enabled|
||DAST must be enabled. Overall SSL grade must be 'A' or 'A+'|
||Default branch must be
The inventory relies on a folder tree structure, used as a database, in a
Leaves are folders and can be groups or projects, and they're identified by specific files (
project.json for projects,
group.json for groups).
These files are created automatically when syncing the Inventory.
The tree structure reflects the organization of groups and projects in a GitLab instance, in our case: https://gitlab.com.
For example, the GitLab project will be located under
data/gitlab-org/gitlab/ in the Inventory.
Projects can be categorized by creating a
properties.yml file in their folder. This file can contain a
categories array, with the categories of the project.
For example, to add the
categories: - product - library
Subgroups can be ignored (skipped during synchronization) by adding an
ignore file into their folder.
Along with the categorization of the projects, the Inventory is also used to link websites we deploy with their projects. The
properties.yml file can contain a
urls array to list all the URLs (starting with
https://) of a project. These URLs are used to validate the SSL configuration of the servers, and insecure findings are reported.
For example, to add the GitLab website URL:
urls: - https://gitlab.com
A synchronization pipeline runs every week, on Monday mornings. If successful, it will generate a Merge Request to review the changes.
The review aims to:
properties.ymlfile in the project folder to specify its categories. Ask the project owner in doubt.
ignorefile if the group should be ignored. Delete its subgroups and projects in the review Merge Request.
group.jsonfor changes, especially the visibility (public/private).
The Merge Request will report a test coverage, corresponding to the ratio of projects categorized. Ideally, these review Merge Requests keep the same coverage, which means the new projects are categorized before getting merged.