Add create/update group secret mutations

What does this MR do and why?

This MR adds GraphQL mutations for creating and updating group-level secrets in GitLab's Secrets Management feature. This extends the existing project-level secrets functionality to support group-level secret management, allowing secrets to be shared across multiple projects within a group.

Key additions:

  • groupSecretCreate mutation - Creates new group secrets with environment scoping and protected branch restrictions
  • groupSecretUpdate mutation - Updates existing group secrets with optimistic locking via metadata version (CAS)
  • GroupSecret GraphQL type - Represents group secrets with fields for name, description, environment, protected status, and lifecycle status
  • Authorization permissions - Adds read_secret, write_secret, and delete_secret permissions for groups (available to Reporter+ role)

Implementation details:

  • Follows the same pattern as existing project secrets mutations
  • Includes internal event tracking for secret creation and update operations
  • Uses feature flag group_secrets_manager to control availability
  • Implements optimistic locking through metadata_cas parameter to prevent concurrent update conflicts
  • Refactors shared secret status logic into reusable SecretStatus concern
  • Adds authorization policies delegating to group permissions

Additional changes:

  • Refactors ProjectSecret to inherit from new BaseSecret class for code reuse
  • Renames ProjectSecretStatusEnum to SecretStatusEnum for use with both project and group secrets
  • Adds authorization permission definitions in config/authz/permissions/secret/
  • Updates GraphQL documentation with new mutation and type definitions
  • Fixes minor inconsistencies in project secrets mutations (payload key naming, feature flag checks)

Sample GraphQL Queries

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
  }
}

Update a group secret:

mutation {
  groupSecretUpdate(input: {
    groupPath: "gitlab-org"
    name: "DATABASE_PASSWORD"
    description: "Updated production database password"
    secret: "new-secret-value"
    environment: "production"
    protected: false
    metadataCas: 1
  }) {
    groupSecret {
      name
      description
      environment
      protected
      metadataVersion
      status
    }
    errors
  }
}

Update only specific fields (partial update):

mutation {
  groupSecretUpdate(input: {
    groupPath: "gitlab-org"
    name: "DATABASE_PASSWORD"
    description: "Updated description only"
    metadataCas: 2
  }) {
    groupSecret {
      name
      description
      metadataVersion
    }
    errors
  }
}

References

Related to #577342

Edited by Erick Bajao

Merge request reports

Loading