Threat Modelling in CI/CD
🌟 Objective
To define how to ensure - in a testable and automatable way - that the threat modelling activity:
- Has been carried out and is up to date;
- Has produced traceable artefacts that are useful to the project;
- Has influenced real decisions and security controls;
- Is integrated into the lifecycle via CI/CD;
- Meets the requirements of frameworks such as NIST SSDF, SAMM or SLSA.
📌 Minimum requirements per project
The presence of threat modelling cannot be merely symbolic: it must result in traceable artefacts, effective controls and measurable validations.
| Mandatory element | Description |
|---|---|
| Versioned threat model | DFD diagram (dfd.drawio, dfd.mmd), threat list (threats.yaml) |
| Threat → requirement → control mapping | mitigations.md file with status and cross-reference |
| Documented justifications for accepted risks | decisions.md file with date, author and reason for acceptance |
| Traceability in the backlog or code | Identifiers such as TM-001 or ACC-003 referenced in PRs/issues |
| Date of last review | last_reviewed field in a threat-model.yml file |
🧲 How to validate in the pipeline (CI/CD)
The CI/CD pipeline must verify not only that the files are present, but also whether they:
- Are up to date with respect to changes in the code;
- Were used as the basis for development decisions;
- Generated related tickets, commits or tests.
| Stage | Recommended validation |
|---|---|
pre-commit | Mandatory files exist (dfd, threats.yaml) |
build | Linting of the models (yaml, mermaid), parsing of mitigations.md |
security test | Threat → control link exists (or has a justification) |
release | Last review has been carried out + critical threats have defined plans |
✅ Minimum compliance CI/CD checklist
| Item | Verified |
|---|---|
/threat-model/ structure present in the repository | ☑️ |
Main files exist (dfd, threats.yaml, mitigations) | ☑️ |
mitigations.md or yaml file has a defined state per threat | ☑️ |
decisions.md documents accepted risks with date + justification | ☑️ |
Commits or issues reference threats (TM-001, etc.) | ☑️ |
| Model reviewed within the cadence of Policy 08 and ≤ 30 days after the latest architectural change | ☑️ |
📂 Suggested structure of the model
📁 threat-model/
📌 README.md # âmbito e método
📌 dfd.drawio # Diagrama técnico ou .mmd (Mermaid)
📌 threats.yaml # Lista de ameaças (id, descrição, severidade, requisito associado)
📌 mitigations.md # Tabela com status (mitigado, em curso, aceite)
📌 decisions.md # Justificações de risco aceite
📌 threat-model.yml # Metadados: última revisão, revisores, etc.
🛠️ Practical examples and automated validations
Artefact linting:
- name: Verificar syntax YAML
run: yamllint threat-model/threats.yaml
Cross-reference validation:
grep -E 'TM-[0-9]{3}' threat-model/mitigations.md \
| while read threat_id; do
git log --oneline | grep "$threat_id" || echo "❌ Threat $threat_id sem commit associado"
done
Checking the last review:
REVIEWED=$(yq '.last_reviewed' threat-model/threat-model.yml)
if [ "$REVIEWED" < "$(date -d '30 days ago' +%F)" ]; then
echo "❌ Threat model desatualizado"; exit 1;
fi
🔄 Integration with IriusRisk
🧠 What IriusRisk can do automatically:
| Capability | Detail |
|---|---|
| Derive threats based on components | Templates model threats by type (e.g. JWT, API, S3) |
| Generate requirements and controls | Automatic, with criticality and state |
| Export data via API | JSON/YAML for integration with CI/CD |
| Create tickets in Jira / ADO | Integration with backlog flows |
🧲 What still needs to be verified in CI/CD:
| Required validation | How to Do It |
|---|---|
| Do the exported threats have a control applied? | Scripts cross-check IDs against code, PRs or tests |
| Are the justifications documented? | decisions.md extracted from IriusRisk or maintained locally |
| Was the review recent? | Check metadata or synchronisation via API |
⚠️ Expected pipeline behaviour
| Type of failure | Recommended pipeline reaction |
|---|---|
| Model missing | ❌ Critical failure |
| Outdated model (> 30 days after an architectural change, or outside the cadence of Policy 08) | ⚠️ Alert + conditional block |
| Threats neither mitigated nor justified | ⚠️ Warning + requires issue/document |
| Linting fails (invalid YAML, Mermaid) | ❌ Build fails |
| No link between threat and code/backlog | ⚠️ Alert for manual review |
✅ Good practices
- Treat threat modelling as a mandatory, verifiable artefact;
- Ensure traceability between threat, control, requirement and backlog;
- Automate freshness and coverage validations in the pipeline;
- Integrate results with risk management tools (e.g. IriusRisk);
- Include references to threats in relevant commits, issues and PRs.
🛍️ Final considerations
The objective of CI/CD is not merely to detect the presence of the model, but to confirm its real impact on the project. This impact manifests itself in:
- Documented decisions;
- Implemented mitigations;
- Derived requirements;
- Risks accepted with accountability.
This approach reinforces traceability and provides concrete evidence of compliance with Security by Design through threat modelling.