# OSCAL guide

NIST Open Security Controls Assessment Language (OSCAL) 1.1.2 is a family of JSON
models for catalogs, applicability, implementation, assessment plans, results, and
open actions. This folder is this book's ledger. It is an Arcfield simulation. It
is not the ISO standard text and not a live authorization.

## What is in this folder

| Path | Function |
| --- | --- |
| `catalog.json` / `catalog.md` / `catalog.html` | ISO/IEC 27001:2022 identities. Each ISO ID opens `control.html`. |
| `control.html` | One catalog item. Hash `#4.1` / `#A.8.5`. Fills from sibling JSON. |
| `profile.json` / `profile.md` / `profile.html` | Statement of Applicability overlay. |
| `component-definition.json` / `component-definition.md` | Who owns each control as a function. |
| `system-security-plan.json` / `system-security-plan.md` | Cited documented information from companion JSON. |
| `assessment-plan.json` / `assessment-plan.md` | How this run examines a criterion. |
| `assessment-results.json` / `assessment-results.md` | What this run observed. |
| `plan-of-action-and-milestones.json` / `.md` | What remains open. |
| `mapping/` | Field map, rules, expected results. |
| `scenarios/` | Simulation facts and verdicts. |
| `schemas/` | Vendored OSCAL 1.1.2 schemas for local validate. |

Readable `.md` files sit next to each JSON. Do not edit them by hand.

Deep dive (not linked from this pack): NIST OSCAL 1.1.2 documentation and model
reference; GitHub `usnistgov/OSCAL`. This ZIP stays offline.


Human-in-the-loop guide for the four factory OSCAL files. Machine process lives in the factory; this package is the result. This document is for the person who owns the companion artefacts and must understand what the baseline is projecting.

Pinned files: `config/create_ultra/oscal/iso27001-2022/`. Rebuild: `python -m scripts.create_ultra.build_iso27001_baseline`. The scripts do not invent Information Security Management System (ISMS) content. They project **EN companion Example JSON** into OSCAL 1.1.2.

This pack is a **SIMULATION** (Arcfield didactic instance). It is not a customer authorization, not a live Identity Provider (IdP), and not a substitute for the ISO standard text.

## The audit model (two comparisons, not one)

In the organisation there are **policies**. They are written and often approved by the CEO or CISO. A policy explains context, sets a scope, defines requirements, and names objects (for example assets) and processes (for example person onboarding). In short: policies define **target** rules — *how this organisation intends to meet a need*. ISO/IEC 27001 does not prescribe that how. The standard says *that* authentication must be controlled; it does not write Arcfield’s Multi-Factor Authentication (MFA) rule.

Regularly, someone checks whether reality matches those rules. That search looks for **evidence** about objects and processes: in systems, in drawers, and in people’s heads.

An audit does **two** comparisons:

| Comparison | Target (the rule) | Actual (what is examined) | Question |
| --- | --- | --- | --- |
| **Standard vs policy** | ISO/IEC 27001:2022 (clauses 4–10 + Annex A) | the policies | Do our policies cover the standard? |
| **Policy vs evidence** | the policies | evidence of objects and processes | Does reality match what we wrote? |

The book artefacts contain **both** policies and evidence. Both already carry an ISO mapping in the companion (ISO 27001 Clauses (ISOCL), ISO 27001 Controls (ISOCTRL), Statement of Applicability (SOA), and per-artefact ISO hints). Ultra does not invent that mapping. It projects it.

The translation step you are looking for sits **between** ISO and evidence: the policy. Without it, Policy vs evidence looks as if evidence were scored against the ISO text. That is the wrong target. ISO is silent on *how*; the policy is not.

Evidence is not produced at the policy. It is produced at the **process** and the **system**, then mapped back (ISO → Policy → Process → System → Evidence). See `config/create_ultra/requirements.md` §2.

### How OSCAL names those layers

