# CI/CD Goat — Pipeline Security Lab

> **Intro:** CI/CD Goat is one of the most practical ways to teach why pipeline trust matters. It gives you a deliberately vulnerable CI/CD environment with source control, runners, Jenkins, GitLab, and challenge flow in one place.
>
> **What this page includes**
>
> * what CI/CD Goat teaches better than generic slides;
> * how to run it quickly with Docker Compose;
> * how to use it for DevSecOps review practice;
> * how to connect the scenarios to release controls and runner design.

## What it is

CI/CD Goat is a deliberately vulnerable CI/CD environment designed around multiple hands-on challenges. The environment includes components such as:

* Gitea;
* Jenkins;
* Jenkins agent;
* LocalStack;
* a “Prod” component with Docker-in-Docker and a web service;
* CTFd;
* GitLab;
* GitLab runner;
* Docker-in-Docker services.

That makes it much closer to a **real pipeline trust-chain learning environment** than a single vulnerable app.

## Why it is valuable

This lab is strong when you want learners to understand:

* why runners and build agents are privileged systems;
* how tokens, repositories, artifacts, and deployment identities connect;
* why CI/CD security is not only a YAML linting problem;
* how build-system compromise becomes a release compromise.

## Best fit

| Persona                   | Fit       | Why                                                         |
| ------------------------- | --------- | ----------------------------------------------------------- |
| DevSecOps engineer        | Very high | It is almost purpose-built for this role                    |
| Product Security engineer | High      | Useful for release trust and supply-chain reviews           |
| Platform engineer         | High      | Great for runner isolation and deployment trust discussions |
| Newcomer                  | Medium    | Best after some familiarity with Git and CI concepts        |

## Run model

CI/CD Goat is best treated as a **local lab on a VM or workstation** that can run Docker Compose comfortably. For most learners, that means:

* a Linux VM, cloud VM, or strong local machine;
* enough CPU and memory for several containers;
* isolated host and network context.

## Quick start — Linux or macOS

```bash
curl -o cicd-goat/docker-compose.yaml --create-dirs   https://raw.githubusercontent.com/cider-security-research/cicd-goat/main/docker-compose.yaml
cd cicd-goat
docker compose up -d
```

This is a very fast way to get a working lab without cloning the whole repository first.

## Quick start — Windows PowerShell

```powershell
mkdir cicd-goat; cd cicd-goat
curl -o docker-compose.yaml https://raw.githubusercontent.com/cider-security-research/cicd-goat/main/docker-compose.yaml
get-content docker-compose.yaml | %{$_ -replace "bridge","nat"}
docker compose up -d
```

## How to use it without spoiling the learning value

The official instructions explicitly warn that the repository contains spoilers. That warning is worth respecting.

A good study pattern is:

1. start the environment;
2. discover the moving parts from the running system itself;
3. take notes on trust boundaries;
4. only later compare your notes to official solutions.

## What to focus on during review

Do not reduce the lab to “find the flag”. Use it to answer:

* which identities can trigger builds or deploys?
* which secrets are exposed to runners or agents?
* how are artifacts promoted?
* where could poisoned pipeline execution happen?
* what approvals are present, missing, or bypassable?

## Suggested learning sequence

### Pass 1 — map the trust chain

* repo;
* pipeline config;
* runner or agent;
* artifact store;
* deployment target.

### Pass 2 — ask what could be poisoned

* source checkout;
* dependency resolution;
* build image;
* runner environment;
* artifact promotion;
* deploy credentials.

### Pass 3 — write the defensive recommendations

* runner isolation model;
* protected environments;
* separation of build and deploy identities;
* artifact signing or verification;
* tighter token scope and secret exposure rules.

## Great follow-up pages in this KB

* [Runner Isolation and Trust Boundaries](/devsecops-cicd-and-supply-chain/index-1/runner-isolation-and-trust-boundaries.md)
* [Protected Environments and Deployment Approvals](/devsecops-cicd-and-supply-chain/index-1/protected-environments-and-deployment-approvals.md)
* [Security Quality Gates and Release Blocking](/devsecops-cicd-and-supply-chain/index-1/security-quality-gates-and-release-blocking.md)
* [GitLab CI YAML Deep Dive](/devsecops-cicd-and-supply-chain/index-1/gitlab-ci-yaml-deep-dive.md)
* [Worked Example Tabletop: CI Runner Compromise Before Release](https://github.com/D3One/Product-Security-Gitbook/blob/main/22-learning-paths-and-labs/worked-example-ci-runner-compromise-tabletop.md)

## Common mistakes

* running it on a machine that already hosts important Docker workloads;
* treating every challenge as if it were independent from runner trust;
* focusing only on secrets and ignoring artifact integrity or deploy authorization;
* browsing solution material too early.

## Cleanup

```bash
docker compose down -v
```

If you changed the environment or created extra volumes or networks, inspect and remove them separately.

## References

* Official project: <https://github.com/cider-security-research/cicd-goat>
* Official README and usage instructions in the repository

\---*Author attribution: Ivan Piskunov, 2026 - Educational and defensive-engineering use.*


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.product-security.expert/learning-labs-interview-and-templates/index-2/cicd-goat-pipeline-security-lab.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
