A baseline, explained on a buffet.
Silly example, real format.
The repository ships a demo standard, All-you-can-eat buffet security, that uses every field of the format. Nobody gets hurt reading about bains-marie, so we use it to walk through how every real baseline, Microsoft 365 or Debian, is built.
Folders, not a database
- categories/
- demo/category
- _category.yml
- buffet/standard, code
BUF - _standard.ymlprofiles, domains, sources
- controls/
- CB-BUF-HYG-001.ymlone file per control
- i18n/fr/
- CB-BUF-HYG-001.ymltranslation, text only
- The tree is the source of truth
- No index lists the controls. This site, the releases and the scanners all read the folders, so nothing can drift.
- One file per control
- Experts work in parallel without conflicts, and
git logon one file is the full provenance of one control. - One standard per product
buffetcovers the classic and the conveyor formats, likedebiancovers 12 and 13. Differences live in each control.
An ID that tells you where it lives
CB-BUF-HYG-001: CIRSEC Baselines, standard BUF, domain HYG, number 001.
Frozen at creation. If a control must change meaning or domain, it is deprecated and a new one replaces it: links never break.
Anatomy of a control
-
Identity
The rule, and how it fails
titleis the desired state, in our own words.findingis what a scan report shows when it is not met: the problem, not the rule. -
Risk and scope
How bad, for whom, how to check
A severity from
infotocritical, the profiles that apply it, and the assessment:automatedmeans a machine can check every part of it. -
Setting and parameters
The value, tunable
63 °C is a sane default, not a law. It is a parameter, with a stricter value for the hardened profile and bounds nobody may cross.
{{ min_temp_c }}is replaced everywhere it appears. -
Audit
Check it by hand, or by machine
A manual procedure always. Machine checks per engine, each with a stable id, so a scanner says exactly which part failed, and only on the versions it applies to.
-
Remediation
Fix it, and undo it
The manual fix, whether it needs a restart, how to roll back, and scripts per engine.
-
Sources and links
Where it comes from
referencesare the primary sources it was written from.mappingssay how it relates to another open framework, herestricter.threatssay what it mitigates. -
People and lifecycle
Who, since when
Authors, reviewers, the release that introduced it, and
updated, bumped on every change: a translation older than that is flagged stale.
id: CB-BUF-HYG-001
title: Keep hot dishes above the safe holding temperature
finding:
title: Hot dishes are held at an unsafe temperature
status: active
profiles: [baseline]
risk: { severity: high, score: 8.2 }
assessment: automated
setting:
recommended_value: "At least {{ min_temp_c }} °C core"
parameters:
- name: min_temp_c
type: integer
default: 63
profile_defaults: { hardened: 70 }
minimum: 60
audit:
manual: Probe three dishes, each at least {{ min_temp_c }} °C.
checks:
- id: bain-marie-temp
engine: demo-sensor
versions: [classic]
spec: { sensor: bain_marie.*.core_temp, operator: ">=" }
remediation:
manual: Set the thermostat to {{ min_temp_c }} °C.
requires_restart: false
rollback: Set it back to its previous value.
references:
- { title: "Food Code, ch. 3", kind: standard }
mappings:
- { framework: demo-food-code, id: FC-3.4, relation: stricter }
threats:
- { framework: demo-buffet-threats, id: BT-001 }
authors: [{ name: Alice }]
introduced_in: 1.0.0
updated: 2026-10-16
The full file, every field commented
Profiles stack, parameters follow
No "Level 1 / Level 2". A standard names its profiles, and hardened extends baseline:
applying it applies every baseline control, adds its own, and uses its own parameter values.
CB-BUF-HYG-001Keep hot dishes hot baselineCB-BUF-GUARD-001Sneeze guards above open dishes baselineCB-BUF-ABUSE-002Smaller plates against waste baselineCB-BUF-ABUSE-001Three trips per customer baseline deprecatedCB-BUF-HYG-002Replace utensils on a schedule hardened
- Your overridenone set
- Profile defaultnone for baseline
- Default63
First value found wins. minimum: 60 means no override may go below 60 °C.
A control's life
- draftWritten from primary sources, never with a proprietary benchmark open.
- reviewA second expert reads it.
CB-BUF-HYG-002is here. - activeShipped in a release. Only active and deprecated controls are released.
- deprecatedKept forever, never deleted, with what replaces it.
CB-BUF-ABUSE-001Three trips per customerdeprecated in 1.1.0: counting trips did not reduce wasteCB-BUF-ABUSE-002Smaller plates against wasteintroduced in 1.1.0, supersedes ABUSE-001Releases are git tags
- m365/v1.0.0git tag
- cirsec-baselines-m365-1.0.0.zip
- controls and translations, YAML
- bundle.jsoneverything resolved
- index.jsonlight list
- .zip.sha256reproducible archive
- RELEASE_NOTES.mdadded, deprecated, updated
- One version per standard
- SemVer: a deprecated control or a stricter default is major, a new control minor, wording and mappings patch.
- Every version stays online
- This site serves each tag at
/b/m365/v1.0.0/CB-M365-AUTH-001, next to the current state at/b/m365/CB-M365-AUTH-001. - The demo is never released
- The buffet only exists to show the format. Real standards start as drafts until their first release.