National Institute of Standards and Technology (NIST) OSCAL 1.1.2 can hold the whole chain. Ultra uses seven models. They are not seven copies of the same question.

| Your layer | OSCAL model | What it is allowed to say | What it must not pretend |
| --- | --- | --- | --- |
| ISO identities (the official set) | **Catalog** | 25 clauses + 93 Annex A IDs and titles | Applicability, HOW, or a 119th Ultra control |
| Which ISO rows are in scope, and why | **Profile** (Statement of Applicability) | Include-all; N/A stays visible with justification | A policy text, or an effectiveness score |
| Who owns the function | **Component definition** | One component per ISOCL/SOA owner; each control on exactly one owner | Invented processes, tools, or departments |
| Documented information we claim | **System Security Plan** | Cites companion Example JSON (policies *and* registers) | “This document works in operations” |
| How we will examine a criterion | **Assessment Plan** | Standard vs policy: EXAMINE / human-in-the-loop (HITL) on policy isoAnchors; Policy vs evidence: enablement method + ISO anchors (A.5.15 (Access control)–A.5.18 (Access rights) and A.8.5 (Secure authentication)) | A kernel score that Password and Authentication Policy (PAP) covers A.8.5, or a new catalog control |
| What we observed this run | **Assessment Results** | Observation for Standard vs policy; findings per Users and Access Inventory (UAI) subject for Policy vs evidence. OSCAL finding state is only `satisfied` / `not-satisfied` | CEO approval of a policy |
| What remains open | **Plan of Action and Milestones (POA&M)** | FAIL / UNKNOWN / REVIEW_REQUIRED follow-up | A rewrite of companion JSON |

**Standard vs policy** lives in Catalog + Profile + System Security Plan (SSP) policy citations **and** in the Assessment Plan as an EXAMINE activity. ISO is the target, the cited policy is the actual. Coverage is **citation + human review**, not a kernel score of “PAP prose satisfies A.8.5”. Assessment Results record that as an observation (`methods: EXAMINE`), not a finding.

**Policy vs evidence** lives in Assessment Plan / Results as a scored method: a bound target field vs a bound actual field on a population. The Ultra first cut (U1) scored target is **Access Control Matrix (ACM) `MFA Required`** (`operational-target`), not PAP narrative. The actual is **UAI `MFA Status`** (`evidence`). PAP stays in the Volume 3 pack as the HOW text; U1 does not parse `mfa_requirements` as a join rule.

### What the companion artefacts are (mixed on purpose)

| Kind | Examples | Role in the two comparisons |
| --- | --- | --- |
| `identity-register` | ISOCL, ISOCTRL, SOA | Name the ISO set and SoA. Not a policy, not operating evidence. |
| `policy` (HOW) | Information Security Policy (ISP), PAP, Human Resources Policy (HRP), … | Target for Policy vs evidence; actual for Standard vs policy. |
| `process` | ONC, OFC, ARA | How Policy vs evidence is operated. |
| `system` | Azure / IdP (often only an ACM/UAI column) | Where actuals are produced. |
| `operational-target` | ACM `MFA Required` | Per-object target values the process compares. U1 uses this as the scored target. |
| `evidence` | UAI, Access Rights Register (ARR), Azure export | Actual for Policy vs evidence. |
| `hybrid` | Exceptions Register (EXR) | Neighbouring path. Not silently joined across books. |

The SSP **Layer A / B** table below does **not** yet split `policy` vs `process` vs `system` vs `evidence`. Layer B only means “a companion artefact beyond the identity registers resolved to an `artifactId`”. Standard vs policy is now also visible as OSCAL `type=policy` components (isoAnchors) beside owner components. That is citation, not a kernel score of “PAP covers A.8.5”.

### What Ultra U1 does *not* yet project

These parts of the mental model are real in the books. They are **not** first-class OSCAL objects in this etappe:

