How it works · with a buffet

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.

5 demo controls2 profiles1 parameter0 real buffets harmed
01

Folders, not a database

  1. categories/
  2. demo/category
  3. _category.yml
  4. buffet/standard, code BUF
  5. _standard.ymlprofiles, domains, sources
  6. controls/
  7. CB-BUF-HYG-001.ymlone file per control
  8. i18n/fr/
  9. 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 log on one file is the full provenance of one control.
One standard per product
buffet covers the classic and the conveyor formats, like debian covers 12 and 13. Differences live in each control.
02

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.

03

Anatomy of a control

CB-BUF-HYG-001
  1. Identity

    The rule, and how it fails

    title is the desired state, in our own words. finding is what a scan report shows when it is not met: the problem, not the rule.

  2. Risk and scope

    How bad, for whom, how to check

    A severity from info to critical, the profiles that apply it, and the assessment: automated means a machine can check every part of it.

  3. 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.

  4. 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.

  5. Remediation

    Fix it, and undo it

    The manual fix, whether it needs a restart, how to roll back, and scripts per engine.

  6. Sources and links

    Where it comes from

    references are the primary sources it was written from. mappings say how it relates to another open framework, here stricter. threats say what it mitigates.

  7. 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.

CB-BUF-HYG-001.ymltrimmed
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
04

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-001 Keep hot dishes hot baseline
  • CB-BUF-GUARD-001 Sneeze guards above open dishes baseline
  • CB-BUF-ABUSE-002 Smaller plates against waste baseline
  • CB-BUF-ABUSE-001 Three trips per customer baseline deprecated
  • CB-BUF-HYG-002 Replace utensils on a schedule hardened
4controls apply
63 °Cmin_temp_c
  1. Your overridenone set
  2. Profile defaultnone for baseline
  3. Default63

First value found wins. minimum: 60 means no override may go below 60 °C.

05

A control's life

  1. draftWritten from primary sources, never with a proprietary benchmark open.
  2. reviewA second expert reads it. CB-BUF-HYG-002 is here.
  3. activeShipped in a release. Only active and deprecated controls are released.
  4. deprecatedKept forever, never deleted, with what replaces it.
CB-BUF-ABUSE-001Three trips per customerdeprecated in 1.1.0: counting trips did not reduce waste
CB-BUF-ABUSE-002Smaller plates against wasteintroduced in 1.1.0, supersedes ABUSE-001
06

Releases are git tags

  1. m365/v1.0.0git tag
  2. cirsec-baselines-m365-1.0.0.zip
  3. controls and translations, YAML
  4. bundle.jsoneverything resolved
  5. index.jsonlight list
  6. .zip.sha256reproducible archive
  7. 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.