| name | gitlab-ci-security-basics |
| description | Harden GitLab CI/CD for owned projects: .gitlab-ci.yml trust boundaries, protected/masked variables, environment protection, CI_JOB_TOKEN least privilege, runner isolation, fork/MR secret exposure, include/template supply chain, and deploy gates. Use when GitLab CI security, .gitlab-ci.yml review, CI/CD variables, protected environments, CI_JOB_TOKEN, shared runners, pipeline secrets, merge request pipelines, include remote, or GitLab deploy job hardening.
|
GitLab CI Security Basics
Secure GitLab CI/CD for repositories and groups you own or are authorized
to harden. Prefer existing group/instance policies and shared templates over a
parallel pipeline stack. Pair general stage/cache design with
ci-cd-pipeline-patterns and secret lifecycle with secrets-management-hygiene.
When To Use
- Authoring or reviewing
.gitlab-ci.yml, *.gitlab-ci.yml includes, or CI components
- CI/CD variables (masked, protected, environment-scoped, file type) and secret leakage
- Protected branches/tags, protected environments, and manual prod deploy gates
CI_JOB_TOKEN, project/group access tokens, deploy tokens, and job permissions
- Shared vs project runners, privileged Docker, Docker socket, and shell runners
- Fork / external MR pipelines and rules that must not receive protected secrets
- Mentions: GitLab CI security, pipeline secrets, MR pipeline trust, include remote,
CI_JOB_TOKEN, protected environment, 流水线安全
Do not use as primary for:
| Need | Skill instead |
|---|
| Multi-platform CI stages, cache keys, fail-fast layout | ci-cd-pipeline-patterns |
| Secret inventory, vault, rotation, .env hygiene | secrets-management-hygiene |
| Branch/MR approval, force-push, CODEOWNERS gates | branch-protection-rules |
| Dockerfile non-root / layer secrets | dockerfile-best-practices |
| SBOM generate/attest gates | sbom-ci-enforcement |
| App code quality inside jobs | code-quality-standards |
Repo Config First
Group, instance, and project CI settings outrank examples in this skill.
- Pipeline files: root
.gitlab-ci.yml, include: local/project/remote/component paths, CI/CD Catalog usage
- CI/CD variables: project vs group vs instance; protected/masked/expanded; environment scope; file vs env
- Protected refs: protected branches/tags that unlock protected variables and deploy jobs
- Environments: protected environments, required approvers, deployment tiers (prod vs review)
- Runners: shared, group, or project; tags; executor (docker/kubernetes/shell); privileged flag
- Token policy: CI job token allowlist / inbound job token scope; project access token lifetime
- MR pipeline mode: merge request pipelines, merged results, fork trust, secret exposure to MRs
- Compliance: required pipeline config, scan execution policies, secret push protection if licensed
Precedence: Documented group/instance policy wins. Flag unprotected prod
variables, privileged shared runners on untrusted code, and remote includes
without pin or ownership.
Workflow
-
Map trust levels. Separate jobs for: fork/external MR → internal MR →
default branch → tag/release → manual/scheduled prod. Never give lower-trust
pipelines the same variables or runner tags as prod deploy.
-
Lock secrets to protected paths.
- Mark deploy/prod variables protected + masked (or file type); scope
by environment (
production, not *)
- Ensure only protected branches/tags run jobs that need those variables
- Disable or carefully control “Expand variable reference” for untrusted input
- Prefer OIDC/JWT (
id_tokens) to cloud roles over long-lived AK/SK in variables
-
Control who can run privileged work.
- Prod deploy:
environment: production + protected environment approvals +
rules limited to default branch or tags; prefer when: manual for prod
- Deny deploy on
merge_request_event and untrusted sources
- Pin images (
image: registry/image:tag@sha256:… when policy requires)
-
Harden CI_JOB_TOKEN and tokens.
- Limit job token access to needed projects (allowlist / limit outbound)
- Do not grant API
api scope tokens to every pipeline; use least privilege
- Never echo tokens; avoid
set -x around auth; mask custom variables
- Rotate project/group access tokens and deploy tokens on schedule and on leak
-
Runner and executor isolation.
- Prefer docker/k8s executors over shell for multi-tenant; no
privileged: true
unless buildkit/dind is required and job code is trusted
- Never mount
docker.sock into jobs that run untrusted MR code
- Tag sensitive runners (
prod-deploy) and select them only from trusted rules
- Treat shared runners as hostile multi-tenant: no host secrets, no privileged
-
Supply chain of pipeline config.
- Prefer
include: local or same-group project includes; pin remote/component
refs to immutable SHA or version, not floating main
- Review third-party CI components like application deps; own critical templates
Routing
| Situation | Primary | Helper |
|---|
| GitLab CI secrets, runners, job token, MR trust, includes, protected envs | This skill | — |
| Generic multi-CI stages, caching, fail-fast, artifacts layout | ci-cd-pipeline-patterns | this skill for GitLab controls |
| Vault/rotation/.env/secret inventory | secrets-management-hygiene | this skill for GitLab variable flags |
| Protected branch/MR approvals, force-push | branch-protection-rules | this skill for CI variable unlock on protected refs |
| Image build hygiene | dockerfile-best-practices | this skill for job image/dind risk |
| SBOM gate in pipeline | sbom-ci-enforcement | this skill for job trust level |
| Scripts/YAML quality | code-quality-standards | always with implementation |
Output Checklist