Implement create group secret mutation
What does this MR do and why?
This MR implements the create mutation for group-level secrets as part of the group secrets management feature. This is MR 2 in the implementation sequence, building on the foundation laid in !217485 (closed).
What this adds:
-
groupSecretCreateGraphQL mutation - Allows creating new group secrets with environment scoping and protected branch restrictions -
GroupSecretmodel - Represents group secrets with validation and dirty tracking -
GroupSecretTypeGraphQL type - Exposes group secret data through the API - Create and Read services for group secrets
- Group-specific CI policy refresher for managing OpenBao access policies
Key implementation details:
Model architecture:
- Introduces
BaseSecretclass that bothProjectSecretandGroupSecretinherit from - Refactors shared secret status logic into reusable
SecretStatusconcern - Renames
ProjectSecretStatusEnumtoSecretStatusEnumfor use across both project and group secrets -
GroupSecrettracks changes toenvironmentandprotectedattributes for policy updates
Service layer:
-
CreateService- Handles secret creation with OpenBao integration -
ReadService- Retrieves secret metadata from OpenBao - Shared service helpers extracted to
Secrets::CreateServiceHelpersfor reuse between project and group secrets - Implements two-phase creation: write secret value, then update metadata with completion timestamp
CI Policy management:
- Introduces
BaseSecretRefresherwith shared policy refresh logic -
GroupSecretRefresher- Manages group-specific policies based on environment and protected status -
ProjectSecretRefresher- Refactored fromSecretRefresherto inherit from base class - Policies are created/updated based on
environment+protectedcombination for groups - Automatically removes policies when no secrets reference them
Authorization:
-
GroupSecretPolicydelegates authorization to the parent group - Uses
write_secretpermission (available to Reporter+ role)
Why this approach:
- Group secrets use
environment+protectedfor scoping (vs. project secrets which useenvironment+branch) - Protected flag determines if secret is only accessible from protected branches
- Follows the same two-phase creation pattern as project secrets for consistency
- Policy management ensures secrets are only accessible to authorized CI jobs
Dependencies
This MR depends on !218266 (merged) being merged first. Will rebase on master once merged.
Sample GraphQL Query
Create a group secret:
mutation {
groupSecretCreate(input: {
groupPath: "gitlab-org"
name: "DATABASE_PASSWORD"
description: "Production database password"
secret: "super-secret-value"
environment: "production"
protected: true
}) {
groupSecret {
name
description
environment
protected
metadataVersion
status
group {
fullPath
}
}
errors
}
}
Related
Related to #577342
This is MR 2 based on !217485 (comment 2989161362)
Edited by Erick Bajao