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
- Paste your .gitlab-ci.yml content into the input field
- Click "Inspect" or wait for automatic processing
- Review security findings with severity ratings (Critical, High, Medium, Low)
- Follow the recommendations to harden your pipeline
- 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: truefrom security scanning jobs - Set
expire_inon 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:withif: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.