- A typed `policy` / `process` / `system` / `evidence` flag on SSP implemented-requirements.
- An evaluator for Standard vs policy (does PAP cover A.8.5?). Coverage is human review of SoA + policy-component citations.
- Binding PAP (or ISP) prose as the scored target for Policy vs evidence. U1 binds ACM columns.
- CEO/CISO approval, version, and review cycle of a policy.
- Evidence still only in drawers or people’s heads (no Example JSON). If it is not a companion artefact, Ultra cannot cite it.
- Enforcement (“MFA enforced”). `MFA Status = Enabled` is recorded enablement only.

OSCAL can hold several of those later (policy components, richer `by-components` statements, a second assessment method). U1 does not invent them.

Worked example — privileged MFA, Volume 3:

```
ISO A.8.5 (Secure authentication) (and A.5.15–A.5.18)     ← target for Standard vs policy; catalog identity only
        ↓  human translation (HOW), not scored by the kernel
Password and Authentication Policy (PAP)   ← policy; in-pack; not a join field
        ↓  operationalised per role/system
Access Control Matrix (ACM) MFA Required = Yes                    ← scored operational-target for Policy vs evidence
        ↓  recorded reality for that account
Users and Access Inventory (UAI) MFA Status = Enabled | Disabled | blank   ← scored evidence (actual) for Policy vs evidence
```

The kernel answers only the last arrow (enablement recorded). It does not answer “is PAP a sufficient ISO policy?” and it does not answer “is MFA enforced?”.

## What you are in the loop for

You do **not** maintain the OSCAL JSON by hand. You maintain the companion registers. The builders read those files and write the OSCAL projection. You then read the projection to see whether the registers still say what you meant.

```
You edit companion Example JSON (ISOCL, ISOCTRL, SOA, cited artefacts)
        ↓  author rebuild
OSCAL baseline in config/  (catalog → profile → component → SSP)
        ↓  you review
Gaps stay visible (N/A justification, unresolved tokens, Layer A vs B)
        ↓  pipeline run
Runner checks the pinned files; it does not silently recreate them
```

If catalog, profile, component, and SSP disagree with ISOCL/SOA, **fix the companion row**, then rebuild. Do not patch one OSCAL file to hide a register problem.

## The four artefacts

| File | OSCAL model | Question it answers | Human source |
| --- | --- | --- | --- |
| `catalog.json` | Catalog | What exists in ISO/IEC 27001:2022? | ISOCL + ISOCTRL titles; clause IDs in `config/iso27001_clause_catalog.json` |
| `profile.json` | Profile (SoA) | What is in Arcfield scope, and why? | SOA Example: Applicability, justification, implementation status |
| `component-definition.json` | Component definition | Who owns each control as a function? | ISOCL `Responsible role`; SOA `Control owner` |
| `system-security-plan.json` | SSP | Where is the documented information cited? | Same registers plus resolved companion `artifactId`s |

Readable contents (generated next to the JSON, do not edit by hand):

| View | What’s in it |
| --- | --- |
| [`catalog.md`](./catalog.md) | 25 clauses + 93 Annex A IDs and titles |
| [`profile.md`](./profile.md) | Applicability, implementation status, N/A justifications |
| [`component-definition.md`](./component-definition.md) | 24 owners and which controls they hold |
| [`system-security-plan.md`](./system-security-plan.md) | Layer A/B/N/A, cited artefacts, unresolved tokens |

A pipeline run also writes sibling Markdown for `assessment-plan`, `assessment-results`, and `plan-of-action-and-milestones`. The Dist ZIP ships this guide as `oscal/oscal-guide.md`. Unpack-and-run: `python3 demo/tools/serve-demo.py`. Optional OSCAL check: `demo/tools/validate-oscal.py`. Sibling views sit next to each JSON in `oscal/`. The factory simulator is not in the ZIP.

Completeness of the **identity** catalog is 25 management-system clauses + 93 Annex A controls (118). That is the official ISO 27001:2022 control set as identities, not 118 extra Ultra criteria.

