Allow configuring the GitGuardian API endpoint in the GitGuardian project integration (EU SaaS & self-hosted)
### Problem to solve
The GitLab → GitGuardian project integration (`Settings → Integrations → GitGuardian`)
currently only works against GitGuardian's US SaaS endpoint.
The destination URL is hardcoded in `ee/lib/gitlab/git_guardian/client.rb`:
```ruby
API_URL = "https://api.gitguardian.com/v1/multiscan"
```
And the only configurable fields on the integration (`PUT /projects/:id/integrations/git-guardian`)
are `token` and `use_inherited_settings` — there is no way to point the integration at
another GitGuardian instance.
As a result:
- Customers on **GitGuardian EU SaaS** (`https://api.eu1.gitguardian.com`) cannot use this
integration — their API token is only valid against the EU region and gets `401` against
the US host.
- Customers running **self-hosted GitGuardian** (`https://gitguardian.my-company.com`)
cannot use it at all.
This is currently blocking EU customers (e.g. enterprises subject to EU data-residency
requirements) and self-hosted deployments from adopting GitLab's native push-protection
integration with GitGuardian.
### Intended users
- GitLab Premium / Ultimate customers using **GitGuardian EU SaaS**
- GitLab Premium / Ultimate customers running **self-hosted GitGuardian**
- GitLab Self-Managed instances that pair with self-hosted GitGuardian for data-residency
/ air-gapped scenarios
### User experience goal
When configuring `Settings → Integrations → GitGuardian` on a project (or via the API),
users should be able to specify the GitGuardian API base URL in addition to the API token.
The default value remains the current `https://api.gitguardian.com` so the change is
fully backwards compatible.
### Proposal
1. Add a new `api_url` (or `endpoint`) string field to the `Integrations::GitGuardian` model.
- Default: `https://api.gitguardian.com`
- Validation: must be a valid HTTPS URL; optionally restrict to allowed hostnames
(`api.gitguardian.com`, `api.eu1.gitguardian.com`, and any URL otherwise allowed by
`ApplicationSetting#outbound_local_requests_allowlist` for self-hosted instances).
2. Surface the new field in the integration form
(`app/views/projects/integrations/git_guardian/_form.html.haml` and EE equivalent),
labelled e.g. *"API endpoint"* with help text linking to GitGuardian's region docs.
3. Thread the value into `Gitlab::GitGuardian::Client`:
```ruby
# ee/lib/gitlab/git_guardian/client.rb
def initialize(api_token, api_url: 'https://api.gitguardian.com')
raise ConfigError, 'Please check your integration configuration.' unless api_token.present?
@api_token = api_token
@api_url = "#{api_url.chomp('/')}/v1/multiscan"
end
# ...
def perform_request(params, repository_url)
response = Gitlab::HTTP.post(@api_url, ...)
end
```
Remove the `API_URL` constant (or keep it only as the default value).
4. Update the project integrations API
(`PUT /projects/:id/integrations/git-guardian`) to accept and persist `api_url`, and
document it in `doc/api/project_integrations.md`.
5. Update user docs at `doc/user/project/integrations/git_guardian.md` to describe how to
choose the right endpoint (US / EU / self-hosted).
6. Add specs covering:
- default URL is used when `api_url` is not set
- custom EU URL routes the request to `https://api.eu1.gitguardian.com/v1/multiscan`
- self-hosted URL is honoured
- invalid URLs are rejected at the model layer
### Backwards compatibility
The default value (`https://api.gitguardian.com`) preserves today's behaviour for every existing integration. No data migration is required beyond adding the column with a default value.
### Documentation references
- GitGuardian API SaaS regions: https://api.gitguardian.com/docs#section/Introduction
- GitGuardian API self-Hoted: https://docs.gitguardian.com/self-hosting/management/application-management/api-configuration
- Existing GitLab integration docs: https://docs.gitlab.com/user/project/integrations/git_guardian/
- Existing GitLab API docs: https://docs.gitlab.com/api/project_integrations/#gitguardian
### Links / references
- Existing client: <https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/gitlab/git_guardian/client.rb>
- Existing model: `ee/app/models/integrations/git_guardian.rb`
issue