Pipeline-Based Access Control
Pipeline-Based Access Control
CI/CD pipelines introduce another access control layer between code repositories and cloud environments. Pipeline permissions determine who can trigger deployments, approve stages, and access deployment logs. Modern pipeline platforms provide sophisticated RBAC models that integrate with enterprise identity providers.
Stage-based approvals enable different teams to control different deployment phases. Security teams might approve security scanning stages, while operations teams approve production deployments. These approvals can be manual for critical changes or automated based on predefined criteria.
# Example GitLab CI/CD pipeline with RBAC controls
stages:
- validate
- plan
- security-review
- deploy-dev
- deploy-staging
- deploy-prod
variables:
TF_ROOT: ${CI_PROJECT_DIR}/infrastructure
TF_STATE_NAME: ${CI_PROJECT_NAME}-${CI_ENVIRONMENT_NAME}
.terraform_init: &terraform_init
- cd ${TF_ROOT}
- terraform init
-backend-config="key=${TF_STATE_NAME}"
-backend-config="bucket=${STATE_BUCKET}"
-backend-config="region=${AWS_DEFAULT_REGION}"
validate:
stage: validate
script:
- *terraform_init
- terraform fmt -check=true
- terraform validate
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
plan:
stage: plan
script:
- *terraform_init
- terraform plan -out=tfplan
- terraform show -json tfplan > tfplan.json
artifacts:
paths:
- ${TF_ROOT}/tfplan
- ${TF_ROOT}/tfplan.json
expire_in: 7 days
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
security-review:
stage: security-review
script:
- checkov -f tfplan.json --framework terraform_plan
- opa eval -d policies/ -i tfplan.json "data.terraform.deny[_]"
artifacts:
reports:
terraform: ${TF_ROOT}/tfplan.json
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
deploy-dev:
stage: deploy-dev
environment:
name: development
script:
- *terraform_init
- terraform apply -auto-approve
rules:
- if: '$CI_COMMIT_BRANCH == "develop"'
when: manual
only:
- develop
deploy-staging:
stage: deploy-staging
environment:
name: staging
script:
- assume-role ${STAGING_ROLE_ARN}
- *terraform_init
- terraform apply -auto-approve
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: manual
allow_failure: false
only:
- main
needs:
- job: deploy-dev
optional: true
deploy-prod:
stage: deploy-prod
environment:
name: production
script:
- assume-role ${PROD_ROLE_ARN}
- *terraform_init
- terraform apply -auto-approve
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: manual
allow_failure: false
only:
- main
needs:
- job: deploy-staging
- job: security-approval
allow_failure: false
security-approval:
stage: deploy-prod
script:
- echo "Security team approval required"
when: manual
only:
- main
allow_failure: false
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: manual
# Restricted to security team members
only:
variables:
- $GITLAB_USER_LOGIN =~ /^(security-lead|security-admin|ciso)$/
Environment-specific permissions ensure teams can only deploy to appropriate environments. Junior developers might deploy to development environments while senior engineers handle staging deployments. Production deployments often require special authorization or multiple approvals from different teams.