Assessment Plan, Assessment Results, and POA&M are **not** baseline. Those are per-run (`emit_oscal` / `evaluate`). The plan documents Standard vs policy as EXAMINE/HITL and Policy vs evidence as the enablement method. Results observe Standard vs policy and score Policy vs evidence. They do not replace SoA or SSP.

### Catalog — identity, not applicability

The catalog is the list of clause and Annex A **identities** (IDs and titles only). It is not a Statement of Applicability and not an assessment method.

- Human: keep ISOCL/ISOCTRL complete and titled; keep `config/iso27001_clause_catalog.json` as the clause ID list (no parent `6.1`, only `6.1.1`–`6.1.3`).
- Script: emit 118 controls, grouped by clause family and Annex A theme.
- You review: 25 + 93 present; labels match ISO IDs (`4.1`, `A.8.5`); no NIST `ac-*` IDs; no privileged-MFA control stuffed into this catalog; no copyrighted “The organization shall…” prose.
- Ultra criteria (for example privileged MFA enablement) stay **assessment methods**, not extra catalog controls.

### Profile — SoA overlay, nothing dropped

The profile imports the **whole** catalog (`include-all`). Annex A applicability comes from SOA Example. Not-applicable rows stay in the profile with justification. They are not excluded.

- Human: for every Annex A row, set Applicability and write a justification (required for both Applicable and Not applicable). Set implementation status and Control owner. Do not delete a row to mean “out of scope”.
- Script: clauses 4–10 are always `applicable` / `always-in-scope`. Annex A copies SOA. Current Arcfield N/A: **A.7.6, A.7.11, A.7.12, A.8.30**.
- You review: 118 alters; four N/A still visible; `excludes-not-applicable` is false; SOA hash in metadata matches the Example file you think you edited.

Changing N/A is a **SoA decision**, not an OSCAL edit.

### Component definition — owners, not invented processes

Components are the Control owners / responsible roles already written in ISOCL and SOA. The builder does not invent ISO processes, departments, or tooling names.

- Human: assign a real owner on each ISOCL clause and each SOA control (`ISMS Manager`, `IT Operations`, `Facilities Manager`, …).
- Script: one process-procedure component per distinct owner; each of the 118 controls appears on **exactly one** owner; one capability “Arcfield ISMS functions” incorporates them all. Source is the local profile.
- You review: owners you recognise from the companion; no duplicate control-id across components; N/A still on the owning component with the exclusion text.

If a control has the wrong owner, change the SOA/ISOCL cell, then rebuild.

### SSP — citation of documented information, not effectiveness

The SSP imports the SoA profile and instantiates the owner component UUIDs. It **cites** companion Example JSON. It does not rewrite those files. It does not score whether the documents work in operations.

