安全与权限 #

一、安全概述 #

GitLab CI/CD提供了多层次的安全机制,保护代码和部署环境的安全。

text
┌─────────────────────────────────────────────────────────────┐
│                    安全机制层次                              │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  代码安全                    流水线安全                      │
│  ┌─────────────────┐        ┌─────────────────┐            │
│  │ • SAST          │        │ • 变量保护      │            │
│  │ • 依赖扫描      │        │ • Masked变量    │            │
│  │ • 密钥检测      │        │ • 权限控制      │            │
│  └─────────────────┘        └─────────────────┘            │
│                                                              │
│  环境安全                    部署安全                        │
│  ┌─────────────────┐        ┌─────────────────┐            │
│  │ • 环境保护      │        │ • 审批流程      │            │
│  │ • 访问控制      │        │ • 部署窗口      │            │
│  │ • 停止环境      │        │ • 回滚机制      │            │
│  └─────────────────┘        └─────────────────┘            │
│                                                              │
└─────────────────────────────────────────────────────────────┘

二、安全扫描 #

1. SAST(静态应用安全测试) #

启用SAST:

yaml
include:
  - template: Jobs/SAST.gitlab-ci.yml

自定义配置:

yaml
include:
  - template: Jobs/SAST.gitlab-ci.yml

variables:
  SAST_EXCLUDED_PATHS: "vendor,lib"
  SAST_BANDIT_EXCLUDED_PATHS: "tests"

2. 依赖扫描 #

启用依赖扫描:

yaml
include:
  - template: Jobs/Dependency-Scanning.gitlab-ci.yml

自定义配置:

yaml
include:
  - template: Jobs/Dependency-Scanning.gitlab-ci.yml

variables:
  DS_EXCLUDED_PATHS: "vendor"
  DS_MAX_DEPTH: 5

3. 容器扫描 #

启用容器扫描:

yaml
include:
  - template: Jobs/Container-Scanning.gitlab-ci.yml

variables:
  CS_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

4. 密钥检测 #

启用密钥检测:

yaml
include:
  - template: Jobs/Secret-Detection.gitlab-ci.yml

5. 完整安全流水线 #

yaml
stages:
  - test
  - security

include:
  - template: Jobs/SAST.gitlab-ci.yml
  - template: Jobs/Dependency-Scanning.gitlab-ci.yml
  - template: Jobs/Secret-Detection.gitlab-ci.yml

container_scanning:
  stage: security
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
        aquasec/trivy image $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
  allow_failure: true

三、变量安全 #

1. Protected变量 #

Protected变量只在protected分支和tags上可用:

  1. 进入Settings → CI/CD → Variables
  2. 添加变量时勾选"Protect variable"
yaml
deploy_production:
  script:
    - echo $PROD_SECRET_KEY
  only:
    - main

2. Masked变量 #

Masked变量在日志中会被隐藏:

yaml
variables:
  SECRET_TOKEN:
    value: "my-secret-token"
    masked: true

要求:

  • 值必须是单行
  • 符合正则表达式:[a-zA-Z0-9_+=/.:@-]+
  • 至少8个字符

3. 文件变量 #

敏感文件使用文件变量:

yaml
variables:
  SSH_KEY:
    type: file
    value: |
      -----BEGIN RSA PRIVATE KEY-----
      ...
      -----END RSA PRIVATE KEY-----

deploy:
  script:
    - chmod 600 $SSH_KEY
    - ssh -i $SSH_KEY user@server

4. 变量作用域 #

yaml
deploy_staging:
  environment:
    name: staging
  variables:
    DEPLOY_KEY: $STAGING_KEY

deploy_production:
  environment:
    name: production
  variables:
    DEPLOY_KEY: $PRODUCTION_KEY

四、权限控制 #

1. 流水线权限 #

Settings → CI/CD → General pipelines:

设置 说明
Public pipelines 公开流水线
Allow pipeline triggers 允许触发流水线
CI/CD access token 访问令牌

2. 环境权限 #

Settings → CI/CD → Protected environments:

yaml
deploy_production:
  stage: deploy
  environment:
    name: production
  script:
    - echo "Deploying..."
  only:
    - main

3. 变量权限 #

Settings → CI/CD → Variables:

设置 说明
Protect variable 只在protected分支可用
Mask variable 在日志中隐藏
Environments 限制环境

4. Job权限 #

yaml
deploy_production:
  stage: deploy
  environment:
    name: production
  script:
    - echo "Deploying..."
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
      when: manual
      allow_failure: false

五、环境保护 #

1. Protected Environments #

Settings → CI/CD → Protected environments:

  1. 点击"Protect an environment"
  2. 选择环境名称
  3. 设置允许的用户/角色
  4. 设置允许的分支

2. 环境配置 #

