Application-level trust store for X.509 signature verification
<!-- Implementation issues are used break-up a large piece of work into small, discrete tasks that can move independently through the build workflow steps. They're typically used to populate a Feature Epic. Once created, an implementation issue is usually refined in order to populate and review the implementation plan and weight. Example workflow: https://about.gitlab.com/handbook/engineering/development/threat-management/planning/diagram.html#plan --> ## Summary <!-- A brief explanation of the why, not the what or how. Assume the reader doesn't know the background and won't have time to dig-up information from comment threads. --> Currently, `/etc/gitlab/trusted-certs` is used at the datastore for trusted roots for X.509 signature verification. I don't think this is suitable for this use-case for a number of reasons. 1. These same roots are used for verifying TLS connections. 2. Adding certs in this way requires placing certs on the file system. Generally, we don't want GitLab to be configured in this way because it's not conducive for cloud native / Kubernetes deployments (which is how GitLab.com is deployed). It's doable with a `volumeMount` or a `secret`, but it would be better if this were configured via the application rather than the system. 3. This is an instance-wide change, but organizations likely want to be selective about which root certs they trust. Therefore, we ought to have a way to configure this on a per-namespace basis. Such a change would also enable people to use X.509 signed commits on GitLab.com. ### Proposal We should store these roots in the database instead. This will allow them to be managed via the application, and each namespace can have a separate set of trusted CAs. Organizations would be able to use their own CA roots on GitLab.com. 1. Roots can be added via the group settings or project settings. 2. Instance-wide trusted roots can be added via the admin area. 3. (Nice to have?) On GitLab.com, groups can opt-out of the instance-level trusted roots. ## Relevant links <!-- Information that the developer might need to refer to when implementing the issue. - [Design Issue](https://gitlab.com/gitlab-org/gitlab/-/issues/<id>) - [Design 1](https://gitlab.com/gitlab-org/gitlab/-/issues/<id>/designs/<image>.png) - [Design 2](https://gitlab.com/gitlab-org/gitlab/-/issues/<id>/designs/<image>.png) - [Similar implementation](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/<id>) --> ## Non-functional requirements <!-- Add details for required items and delete others. --> - [ ] Documentation: - [ ] Feature flag: - [ ] Performance: - [ ] Testing: ## Implementation plan <!-- Steps and the parts of the code that will need to get updated. The plan can also call-out responsibilities for other team members or teams and can be split into smaller MRs to simplify the code review process. e.g.: - MR 1: Part 1 - [ ] ~frontend Step 1 - [ ] ~frontend Step 2 - MR 2: Part 2 - [ ] ~backend Step 1 - [ ] ~backend Step 2 - MR 3: Part 3 - [ ] ~frontend Step 1 - [ ] ~frontend Step 2 --> <!-- Workflow and other relevant labels # ~"group::" ~"Category:" ~"GitLab Ultimate" Other settings you might want to include when creating the issue. # /assign @ # /epic & --> ## Verification steps <!-- Add verification steps to help GitLab team members test the implementation. This is particularly useful during the MR review and the ~"workflow::verification" step. You may not know exactly what the verification steps should be during issue refinement, so you can always come back later to add them. 1. Check-out the corresponding branch 1. ... 1. Profit! -->
issue