← Back to projects

Personal project
Risk Assessment Matrix — methodical risk register
A risk register that follows a written method — ISO/IEC 27005:2022 or EBIOS Risk Manager — and checks itself: scores, treatment, formal acceptance by the right authority and reviews, with reports, safe CSV import/export and a web interface
Context
I rebuilt this project from scratch, replacing two older prototypes (an English risk matrix and its French rebuild). The aim: a risk register a small or mid-sized organisation can defend in front of management or an ISO/IEC 27001 auditor. The method — scales, grid, appetite, acceptance authorities — is written in a file and validated; every risk is then checked against it automatically. Atelier Lumen, the fictional company of my incident response tabletop exercise, provides the example registers.
What the repository contains
- A method format in TOML, bilingual, with two presets: 5×5 likelihood × impact (ISO/IEC 27005:2022) and EBIOS RM 4×4 (likelihood V1–V4 × severity G1–G4, ANSSI 1.5)
- A register format: assets, threat, vulnerability, inherent and residual risk, planned measures, treatment (reduce, accept, transfer, avoid), formal acceptance, review, history
- References on each risk and measure: ISO/IEC 27001:2022 Annex A controls (numbers only), MITRE ATT&CK techniques, and the matching incident response playbook
- Four commands: risk-check (validation), risk-report (Markdown and HTML), risk-export (JSON, CSV) and risk-import (CSV to TOML)
- An assessment guide and Atelier Lumen example registers, in French and English
Rules checked automatically
- A consistent method: monotonic grid, every level used, an acceptance authority for each level above the appetite, shorter reviews for more severe risks
- Residual risk never above inherent risk without a justification
- Formal acceptance required when the residual risk stays above the appetite and nothing is under way to reduce it (ISO/IEC 27001, 6.1.3) — signed by the authority set by the method, for its maximum duration
- Next review within the frequency of the residual level; chronological history
- Errors (invalid data) are kept apart from warnings (overdue measure or review, expired acceptance); --strict makes warnings blocking
Security choices
- CSV export protected against formula injection (CWE-1236): cells starting with =, +, -, @ are neutralised, and the protection is removed on import
- Imports limited in size and rows, UTF-8 required, no file overwritten without --force
- HTML report as a single file with no script: every text escaped, CSP allowing only its own stylesheet through a SHA-256 hash
- Real registers excluded from Git by naming convention; the web interface reads a file locally and never sends or keeps it
Web interface
- Loads the example registers or a local JSON export, fully validated before display (types, dates, colours, consistency with the grid)
- Summary of active risks, risks above the appetite, overdue measures and reviews, expired acceptances
- Clickable inherent and residual heat maps, filters (level, owner, treatment, accent-insensitive search) and a detailed sheet per risk
- Action plan and review schedule; French and English, light and dark themes, keyboard and mobile friendly, strict CSP
Engineering quality
240
Automated tests
216 Python + 24 web
7
CI jobs
Windows + Linux, Python 3.11/3.14, Ruff, registers, web interface
2
Method presets
5×5 and EBIOS RM 4×4
0
Runtime dependencies
How it is used
- 1PreparePick a preset, adapt the scales and the appetite with management, and let risk-check validate the method.
- 2AssessDescribe each risk (cause → event → consequence) and score its inherent risk; the level is read from the method's grid.
- 3Treat and acceptPlan measures with owners and due dates, score the residual risk, and have the designated authority accept what remains.
- 4ReviewReviews and acceptances expire on their own schedule; risk-check --strict and the report flag what is overdue.
Screenshots