yaml
deploy_production:
  stage: deploy
  environment:
    name: production
    url: https://example.com
    deployment_tier: production
  script:
    - echo "Deploying..."
  only:
    - main
  when: manual

3. 环境停止 #

yaml
deploy_staging:
  stage: deploy
  environment:
    name: staging
    url: https://staging.example.com
    on_stop: stop_staging
  script:
    - echo "Deploying to staging"

stop_staging:
  stage: deploy
  environment:
    name: staging
    action: stop
  script:
    - echo "Stopping staging"
  when: manual
  only:
    - develop

4. 环境审批 #

yaml
deploy_production:
  stage: deploy
  environment:
    name: production
  script:
    - echo "Deploying..."
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
      when: manual
      allow_failure: false

六、密钥管理 #

1. GitLab变量 #

yaml
variables:
  DATABASE_URL: "postgres://user:pass@host:5432/db"
  API_KEY: "your-api-key"

2. 外部密钥管理 #

HashiCorp Vault #

yaml
variables:
  VAULT_ADDR: "https://vault.example.com"
  VAULT_TOKEN: "your-token"

deploy:
  script:
    - export DB_PASSWORD=$(vault kv get -field=password secret/db)

AWS Secrets Manager #

yaml
deploy:
  script:
    - export DB_PASSWORD=$(aws secretsmanager get-secret-value --secret-id db-password --query SecretString --output text)

3. CI/CD变量最佳实践 #

yaml
variables:
  APP_NAME: "myapp"
  REGISTRY: "registry.example.com"

deploy:
  script:
    - echo "Deploying $APP_NAME to $REGISTRY"

七、安全最佳实践 #

1. 最小权限原则 #

yaml
deploy_staging:
  environment:
    name: staging
  script:
    - echo "Deploying..."
  rules:
    - if: $CI_COMMIT_BRANCH == "develop"

2. 分离环境密钥 #

yaml
deploy_staging:
  variables:
    DEPLOY_KEY: $STAGING_KEY
  environment:
    name: staging

deploy_production:
  variables:
    DEPLOY_KEY: $PRODUCTION_KEY
  environment:
    name: production
  when: manual

3. 使用Protected变量 #

yaml
deploy_production:
  script:
    - echo $PROD_SECRET
  only:
    - main

4. 启用安全扫描 #

yaml
include:
  - template: Jobs/SAST.gitlab-ci.yml
  - template: Jobs/Dependency-Scanning.gitlab-ci.yml
  - template: Jobs/Secret-Detection.gitlab-ci.yml

5. 限制镜像来源 #

yaml
variables:
  DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

build:
  script:
    - docker pull $DOCKER_IMAGE

6. 审计日志 #

Settings → Audit Events:

  • 查看所有CI/CD操作日志
  • 监控敏感操作
  • 设置告警

八、安全流水线示例 #

yaml
stages:
  - test
  - security
  - build
  - deploy

include:
  - template: Jobs/SAST.gitlab-ci.yml
  - template: Jobs/Dependency-Scanning.gitlab-ci.yml
  - template: Jobs/Secret-Detection.gitlab-ci.yml

variables:
  REGISTRY: $CI_REGISTRY
  IMAGE_NAME: $CI_REGISTRY_IMAGE

test:
  stage: test
  image: node:18
  script:
    - npm ci
    - npm test
  coverage: '/Coverage: \d+%/'

security_gate:
  stage: security
  script:
    - echo "Checking security scan results..."
    - |
      if [ -f "gl-sast-report.json" ]; then
        high_vulnerabilities=$(jq '.vulnerabilities | map(select(.severity == "High" or .severity == "Critical")) | length' gl-sast-report.json)
        if [ "$high_vulnerabilities" -gt 0 ]; then
          echo "Found $high_vulnerabilities high/critical vulnerabilities"
          exit 1
        fi
      fi
  allow_failure: false

build:
  stage: build
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build -t $IMAGE_NAME:$CI_COMMIT_SHA .
    - docker push $IMAGE_NAME:$CI_COMMIT_SHA

deploy_staging:
  stage: deploy
  image: bitnami/kubectl:latest
  environment:
    name: staging
    url: https://staging.example.com
  script:
    - kubectl set image deployment/myapp myapp=$IMAGE_NAME:$CI_COMMIT_SHA
  only:
    - develop

deploy_production:
  stage: deploy
  image: bitnami/kubectl:latest
  environment:
    name: production
    url: https://example.com
  script:
    - kubectl set image deployment/myapp myapp=$IMAGE_NAME:$CI_COMMIT_SHA
  only:
    - main
  when: manual
  allow_failure: false

下一步 #

现在你已经掌握了安全与权限,接下来让我们学习 父子流水线

最后更新:2026-03-28