Validates .gitlab-ci.yml syntax, detects security misconfigurations in job definitions, checks for deprecated keywords, ensures proper stage ordering, and audits pipeline configurations for best practices. Use when working with .gitlab-ci.yml files, validating GitLab CI/CD pipeline syntax, debugging configuration errors, checking for hardcoded secrets or credentials in pipeline jobs, optimizing pipeline performance with DAG or cache, or performing security audits on GitLab CI/CD configurations.
91%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Validates, lints, tests, and secures GitLab CI/CD pipeline configurations (.gitlab-ci.yml files) across three layers: syntax/schema validation, best practices analysis, and security scanning.
gitlab-ci-local..gitlab-ci.yml change before merging.curl | bash patterns or SSL bypasses.include: entries, components and needs graphs for problems.bash scripts/validate_gitlab_ci.sh --syntax-only .gitlab-ci.ymlChecks: YAML structure, GitLab CI schema compliance, job definitions, stage references, dependency graphs (needs/dependencies/extends), include configurations (component, project, remote, local, template), circular dependency detection, and GitLab limits (500 jobs max, 255-char job names, 50 max needs, 100 max components).
Action: Fix all syntax errors before proceeding.
bash scripts/validate_gitlab_ci.sh --best-practices .gitlab-ci.ymlChecks: Cache usage for dependency installation, artifact expiration settings, DAG optimization with needs, parallel execution opportunities, Docker image version pinning, deprecated only/except → rules migration, missing timeouts and retries, resource group usage.
Action: Review suggestions and apply relevant optimizations.
bash scripts/validate_gitlab_ci.sh --security-only .gitlab-ci.ymlChecks: Hardcoded secrets and credentials, component security (version pinning, trusted sources), remote include integrity, insecure script patterns (curl | bash, eval), SSL/TLS verification bypasses, dangerous file permissions (chmod 777), overly broad artifact paths, variable masking, path traversal in local includes.
Action: Fix all critical and high-severity issues immediately.
# Install gitlab-ci-local first (requires Docker and Node.js)
bash scripts/install_tools.sh
# Test pipeline locally
gitlab-ci-local
# Or via the validator script
bash scripts/validate_gitlab_ci.sh --test-only .gitlab-ci.ymlSimulates local pipeline execution to test job ordering, dependencies, and environment setup. Requires Docker and gitlab-ci-local.
# Full validation (all three layers)
bash scripts/validate_gitlab_ci.sh .gitlab-ci.yml
# Strict mode (fail on warnings)
bash scripts/validate_gitlab_ci.sh .gitlab-ci.yml --strictbash scripts/validate_gitlab_ci.sh .gitlab-ci.yml --syntax-only
bash scripts/validate_gitlab_ci.sh .gitlab-ci.yml --best-practices
bash scripts/validate_gitlab_ci.sh .gitlab-ci.yml --security-only
bash scripts/validate_gitlab_ci.sh .gitlab-ci.yml --no-best-practices
bash scripts/validate_gitlab_ci.sh .gitlab-ci.yml --no-security
bash scripts/validate_gitlab_ci.sh .gitlab-ci.yml --strictpython3 scripts/validate_syntax.py .gitlab-ci.yml
python3 scripts/check_best_practices.py .gitlab-ci.yml
python3 scripts/check_security.py .gitlab-ci.yml════════════════════════════════════════════════════════════════════════════════
Validation Summary
════════════════════════════════════════════════════════════════════════════════
Syntax Validation: PASSED
Best Practices: WARNINGS
Security Scan: PASSED
✓ All validation checks passedstages:
- validate
validate_pipeline:
stage: validate
script:
- pip3 install PyYAML
- bash scripts/validate_gitlab_ci.sh .gitlab-ci.yml --strictAdd custom rules directly to the relevant script:
# In check_best_practices.py
def _check_custom_rule(self):
"""Check for custom organization rule"""
for job_name, job in self.config.items():
if not self._is_job(job_name):
continue
if 'tags' not in job:
self.issues.append(BestPracticeIssue(
'warning',
self._get_line(job_name),
f"Job '{job_name}' should specify runner tags",
'custom-missing-tags',
"Add 'tags' to select appropriate runners"
))scripts/validate_syntax.pyscripts/check_best_practices.pyscripts/check_security.pypip3 install PyYAMLgitlab-ci-localWHY: Local execution without pre-validation produces obscure runtime errors; resolve schema and syntax errors first to get actionable output.
BAD: Run gitlab-ci-local on an untested config and debug runtime failures.
GOOD: Run bash scripts/validate_gitlab_ci.sh --syntax-only .gitlab-ci.yml first; proceed to local testing only after syntax passes.
only/except deprecation warningsWHY: Pipelines using deprecated keywords will break when GitLab removes them; treat these as errors, not warnings.
BAD: Leave only: [main] after the validator flags it as deprecated.
GOOD: Migrate to rules: syntax during the same fix session.
include: targetsWHY: A valid base file with an invalid include template causes mysterious pipeline failures at queue time.
BAD: Validate only .gitlab-ci.yml and skip templates/*.yml includes.
GOOD: Validate all local include files as well; the validator checks include:local paths automatically.
--strict as the first validation step on an unfamiliar pipelineWHY: Strict mode fails on warnings and produces noise that obscures real errors; establish a baseline first.
BAD: Run --strict on an inherited pipeline and skip the output because it has 50 warnings.
GOOD: Run without --strict first; fix errors and critical warnings, then enable strict mode as a CI gate.
WHY: The security layer flags hardcoded credentials and tokens in scripts and variables (for example [variable-hardcoded-secret], [api-key]). Committed secrets persist in history even after removal.
BAD: variables: { API_KEY: "abc123" } in .gitlab-ci.yml.
GOOD: Define the value as a masked, protected CI/CD variable in project settings and reference $API_KEY.
WHY: The scan reports [curl-pipe-bash] and [wget-pipe-bash]. The job runs whatever the remote host serves at that moment.
BAD: script: - curl -s https://example.com/install.sh | bash.
GOOD: Use a pinned image that already contains the tool, or download, verify and then run the file.
latest tagsWHY: The best-practices layer reports [image-latest-tag] and [image-no-version]. A floating tag means the same commit can build differently on different days.
BAD: image: node:latest.
GOOD: image: node:20.11-alpine, or a digest.
WHY: The validator reports [include-component-no-version], [include-component-latest-version] and [include-project-unpinned]. An upstream change to the included file alters your pipeline with no change in your repository.
BAD: include: - project: group/ci-templates with no ref.
GOOD: Pin ref: to a tag or commit, and pin component versions to a semantic version.
WHY: The best-practices layer reports [artifact-no-expiration]. Artifacts with no expiry accumulate and consume storage.
BAD: artifacts: { paths: [dist/] } with no expire_in.
GOOD: Add expire_in: 1 week (or a value that fits the job).
WHY: The security layer flags verification bypasses ([insecure-ssl], [skip-verification]). It removes protection against tampering with downloaded content.
BAD: script: - git config --global http.sslVerify false.
GOOD: Fix the certificate chain or install the corporate CA in the job image.
references/gitlab-ci-reference.md: Complete GitLab CI/CD YAML syntax referencereferences/best-practices.md: Detailed best practices guidereferences/common-issues.md: Common issues and solutionsscripts/: rule definitions live in validate_syntax.py, check_best_practices.py and check_security.pyassets/basic-pipeline.gitlab-ci.yml: Simple three-stage pipelineassets/docker-build.gitlab-ci.yml: Docker build and push workflowassets/multi-stage.gitlab-ci.yml: Multi-stage pipeline with DAGassets/complex-workflow.gitlab-ci.yml: Advanced workflow with all featuresassets/component-pipeline.gitlab-ci.yml: GitLab 17.0+ pipeline using CI/CD components# Test with examples
bash scripts/validate_gitlab_ci.sh assets/basic-pipeline.gitlab-ci.yml
bash scripts/validate_gitlab_ci.sh assets/component-pipeline.gitlab-ci.ymlWhen encountering custom GitLab features or version-specific requirements, this skill can:
Note: This skill validates GitLab CI/CD configurations but does not execute pipelines. Use GitLab's CI Lint tool or gitlab-ci-local for testing actual pipeline execution.
pantheon-org/tekhne
9aa89e5
Also appears in
last in sync Aug 28, 2026
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.