CI/CD Pipeline¶
This repo runs a GitLab CI pipeline defined in .gitlab-ci.yml. The pipeline enforces security scanning and documentation validity on every change.
Jobs¶
| Job | Stage | Runs On | Purpose |
|---|---|---|---|
secret-detection |
test | Every push, every branch | Detect accidentally committed secrets or credentials |
kics-iac-sast |
test | MRs + main |
Scan OpenTofu IaC for misconfigurations |
semgrep-sast |
test | MRs + main |
General static analysis |
docs-build |
docs | Every push, every branch | Validate MkDocs builds without broken links |
Why Jobs Are Scoped This Way¶
Secret detection runs on every branch because a committed secret is already exposed the moment it is pushed — catching it only on main is too late. The pre-commit hook (see below) provides a first line of defence before the push even happens.
KICS and Semgrep run on MRs and main only because they are slower and their results are most actionable at review time. Terraform misconfiguration findings appear in the GitLab Security Dashboard under Security & Compliance → Vulnerability Report.
Docs build runs on every branch because it is fast (~10s) and gives immediate feedback on broken links regardless of where you are working.
Security Dashboard¶
KICS findings surface as Infrastructure as Code vulnerabilities in the GitLab Security Dashboard. A full Security Dashboard requires GitLab Ultimate; on Free/Premium the individual job reports are still available in the pipeline view.
KICS is configured to scan only the tofu/ directory:
kics-iac-sast:
variables:
SAST_SCANNER_ALLOWED_CLI_OPTS: "--path tofu"
Branch Workflow¶
Never commit directly to main. Always work on a branch named after the Jira ticket:
git checkout -b NVS-123-short-description
# or
git checkout -b NHC-456-short-description
The pre-commit hooks will block any commit on main and reject branch names that don't start with a ticket ID. The pattern enforced is [A-Z]+-[0-9]+ at the start of the branch name.
Pre-Commit Hooks¶
Before changes reach the pipeline, pre-commit hooks enforce the same checks locally. Install once per machine:
python3 -m venv .venv
source .venv/bin/activate
pip install pre-commit
# Do NOT use: sudo apt install pre-commit — the apt version is outdated
Then register both hook types:
pre-commit install # runs on git commit
pre-commit install --hook-type pre-push # runs on git push
| Hook | Purpose |
|---|---|
no-commit-to-main |
Blocks direct commits to main |
jira-branch-name |
Rejects branch names without a Jira ticket ID prefix |
mkdocs-build (Docker) |
Mirrors docs-build CI job |
gitleaks |
Mirrors secret-detection CI job |
detect-private-key |
Mirrors secret-detection CI job |
check-yaml |
Catches malformed YAML in checklists/ |
tofu-fmt |
Keeps OpenTofu diffs clean |
Run all hooks manually at any time:
pre-commit run --all-files
Local Docs Serve¶
To preview the docs site locally before pushing:
docker compose up docs
# then open http://localhost:9001
This uses the same squidfunk/mkdocs-material:9 image as the CI job.