Evidence is layered so a human can see how thin the citation is. This layer is **citation depth**, not Policy vs Evidence (see [The audit model](#the-audit-model-two-comparisons-not-one)).

| Layer | Meaning | Typical source |
| --- | --- | --- |
| **A documented** | Identity registers only (ISOCL, ISOCTRL, SOA). The control is named in the ISMS set. | Clause/control register row |
| **B linked** | At least one companion artefact **beyond** those registers resolved to an `artifactId` (ACM, PAP, UAI, …). | `Implementation artifact(s)` / `Evidence reference` tokens that match Example JSON |
| **N/A** | SoA exclusion. No operating evidence claimed. | SOA Not applicable + justification |
| **C** | Field-level actual scoring (enablement PASS/FAIL/UNKNOWN). | **Not in this SSP.** That is `evaluate` / the kernel on a run. |

Unresolved evidence tokens (a cell that names something the curated folder cannot match) stay on the implemented-requirement as `unresolved-evidence`. That is a **property**, not an abort. The human job is to either add/rename the companion artefact or clean the token in ISOCL/SOA.

Current Arcfield projection (order of magnitude, not a target): Layer A ~44, Layer B ~70, N/A 4, plus unresolved tokens that remain visible on purpose.

Missing actual on a bound field is also not an abort here. The SSP records documented information. Operational gaps belong in a run’s Assessment Results.

## Companion files you actually edit

Paths: `iso27001-data/persistent/companion/curated/en/` (EN is SSOT).

| File | Role in the loop |
| --- | --- |
| `ISOCL_ISO_27001_2022_Clauses_Example.json` | Clause IDs, titles, responsible role, implementation artefact tokens |
| `ISOCTRL_ISO_27001_2022_Controls_Example.json` | Annex A titles (catalog) |
| `SOA_Statement_of_Applicability_SoA_Example.json` | Applicability, justification, status, owner, evidence reference |
| Other `*_Example.json` | Cited when a token resolves (ACM, UAI, PAP, …). Read-only for the builders. |
| `*_Contract.json` | Structure of those artefacts. Ultra does not rewrite Contract or Example. |

The builders hash SOA and ISOCL into profile/SSP metadata. A runner `--check` that reports **stale** means you changed a register and have not rebuilt the projection.

## Day-to-day actions

**Read / check (no write to SSOT)**

```zsh
python -m scripts.create_ultra.build_iso27001_baseline --check
```

Exit 0: pinned files present, schema-valid, hashes match companion. Exit 3: missing or stale — generate is offered only in an **interactive** runner. `--yes` / non-interactive **aborts** (does not create). Helper option 73 (Create companion → Ultra) shares the Ultra `runId`; the gate report is `{runId}/baseline/`. Scratch is factory `tmpRoot`, not a folder in the run. The JSON themselves stay in `config/`.

**Author rebuild (writes config only)**

```zsh
python -m scripts.create_ultra.build_iso27001_baseline
```

Without `--run-id` / `PIPELINE_RUN_ID` this is not a product run. It overwrites the four pinned files after catalog → profile → component → SSP. Single-model rebuilds exist (`build_iso27001_catalog`, `_profile`, `_component`, `_ssp`) but the orchestrator is the one that keeps them in lockstep.

Rebuild after you change ISOCL, ISOCTRL, SOA, the clause ID list, or an evidence token you expect to resolve. Then `--check` again and read:

1. N/A still justified and visible.
2. Owners still match the roles you intend.
3. Layer B citations you expected (for example A.5.15 → ACM) are linked, not stuck on Layer A.
4. Unresolved tokens: accept, fix the cell, or add the artefact — do not delete the property to look clean.

## What this baseline is not

- Not a place to paste ISO requirement prose.
- Not a third ZIP next to Basic/Premium. Live SKUs are `dist/{lang}/Companions/{Basic|Premium|Ultra}/`. The Ultra ZIP is the OSCAL of this book's companions, plus a demo, a pre-built report, and a guide. Office snapshot: `Source/volume-3/{Basic,Premium}/`. `license.json` records the Master Companion License conditions (`productTier`, not extra rights).
- Not the historical Volume 3 IAM needle under `oscal/samples/` (OSC-001). That sample catalog still has one Ultra criterion on purpose. Live `emit_oscal` **copies** this factory catalog (118 identities) into the run/ZIP. The Ultra criterion is the assessment method on A.5.15–A.5.18 and A.8.5, not a 119th control.
- Not a kernel score of “does this policy cover ISO?” (Standard vs policy is citation + human review).
- Not enforcement: `MFA Status = Enabled` is not “MFA durchgesetzt”.
- Not a rewrite of companion JSON, and not a silent load of Volume 2 EXR into Volume 3.

## Locked rules (do not “simplify”)

- Official completeness = 25 + 93. N/A stays in the profile and SSP.
- Components come from companion owners, not a homemade process list.
- Unresolved evidence and missing actuals are visible findings/properties, not pipeline stops.
- Human edits the registers; scripts emit OSCAL; Dist/config/companion remain the end result. A run folder is for understanding, not a second SSOT.
