Protected terraform states: GraphQL API for protection rules
Problem Statement
As part of the Protected Terraform States epic, we are adding protection rules that control who can write to a Terraform state and from where.
This issue covers the GraphQL API for querying and managing Terraform state protection rules. This API is also a prerequisite for the frontend UI that will allow maintainers to configure protection rules from the project settings.
Proposal
Expose terraformStateProtectionRules on the Project GraphQL type and provide
create, update, and delete mutations.
Querying protection rules
query {
project(fullPath: "my-group/my-project") {
terraformStateProtectionRules {
nodes {
id
stateName
minimumAccessLevelForWrite
allowedFrom
}
}
}
}
Returns all protection rules for the project. Unauthorized users receive empty results.
Creating a protection rule
mutation {
createTerraformStateProtectionRule(input: {
projectPath: "my-group/my-project"
stateName: "production"
minimumAccessLevelForWrite: MAINTAINER
allowedFrom: CI_ON_PROTECTED_BRANCH_ONLY
}) {
terraformStateProtectionRule { id stateName minimumAccessLevelForWrite allowedFrom }
errors
}
}
-
stateName— the Terraform state to protect (must be unique per project) -
minimumAccessLevelForWrite— minimum role for write operations:DEVELOPER,MAINTAINER,OWNER, orADMIN -
allowedFrom— source restriction (optional, defaults toANYWHERE):ANYWHERE,CI_ONLY, orCI_ON_PROTECTED_BRANCH_ONLY
Updating a protection rule
mutation {
updateTerraformStateProtectionRule(input: {
id: "gid://gitlab/Terraform::StateProtectionRule/1"
minimumAccessLevelForWrite: OWNER
}) {
terraformStateProtectionRule { id stateName minimumAccessLevelForWrite allowedFrom }
errors
}
}
Supports partial updates — only provided fields are changed.
Deleting a protection rule
mutation {
deleteTerraformStateProtectionRule(input: {
id: "gid://gitlab/Terraform::StateProtectionRule/1"
}) {
terraformStateProtectionRule { id stateName }
errors
}
}
Authorization
- Query: Maintainer+ sees rules; Developer and below sees empty results
- Mutations: Maintainer+ can create/update/delete; lower roles receive a permission error
- Follows the same
admin_terraform_statepermission as existing Terraform state mutations
Feature flag
Gated behind terraform_state_protection_rules (gitlab_com_derisk).
Scope
In scope:
- GraphQL type for protection rules with fields:
id,stateName,minimumAccessLevelForWrite,allowedFrom - Enums for access levels and source restrictions
- Query via
project { terraformStateProtectionRules } - Create, update (partial), and delete mutations
- Specs for all of the above
Out of scope:
- REST API for rules CRUD (separate issue)
- Frontend UI (separate issue)
- Internal events / instrumentation (separate issue)
Reference
This follows the packages protection rules GraphQL pattern.
Implementation checklist
- GraphQL type exposing protection rule fields
-
Enums for access levels (
DEVELOPER,MAINTAINER,OWNER,ADMIN) and source restrictions (ANYWHERE,CI_ONLY,CI_ON_PROTECTED_BRANCH_ONLY) -
Query on
ProjectTypeto list protection rules - Create mutation
- Update mutation with partial update support
- Delete mutation
- Specs for types, enums, query, and all mutations