GitLab CI Inspector

Detect security issues in GitLab CI pipelines: exposed secrets, insecure images, dangerous allow_failure, and runner misconfigurations

Enter your .gitlab-ci.yml to scan for security vulnerabilities and misconfigurations

What is the GitLab CI Inspector?

The GitLab CI Inspector is a client-side security tool that analyzes your .gitlab-ci.yml pipeline definitions for vulnerabilities. It detects exposed secrets in scripts, insecure image references, dangerous allow_failure patterns on security jobs, missing artifact expiry, privileged Docker-in-Docker services, and deployment jobs running on shared runners — then calculates a security score with prioritized remediation recommendations.

How to Use

  1. Paste your .gitlab-ci.yml content into the input field
  2. Click "Inspect" or wait for automatic processing
  3. Review security findings with severity ratings (Critical, High, Medium, Low)
  4. Follow the recommendations to harden your pipeline
  5. Export a full security report in JSON or Markdown format

Example: Pipeline with Security Issues

This pipeline has multiple security vulnerabilities the inspector will detect:

image: node:latest

variables:
  DB_PASSWORD: "super_secret_123"

build:
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/

sast:
  stage: test
  allow_failure: true
  script:
    - run-sast-scanner

deploy_production:
  stage: deploy
  image: my-registry.evil.com/deployer:latest
  services:
    - docker:24-dind
  script:
    - api_key="sk-proj-abc123def456"
    - ./deploy.sh
  environment:
    name: production

What Security Issues Are Detected?

  • Exposed secrets in scripts — Hardcoded passwords, API keys, tokens, and credentials in script blocks
  • Unprotected variables — Sensitive values (passwords, tokens, keys) defined in plaintext in the pipeline file
  • Insecure image references — Using :latest tag or images from unverified registries
  • Dangerous allow_failure — Security-critical jobs (SAST, DAST, scanning) that are allowed to fail
  • Missing artifact expiry — Artifacts without expire_in stored indefinitely
  • Shared runner on sensitive jobs — Deployment or production jobs without specific runner tags
  • Docker-in-Docker (privileged) — Services requiring privileged mode with container escape risk

Security Scoring

Each pipeline receives a security score from 0 to 100 based on detected findings. Severity weights are: Critical (25 points deducted), High (15 points), Medium (8 points), Low (3 points). The score maps to a letter grade: A (90+), B (75+), C (60+), D (40+), F (below 40).

GitLab CI Security Best Practices

  • Pin images to specific versions or SHA digests — never use :latest
  • Store secrets in CI/CD Variables with "Protected" and "Masked" flags — never in .gitlab-ci.yml
  • Remove allow_failure: true from security scanning jobs
  • Set expire_in on all artifact definitions to manage storage
  • Use dedicated runners with specific tags for deployment and production jobs
  • Avoid Docker-in-Docker when possible — use kaniko or buildah for container builds
  • Enable protected branches and require merge request approvals before deploying
  • Use rules: with if: conditions to control when sensitive jobs run

Supply Chain Security in GitLab CI

Container images used in CI pipelines are a common attack vector. When you reference an image by mutable tag (e.g., node:latest), a compromised registry or upstream maintainer can inject malicious code that runs in your pipeline with access to your secrets and deployment credentials. Pin images to immutable digests or specific versions to ensure reproducible, tamper-resistant builds.

Privacy and Security

All inspection happens entirely in your browser using JavaScript. Your .gitlab-ci.yml files — which may contain sensitive information like variable names, infrastructure details, and deployment configurations — never leave your device. No data is stored, logged, or transmitted.

Frequently Asked Questions

What security issues does the GitLab CI Inspector detect?

The inspector detects exposed secrets in scripts (hardcoded passwords, API keys, GitLab tokens, AWS keys), sensitive variables defined in plaintext, insecure image references (using :latest or unverified registries), dangerous allow_failure on security jobs, missing artifact expiry, use of Docker-in-Docker (privileged mode), and deployment jobs running on shared runners without specific tags.

How is the security score calculated?

The score starts at 100 and deducts points based on finding severity: Critical issues (exposed secrets) deduct 25 points, High issues (insecure images, unprotected variables, privileged services) deduct 15, Medium issues (dangerous allow_failure, shared runner on sensitive jobs) deduct 8, and Low issues (missing artifact expiry) deduct 3. Grades map to: A (90+), B (75+), C (60+), D (40+), F (below 40).

Why should I avoid using :latest tag in CI images?

The :latest tag is mutable — it can point to different image versions over time. This means your pipeline may break unexpectedly when the upstream image changes, or worse, a compromised image could be pushed as :latest. Pin images to specific versions (e.g., node:20.11.0-alpine) or SHA digests for reproducible and secure builds.

What is wrong with allow_failure on security jobs?

When allow_failure is true on security-related jobs (SAST, DAST, dependency scanning, secret detection), the pipeline passes even if vulnerabilities are found. This defeats the purpose of security gates and may allow vulnerable code to reach production. Remove allow_failure from security-critical jobs to enforce security policies.

Why are artifacts without expire_in flagged?

GitLab stores job artifacts indefinitely if no expire_in is specified (unless instance-level defaults override this). Over time, this consumes significant project storage and may retain sensitive build outputs longer than necessary. Setting expire_in (e.g., 1 week, 30 days) ensures artifacts are cleaned up automatically.

What is the risk of Docker-in-Docker (dind) in GitLab CI?

Docker-in-Docker requires the runner to operate in privileged mode, which grants the container near-full access to the host system. A malicious job or compromised dependency could exploit this to escape the container. Alternatives like kaniko or buildah can build images without privileged mode.

Why should deployment jobs use specific runner tags?

Shared runners are accessible to all projects on a GitLab instance. Running deployment jobs (which typically access production secrets) on shared runners means other projects' jobs execute on the same infrastructure. Specific runner tags ensure sensitive jobs run on dedicated, project-specific runners with appropriate isolation.

How should I handle secrets in GitLab CI pipelines?

Never hardcode secrets in .gitlab-ci.yml. Use GitLab CI/CD Variables (Settings → CI/CD → Variables) with the 'Protected' flag (only available on protected branches) and 'Masked' flag (hidden in logs). For external secrets, integrate with HashiCorp Vault or other secret managers via GitLab's native integration.

Does the inspector support included configurations?

The inspector analyzes the YAML content you paste directly. If your pipeline uses include: directives to pull in remote or local templates, paste the resolved/merged configuration for complete analysis. The inspector will detect issues in whatever content is provided.

Is my .gitlab-ci.yml file sent to any server?

No. All analysis happens entirely in your browser using JavaScript. Your GitLab CI configuration — which may contain sensitive information like variable names, infrastructure details, and deployment targets — never leaves your device. No data is stored, logged, or transmitted.