Merge pull request #71 from andrewibrah/add-grc-skills

Add 5 skills: GRC (800-30, RMF, CMMC, HIPAA, TPRM)
This commit is contained in:
Mahipal
2026-06-20 16:44:09 +02:00
committed by GitHub
25 changed files with 3489 additions and 0 deletions
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to the Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by the Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding any notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. Please do not remove or change
the license header comment from a contributed file except when
necessary.
Copyright 2026 mukul975
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
@@ -0,0 +1,142 @@
---
name: achieving-cmmc-level-2-compliance
description: >-
Prepare a defense-contractor environment for CMMC Level 2 certification: scope CUI
and FCI, implement the 110 NIST SP 800-171 Rev 2 security requirements across 14
families, compute the SPRS score with the DoD Assessment Methodology, manage a
compliant POA&M, and ready the organization for a C3PAO assessment. Use when an
organization handles Controlled Unclassified Information (CUI) under a DoD contract,
when a contract carries DFARS clause 252.204-7012/7019/7020/7021, when preparing for
or responding to a CMMC assessment, when computing or improving an SPRS score, when
building a System Security Plan or POA&M for 800-171, or when scoping which systems
are in the CUI boundary. Keywords: CMMC, CMMC Level 2, NIST 800-171, SP 800-171 Rev 2,
CUI, FCI, SPRS, DFARS 7012, C3PAO, POA&M, System Security Plan, DoD Assessment
Methodology, 110 controls, defense industrial base, DIB, FedRAMP equivalency.
domain: cybersecurity
subdomain: compliance-governance
tags:
- cmmc
- nist-800-171
- cui
- sprs
- dfars
- c3pao
- poam
- compliance
- governance
- defense-industrial-base
version: "1.0"
author: andrewibrah
license: Apache-2.0
nist_csf:
- GV.OC-03
- GV.SC-01
- ID.AM-08
- ID.RA-05
- PR.AA-01
- PR.DS-01
mitre_attack:
- T1078
- T1190
- T1041
- T1048
- T1567
---
# Achieving CMMC Level 2 Compliance
## When to Use
- When an organization in the **Defense Industrial Base (DIB)** stores, processes, or transmits **Controlled Unclassified Information (CUI)** under a DoD contract.
- When a contract includes **DFARS 252.204-7012** (safeguarding/incident reporting), **-7019/-7020** (NIST 800-171 self-assessment + SPRS), or the new **-7021** (CMMC requirement).
- When preparing for a **C3PAO** third-party assessment or a DoD-led assessment.
- When you must **compute, post, or improve an SPRS score** based on the NIST SP 800-171 DoD Assessment Methodology.
- When authoring or remediating a **System Security Plan (SSP)** and **POA&M** for the 110 requirements.
- When **scoping** which assets fall inside the CUI/FCI boundary (CUI assets, security-protection assets, contractor risk-managed assets, out-of-scope).
## Prerequisites
- Knowledge of **which contracts carry CUI** and the CUI categories involved (check the contract and the DoD CUI Registry).
- An asset inventory and network diagram so you can define the **CMMC assessment scope** before assessing controls.
- The **NIST SP 800-171 Rev 2** requirements and the **DoD Assessment Methodology** scoring weights.
- A documented **SSP** (its absence is itself a failed requirement — 3.12.4).
- Identification of any **External Service Providers (ESPs)** / cloud services touching CUI, and whether they meet **FedRAMP Moderate (or equivalency)**.
## Workflow
### 1. Determine applicability and CUI categories
Confirm the contract requires CMMC Level 2 (CUI present, not just FCI). FCI-only contracts are **Level 1** (the 15 FAR 52.204-21 requirements). Identify CUI categories from the contract and the DoD CUI Registry.
### 2. Scope the environment
Classify every asset into one of the CMMC scoping categories:
- **CUI Assets** — process/store/transmit CUI (in scope, assessed against all applicable controls).
- **Security Protection Assets** — provide security to the CUI environment (in scope).
- **Contractor Risk Managed Assets** — could but are not intended to handle CUI; managed by policy.
- **Specialized Assets** (IoT/OT, GFE, test equipment) — documented, limited assessment.
- **Out-of-Scope** — physically/logically isolated from CUI.
Minimize scope deliberately — a smaller, well-segmented CUI enclave is far cheaper to certify than a flat network.
### 3. Implement the 110 requirements (NIST SP 800-171 Rev 2)
Work the **14 families** (3.13.14). For each requirement, implement, then write the **how** in the SSP. High-leverage early wins: MFA (3.5.3), FIPS-validated cryptography (3.13.11), audit logging (3.3.x), access control + least privilege (3.1.x), and incident response (3.6.x).
### 4. Score with the DoD Assessment Methodology (SPRS)
Start at **110** and subtract the weighted value (**1, 3, or 5 points**) of each **unmet** requirement; partial credit applies to a small number of controls (e.g., MFA, FIPS crypto). The result is the **SPRS score** (maximum 110; the methodology floor is 203). Post the score, the SSP date, and the assessment scope to **SPRS** (or eMASS for higher assessments).
### 5. Build a compliant POA&M
Document every unmet requirement with owner, remediation, and milestone. **Constraints under the CMMC rule:** a **Conditional** status requires a score of at least **80%** (≥ 88 of 110), only **POA&M-eligible** requirements may be deferred (the highest-weighted security requirements must be fully met — verify eligibility against 32 CFR Part 170), and all POA&M items must be **closed within 180 days** to convert Conditional → **Final**.
### 6. Assess (self or C3PAO)
- **Level 1** and a subset of Level 2 = annual **self-assessment** with an affirmation in SPRS.
- **Level 2 (most CUI contracts)** = triennial **C3PAO** certification assessment.
- **Level 3** = DoD (DIBCAC) assessment on top of Level 2, adding SP 800-172 enhanced requirements.
Assessors evaluate each objective as **MET / NOT MET / N/A** with evidence (examine/interview/test). A senior official files the **annual affirmation** of continued compliance.
### 7. Maintain certification
Certification is valid **three years** with **annual affirmations**. Maintain the SSP, re-score on change, keep evidence current, and feed significant changes back into the assessment.
## Key Concepts
| Concept | Definition |
|---|---|
| FCI | Federal Contract Information — Level 1 protects it (FAR 52.204-21). |
| CUI | Controlled Unclassified Information — Level 2 protects it (NIST 800-171). |
| 110 requirements | The SP 800-171 Rev 2 security requirements across 14 families. |
| SPRS | Supplier Performance Risk System — where the 800-171 score is posted. |
| DoD Assessment Methodology | The 1/3/5-point weighting used to compute the score from 110. |
| C3PAO | CMMC Third-Party Assessment Organization — performs Level 2 certification. |
| POA&M | Plan of Action & Milestones — limited, must close in 180 days for Final status. |
| Conditional vs Final | Conditional = open POA&M (score ≥ 80%); Final = all controls met. |
| ESP | External Service Provider — must meet FedRAMP Moderate / equivalency for CUI. |
| Scoping categories | CUI / Security Protection / Contractor Risk Managed / Specialized / Out-of-Scope. |
## Tools & Systems
- **NIST SP 800-171 Rev 2** — the 110 requirements (and 800-171A for assessment objectives).
- **DoD NIST SP 800-171 Assessment Methodology** — the scoring weights.
- **32 CFR Part 170** (CMMC Program rule) and **48 CFR / DFARS 252.204-7021** (acquisition rule).
- **SPRS** — score posting; **SAM.gov** for registration.
- **SP 800-172 / 800-172A** — enhanced requirements for Level 3.
- **GRC / compliance tooling** — to manage the SSP, POA&M, and evidence (e.g., Xacta, RegScale, FutureFeed-style trackers).
## Common Scenarios
- **Prime flows CUI to a sub.** The sub needs its own Level 2 scope, SSP, SPRS score, and (most likely) C3PAO certification.
- **Score is below 88.** Prioritize the highest-weighted unmet requirements (5-point, then 3-point) to clear the conditional threshold and shrink the POA&M.
- **Cloud holds CUI.** Confirm the service is FedRAMP Moderate authorized or meets equivalency; document the responsibility split.
- **Flat network.** Re-scope into a segmented CUI enclave to cut the assessment surface before spending on controls.
- **Annual affirmation due.** A senior official affirms continued compliance in SPRS; let it lapse and you risk contract eligibility.
## Output Format
Produce a **CMMC Level 2 Readiness Report** using `assets/template.md`, containing:
1. **Applicability & CUI categories** — why Level 2 applies.
2. **Scope** — assets by scoping category and the CUI boundary diagram reference.
3. **Control status by family** — met / not met / N/A across the 14 families.
4. **SPRS score** — computed score, deductions, and the gap to 110 and to the 88 threshold.
5. **POA&M** — unmet requirements, eligibility check, owners, 180-day milestones.
6. **Assessment path** — self vs C3PAO, target date, affirmation owner.
7. **Remediation roadmap** — sequenced by point value and effort.
Use `scripts/process.py` to compute the SPRS score from a control-status JSON, flag POA&M-eligibility concerns, and report the gap to the conditional-certification threshold.
@@ -0,0 +1,63 @@
# CMMC Level 2 Readiness Report — Worked Example
> Filled example for a small DIB manufacturer handling CUI on a segmented enclave.
> Replace bracketed content for your own organization.
## 1. Applicability & CUI Categories
- **Contract drivers:** Prime subcontract with DFARS **252.204-7012** and **-7021**; CUI present → **CMMC Level 2** required.
- **CUI categories (from contract + DoD CUI Registry):** Controlled Technical Information (CTI), Export Controlled (EAR).
- **Target assessment path:** Triennial **C3PAO** certification (Phase 2 applies from Nov 10, 2026).
## 2. Scope (CMMC Level 2 Scoping Guide)
| Category | Examples in this environment |
|---|---|
| CUI Assets | Engineering workstations, CUI file share, the segmented "Enclave-1" VLAN |
| Security Protection Assets | EDR console, SIEM, firewall, IdP/MFA, jump host |
| Contractor Risk Managed | General corporate laptops (policy-blocked from CUI) |
| Specialized Assets | CNC machine controllers (documented, isolated) |
| Out-of-Scope | Guest Wi-Fi, marketing SaaS |
**Boundary note:** CUI is confined to Enclave-1 behind segmentation and MFA. Deliberately minimized to shrink the assessment surface. See network diagram `CUI-boundary-v3`.
## 3. Control Status by Family (NIST SP 800-171 Rev 2)
*(summary; full per-requirement status lives in the SSP)*
| Family | Met | Partial | Not Met | N/A |
|---|---|---|---|---|
| 3.1 Access Control | 22 | 0 | 0 | 0 |
| 3.3 Audit & Accountability | 8 | 0 | 1 | 0 |
| 3.5 Identification & Auth | 10 | 1 | 0 | 0 |
| 3.8 Media Protection | 8 | 0 | 1 | 0 |
| 3.13 System & Comms Protection | 15 | 0 | 1 | 0 |
| 3.14 System & Info Integrity | 6 | 0 | 1 | 0 |
| *(others)* | all met | — | — | — |
## 4. SPRS Score
*(computed by `scripts/process.py` from the control-status JSON)*
- **Score: 97 / 110** (started at 110; deducted 13).
- **Gap to perfect:** 13 points across 4 not-met + 1 partial requirement.
- **Conditional threshold (≥ 88):** **MET** (margin 9) — eligible for Conditional status *if* the remaining items are POA&M-eligible.
- **Posted to SPRS:** score, SSP date, and assessment scope.
## 5. POA&M (eligibility-checked)
| ID | Requirement | Points | Eligibility | Remediation | Owner | Milestone (≤180d) |
|---|---|---|---|---|---|---|
| 3.3.1 | Audit log generation/coverage | 5 | **Verify** — high weight; confirm against 32 CFR 170 | Enable full audit policy + ship to SIEM | SecOps | 2026-07-30 |
| 3.13.11 | FIPS-validated cryptography | 3 | **Verify** eligibility | Replace non-validated module with FIPS 140-validated | Infra | 2026-08-15 |
| 3.5.3 | MFA (partial) | 3 | Partial-credit control | Extend MFA to remaining admin paths | IAM | 2026-07-20 |
| 3.8.9 | Backup CUI protection | 1 | Eligible | Encrypt + access-control backup store | Infra | 2026-08-31 |
| 3.14.1 | Flaw remediation | 1 | Eligible | Formalize patch SLA + tracking | IT | 2026-08-31 |
> The two 3-point and one 5-point items must clear eligibility review; the highest-weighted security requirements generally cannot remain on a POA&M. All items close within **180 days** to convert Conditional → **Final**.
## 6. Assessment Path
- **Type:** C3PAO certification assessment.
- **Target window:** Q4 2026, after POA&M closure of the high-weight items.
- **Affirmation owner:** [senior official] files the annual affirmation in SPRS.
## 7. Remediation Roadmap (sequenced by point value, then effort)
1. **3.3.1 audit logging (5 pts)** — biggest score lever and likely POA&M-ineligible → do first.
2. **3.13.11 FIPS crypto (3 pts)** and **3.5.3 MFA gap (3 pts)** — close to remove eligibility risk.
3. **3.8.9, 3.14.1 (1 pt each)** — low-effort cleanups before the C3PAO date.
4. Re-run the SPRS calculator after each closure; goal is **110** before assessment.
@@ -0,0 +1,84 @@
# CMMC Level 2 — Standards & Reference
## Governing rules
| Rule | Citation | Status / effective date |
|---|---|---|
| CMMC Program rule | 32 CFR Part 170 | Effective **December 16, 2024** |
| CMMC acquisition rule (DFARS) | 48 CFR; DFARS clause **252.204-7021** (and 204.7503) | Published Sept 10, 2025; effective **November 10, 2025** |
| Safeguarding CUI / incident reporting | DFARS **252.204-7012** | In effect |
| NIST 800-171 self-assessment + SPRS posting | DFARS **252.204-7019 / -7020** | In effect |
> Always confirm current status at the source — acquisition rules and phase dates have moved before. Authoritative: https://dodcio.defense.gov/CMMC/ and the eCFR for 32 CFR Part 170.
## Phased rollout (per the acquisition rule)
| Phase | Begins | What applies |
|---|---|---|
| Phase 1 | **Nov 10, 2025** | Level 1 and some Level 2 **self-assessment** required in solicitations |
| Phase 2 | **Nov 10, 2026** | Level 2 **C3PAO certification** required for applicable contracts |
| Phase 3 | **Nov 10, 2027** | Level 2 C3PAO + Level 3 **DIBCAC** assessment phased in |
| Phase 4 | **Nov 10, 2028** | Full implementation across applicable DoD contracts |
## The three CMMC levels
| Level | Protects | Requirements | Assessment |
|---|---|---|---|
| Level 1 | FCI | 15 requirements (FAR 52.204-21) | Annual self-assessment + affirmation |
| Level 2 | CUI | **110 requirements (NIST SP 800-171 Rev 2)** | Self **or** triennial C3PAO certification |
| Level 3 | CUI (high priority) | 110 + selected **SP 800-172** enhanced | DoD (DIBCAC) assessment |
Certification validity: **3 years**, with **annual affirmation** by a senior official in SPRS.
## NIST SP 800-171 Rev 2 — the 14 families (110 requirements)
| § | Family | # reqs |
|---|---|---|
| 3.1 | Access Control | 22 |
| 3.2 | Awareness and Training | 3 |
| 3.3 | Audit and Accountability | 9 |
| 3.4 | Configuration Management | 9 |
| 3.5 | Identification and Authentication | 11 |
| 3.6 | Incident Response | 3 |
| 3.7 | Maintenance | 6 |
| 3.8 | Media Protection | 9 |
| 3.9 | Personnel Security | 2 |
| 3.10 | Physical Protection | 6 |
| 3.11 | Risk Assessment | 3 |
| 3.12 | Security Assessment | 4 |
| 3.13 | System and Communications Protection | 16 |
| 3.14 | System and Information Integrity | 7 |
| | **Total** | **110** |
(Assessment objectives for each requirement are in **NIST SP 800-171A**.)
## DoD Assessment Methodology — SPRS scoring
- Start at **110**. Subtract the weighted value of each **NOT MET** requirement.
- Weights: **1, 3, or 5 points**. The most security-significant requirements are weighted 3 or 5.
- **Partial credit** applies to a small number of requirements (notably MFA at 3.5.3 and FIPS-validated cryptography at 3.13.11) where partial implementation reduces the deduction.
- Maximum score **110**; the methodology floor is **203** (more is deducted than the 110 starting points because of the weighting).
- The complete per-requirement point assignment is published in the **DoD NIST SP 800-171 Assessment Methodology** — use that document for the authoritative weight of each control rather than estimating.
## POA&M rules under the CMMC rule (32 CFR Part 170)
- A **Conditional** Level 2 status is allowed only if the assessment score is **at least 80% (≥ 88 of 110)**.
- Only **POA&M-eligible** requirements may be deferred. The highest-weighted security requirements generally **must be fully met** and **cannot** sit on a POA&M — verify each item's eligibility against the rule.
- All POA&M items must be **closed within 180 days**; a closeout assessment then converts **Conditional → Final**.
## Scoping categories (CMMC Level 2 Scoping Guide)
| Category | Treatment |
|---|---|
| CUI Assets | Process/store/transmit CUI — assessed against applicable requirements. |
| Security Protection Assets | Provide security to the CUI environment — in scope. |
| Contractor Risk Managed Assets | Capable of handling CUI but not intended to — managed by policy/config. |
| Specialized Assets | IoT/OT, GFE, test equipment — documented, limited assessment. |
| Out-of-Scope Assets | Isolated from CUI — not assessed. |
## External Service Providers / cloud
- Cloud services that store/process/transmit CUI must be **FedRAMP Moderate authorized or meet FedRAMP Moderate equivalency**.
- Document the customer/provider responsibility split (CRM) and inherited controls in the SSP.
## NIST CSF 2.0 alignment
| CSF 2.0 ID | Relevance |
|---|---|
| GV.OC-03 | Legal/regulatory (DFARS/CMMC) requirements understood. |
| GV.SC-01 | Supply-chain risk management — flowdown to subs / ESPs. |
| ID.AM-08 | Assets managed across the lifecycle (scoping). |
| ID.RA-05 | Risk informs prioritization of unmet requirements. |
| PR.AA-01 | Identity and access (3.1 / 3.5 families). |
| PR.DS-01 | Data-at-rest protection (FIPS crypto, media protection). |
@@ -0,0 +1,198 @@
#!/usr/bin/env python3
"""
CMMC Level 2 / NIST SP 800-171 Rev 2 SPRS score calculator.
Implements the DoD Assessment Methodology arithmetic: start at 110 and subtract
the weighted value (1, 3, or 5) of each NOT MET requirement, with partial credit
for the small set of requirements that allow it. Reports the SPRS score, the gap
to a perfect 110 and to the 88-point (80%) conditional-certification threshold,
and flags higher-weighted unmet requirements whose POA&M eligibility must be
verified against 32 CFR Part 170.
NOTE: per-requirement point weights are defined by the DoD NIST SP 800-171
Assessment Methodology. Supply each requirement's official weight in the input
(this tool does not invent weights). Use status 'partial' with 'partial_deduction'
only for requirements the methodology allows partial credit on (e.g., 3.5.3 MFA,
3.13.11 FIPS crypto).
Input JSON shape:
{
"org": {"name": "Acme Defense LLC", "scope": "CUI enclave"},
"requirements": [
{"id": "3.1.1", "family": "3.1", "status": "met", "weight": 5},
{"id": "3.5.3", "family": "3.5", "status": "partial", "weight": 5, "partial_deduction": 3},
{"id": "3.3.1", "family": "3.3", "status": "not_met", "weight": 5},
{"id": "3.8.9", "family": "3.8", "status": "not_met", "weight": 1},
{"id": "3.2.1", "family": "3.2", "status": "na", "weight": 1}
]
}
status: met | not_met | partial | na
Usage:
python process.py --input controls.json [--output readiness.md]
python process.py --input controls.json --require-conditional # exit 1 if score < 88
"""
import argparse
import json
import sys
START_SCORE = 110
CONDITIONAL_THRESHOLD = 88 # 80% of 110
VALID_STATUS = {"met", "not_met", "partial", "na"}
VALID_WEIGHTS = {1, 3, 5}
def compute(data):
reqs = data.get("requirements", [])
if not reqs:
raise ValueError("requirements list is required")
deductions = 0
counts = {"met": 0, "not_met": 0, "partial": 0, "na": 0}
poam_flags = [] # higher-weight unmet -> verify POA&M eligibility
by_family = {} # family -> {met,not_met,partial,na}
detail = []
for r in reqs:
rid = r.get("id", "?")
status = r.get("status")
weight = r.get("weight")
if status not in VALID_STATUS:
raise ValueError(f"{rid}: status '{status}' invalid (met|not_met|partial|na)")
if status in ("not_met", "partial", "met") and weight not in VALID_WEIGHTS:
raise ValueError(f"{rid}: weight '{weight}' invalid (must be 1, 3, or 5)")
fam = r.get("family", rid.rsplit(".", 1)[0])
fam_rec = by_family.setdefault(fam, {"met": 0, "not_met": 0, "partial": 0, "na": 0})
fam_rec[status] += 1
counts[status] += 1
ded = 0
if status == "not_met":
ded = weight
if weight > 1:
poam_flags.append((rid, weight))
elif status == "partial":
ded = r.get("partial_deduction")
if ded is None:
raise ValueError(f"{rid}: status 'partial' requires 'partial_deduction'")
if ded < 0 or ded > weight:
raise ValueError(f"{rid}: partial_deduction {ded} out of range (0..{weight})")
if ded > 1:
poam_flags.append((rid, ded))
deductions += ded
detail.append((rid, fam, status, weight, ded))
score = START_SCORE - deductions
return {
"score": score,
"deductions": deductions,
"counts": counts,
"by_family": by_family,
"poam_flags": poam_flags,
"detail": detail,
}
def render(data, res):
org = data.get("org", {})
lines = []
lines.append(f"# CMMC Level 2 Readiness - {org.get('name','Organization')}")
lines.append("")
if org.get("scope"):
lines.append(f"- **Scope:** {org['scope']}")
lines.append("")
score = res["score"]
lines.append("## SPRS Score (DoD Assessment Methodology)")
lines.append("")
lines.append(f"- **Score:** **{score}** / 110 (started at 110, deducted {res['deductions']})")
lines.append(f"- **Gap to perfect (110):** {110 - score}")
if score >= CONDITIONAL_THRESHOLD:
lines.append(f"- **Conditional threshold (>= {CONDITIONAL_THRESHOLD}):** MET "
f"(margin {score - CONDITIONAL_THRESHOLD}) - eligible for Conditional status "
"if remaining items are POA&M-eligible.")
else:
lines.append(f"- **Conditional threshold (>= {CONDITIONAL_THRESHOLD}):** NOT MET "
f"(short by {CONDITIONAL_THRESHOLD - score}) - not eligible for Conditional "
"certification until the score reaches 88.")
c = res["counts"]
lines.append(f"- **Status tally:** met {c['met']}, partial {c['partial']}, "
f"not met {c['not_met']}, N/A {c['na']}")
lines.append("")
# by family
lines.append("## Status by family")
lines.append("")
lines.append("| Family | Met | Partial | Not Met | N/A |")
lines.append("|---|---|---|---|---|")
for fam in sorted(res["by_family"]):
f = res["by_family"][fam]
lines.append(f"| {fam} | {f['met']} | {f['partial']} | {f['not_met']} | {f['na']} |")
lines.append("")
# POA&M eligibility flags
lines.append("## POA&M eligibility check")
lines.append("")
if not res["poam_flags"]:
lines.append("No unmet requirement carries more than 1 point of deduction. "
"Remaining gaps are most likely POA&M-eligible (still verify against 32 CFR Part 170).")
else:
lines.append("The following unmet/partial requirements carry **> 1 point**. The highest-weighted "
"security requirements generally **cannot** sit on a POA&M - verify each against "
"32 CFR Part 170 before relying on Conditional status:")
lines.append("")
lines.append("| Requirement | Points lost |")
lines.append("|---|---|")
for rid, w in sorted(res["poam_flags"], key=lambda x: -x[1]):
lines.append(f"| {rid} | {w} |")
lines.append("")
lines.append("> All POA&M items must be closed within **180 days** to convert Conditional -> Final.")
return "\n".join(lines)
def main():
ap = argparse.ArgumentParser(description="CMMC L2 / NIST 800-171 SPRS score calculator")
ap.add_argument("--input", "-i", required=True, help="Path to control-status JSON")
ap.add_argument("--output", "-o", help="Write Markdown readiness report to this path")
ap.add_argument("--require-conditional", action="store_true",
help="Exit non-zero if SPRS score < 88 (conditional threshold)")
args = ap.parse_args()
try:
with open(args.input) as f:
data = json.load(f)
except (OSError, json.JSONDecodeError) as e:
print(f"ERROR: could not read input JSON: {e}", file=sys.stderr)
return 2
try:
res = compute(data)
md = render(data, res)
except ValueError as e:
print(f"ERROR: {e}", file=sys.stderr)
return 2
if args.output:
with open(args.output, "w") as f:
f.write(md + "\n")
print(f"Readiness report written to {args.output}", file=sys.stderr)
else:
print(md)
print(f"SPRS score {res['score']}/110 (deductions {res['deductions']}; "
f"not met {res['counts']['not_met']}, partial {res['counts']['partial']}).",
file=sys.stderr)
if args.require_conditional and res["score"] < CONDITIONAL_THRESHOLD:
print(f"FAIL: score {res['score']} < {CONDITIONAL_THRESHOLD} conditional threshold.",
file=sys.stderr)
return 1
return 0
if __name__ == "__main__":
sys.exit(main())
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to the Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by the Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding any notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. Please do not remove or change
the license header comment from a contributed file except when
necessary.
Copyright 2026 mukul975
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
@@ -0,0 +1,145 @@
---
name: conducting-cyber-risk-assessment-with-nist-800-30
description: >-
Conduct a defensible cybersecurity risk assessment using the NIST SP 800-30 Rev 1
methodology: prepare scope and a risk model, identify threat sources and threat events,
identify vulnerabilities and predisposing conditions, determine likelihood and impact,
compute risk, and communicate results as a prioritized risk register. Use when an
organization needs an actual risk *assessment* (not a maturity score), when a control
framework (CSF, ISO 27001, RMF, SOC 2, PCI) requires a documented risk analysis as input,
when leadership asks "what are our top risks and how bad are they", when assessing risk
for a new system or major change, or when building a risk register from scratch. This is
the methodology that feeds framework selection, ATO packages, and treatment decisions.
Keywords: risk assessment, NIST 800-30, threat modeling, likelihood and impact, risk
register, risk analysis, threat sources, vulnerabilities, risk determination, qualitative
risk, risk matrix, residual risk, risk treatment.
domain: cybersecurity
subdomain: compliance-governance
tags:
- risk-assessment
- nist-800-30
- risk-management
- threat-modeling
- risk-register
- governance
- nist-800-39
- compliance
version: "1.0"
author: andrewibrah
license: Apache-2.0
nist_csf:
- GV.RM-01
- ID.RA-01
- ID.RA-03
- ID.RA-04
- ID.RA-05
mitre_attack:
- T1566
- T1078
- T1190
- T1486
- T1021
---
# Conducting a Cyber Risk Assessment with NIST SP 800-30
## When to Use
- When the organization needs a real risk *assessment* — an analysis of specific threats, likelihoods, and impacts — rather than a maturity score against a framework. (Maturity tells you how mature your practices are; a risk assessment tells you what could hurt you and how badly.)
- When another framework requires a documented risk analysis as a mandatory input: NIST CSF (ID.RA), ISO 27001 (Clause 6.1.2), NIST RMF / 800-37 (the Prepare and Select steps), SOC 2 (CC3), PCI DSS, or HIPAA (§164.308(a)(1)(ii)(A)).
- When standing up or significantly changing a system and you must understand its risk before authorization or go-live.
- When leadership asks for the organization's top risks, ranked, with a rationale they can defend to a board or regulator.
- When building or refreshing an enterprise risk register.
## Prerequisites
- An inventory of in-scope assets, systems, and the information types they handle (system boundary defined).
- Access to threat intelligence (internal incident history, sector ISAC feeds, MITRE ATT&CK) to ground threat-event likelihood in observed behavior.
- Vulnerability data (scan results, pen-test findings, configuration/architecture review) for the in-scope systems.
- Business context: which missions/processes the systems support, and what impact to confidentiality, integrity, or availability would mean in business terms.
- Agreement on the **risk model and scales** before scoring, so results are comparable and repeatable (see `references/standards.md`).
- Familiarity with the three-tier risk-management context from NIST SP 800-39 (organization, mission/business process, information system).
## Workflow
NIST SP 800-30 Rev 1 defines four steps. Steps 1 and 4 bookend the assessment; Step 2 is the analytic core.
### 1. Prepare for the assessment
Define and document:
- **Purpose** (e.g., support an authorization decision, inform control selection, satisfy ISO 6.1.2).
- **Scope** — organizational tier (Tier 1/2/3), systems, and time horizon.
- **Assumptions and constraints** (e.g., assume an external adversarial threat with moderate capability).
- **Information sources** — threat, vulnerability, and impact inputs.
- **Risk model and analytic approach** — the factors (threat source, threat event, vulnerability, likelihood, impact) and the scales (qualitative Very LowVery High, or semi-quantitative 010). Lock these now.
### 2. Conduct the assessment
Work through the analytic tasks in order. The 800-30 appendices provide the reference taxonomies (DI).
**2a. Identify threat sources (Appendix D).** Classify by type: **Adversarial** (individuals, groups, nation-states — characterize capability, intent, targeting), **Accidental** (user error), **Structural** (equipment/software failure), **Environmental** (natural disasters, infrastructure outages).
**2b. Identify threat events (Appendix E).** The specific actions a source could take (e.g., "adversary exfiltrates credentials via phishing then moves laterally"). Map adversarial events to MITRE ATT&CK techniques for traceability.
**2c. Identify vulnerabilities and predisposing conditions (Appendix F).** Weaknesses (missing MFA, unpatched service) and conditions that make exploitation more or less likely (internet exposure, flat network, lack of segmentation).
**2d. Determine likelihood (Appendix G).** Assess the likelihood that a threat event is *initiated* (adversarial) or *occurs* (non-adversarial), and the likelihood it results in adverse impact given the vulnerabilities. Combine into an overall likelihood on the agreed scale.
**2e. Determine impact (Appendix H).** Magnitude of harm if the event succeeds — to operations, assets, individuals, other organizations, or the nation. Express against the agreed scale and in business terms.
**2f. Determine risk (Appendix I).** Risk is a function of likelihood and impact. Plot each threat event on the risk matrix (e.g., likelihood × impact → Very Low … Very High). Record the risk level, the contributing factors, and uncertainty/assumptions.
### 3. Communicate and share results
Produce the **risk register** and an executive briefing. For each risk: the threat event, affected assets, likelihood, impact, risk level, key contributing vulnerabilities, and a recommended treatment. Rank by risk level so decision-makers see the top risks first.
### 4. Maintain the assessment
Risk is not static. Define a refresh cadence and the triggers that force re-assessment (new system, major architecture change, significant incident, new threat intel). Track risk-acceptance decisions and treatment progress over time.
### 5. Drive treatment decisions
Hand the ranked register to risk owners. For each risk choose a treatment — **mitigate** (add/strengthen controls), **transfer** (insurance, contractual), **avoid** (stop the activity), or **accept** (document residual risk with an authorizing signature). Re-score residual risk after planned controls to show the post-treatment position.
## Key Concepts
| Concept | Definition |
|---|---|
| Threat source | The cause of a threat event: adversarial, accidental, structural, or environmental. |
| Threat event | A specific action or occurrence that could cause harm (mapped to ATT&CK for adversarial cases). |
| Vulnerability | A weakness that a threat event can exploit. |
| Predisposing condition | A condition that increases or decreases the likelihood of adverse impact (e.g., internet exposure). |
| Likelihood | The chance a threat event initiates/occurs *and* results in adverse impact. |
| Impact | The magnitude of harm if the event succeeds. |
| Risk | A function of likelihood and impact; the expected harm to the organization. |
| Inherent vs residual risk | Risk before vs after planned/implemented controls. |
| Risk tolerance / appetite | The level of risk leadership is willing to accept. |
| Risk register | The prioritized record of risks, scores, owners, and treatments. |
## Tools & Systems
- **NIST SP 800-30 Rev 1** — the methodology and Appendices DI taxonomies (threat sources, events, vulnerabilities, likelihood, impact, risk).
- **NIST SP 800-39** — enterprise risk-management context (three tiers).
- **MITRE ATT&CK** — to enumerate and ground adversarial threat events in observed TTPs.
- **Vulnerability scanners / pen-test reports** — empirical vulnerability input.
- **Threat intel sources** — sector ISACs, vendor feeds, internal incident history for likelihood grounding.
- **GRC / risk-register tooling** — spreadsheet, or platforms such as ServiceNow GRC, Archer, OneTrust, to store and track the register.
- **FAIR** (optional) — a quantitative model if leadership wants risk expressed in dollar ranges rather than qualitative bands.
## Common Scenarios
- **CSF/ISO/SOC 2 needs a risk analysis.** Run 800-30 to produce the documented assessment those frameworks require as input, then map results to their control sets.
- **New system before go-live.** Assess threat events against the system's architecture and feed the result into the authorization (RMF Select/Authorize) decision.
- **Board wants the top risks.** Deliver a ranked register with impacts in business terms and clear treatment recommendations.
- **Post-incident.** Re-assess the affected systems; the incident updates likelihood evidence and may surface new threat events.
- **Annual refresh.** Re-score against current threat intel and control changes; show movement in residual risk year over year.
## Output Format
Produce a **Risk Assessment Report** using `assets/template.md`, containing:
1. **Purpose, scope, and tier** — what was assessed and why.
2. **Assumptions, constraints, and risk model** — the factors and scales used (so results are reproducible).
3. **Threat sources** — by type, with adversarial characterization.
4. **Threat events** — each with affected assets and ATT&CK mapping where adversarial.
5. **Vulnerabilities and predisposing conditions** — tied to threat events.
6. **Risk register** — table: ID, threat event, asset, likelihood, impact, **risk level**, contributing vulnerabilities, recommended treatment, owner, residual risk.
7. **Top risks summary** — ranked, in business terms, for leadership.
8. **Maintenance plan** — refresh cadence and re-assessment triggers.
Use `scripts/process.py` to score the register from a risk-input JSON (likelihood × impact → risk level on a configurable matrix), rank risks, and emit the register table.
@@ -0,0 +1,60 @@
# Risk Assessment Report (NIST SP 800-30 Rev 1) — Worked Example
> Filled example for a mid-size SaaS company assessing its internet-facing
> application tier. Replace bracketed content for your own assessment.
## 1. Purpose, Scope, and Tier
- **Purpose:** Inform control-investment decisions for FY26 and satisfy the documented risk-analysis input required by the company's SOC 2 (CC3) program and ISO 27001 Clause 6.1.2.
- **Scope:** Internet-facing application tier — customer web portal, its identity provider (IdP), the API gateway, and the data lake behind them.
- **Risk-management tier (SP 800-39):** Tier 3 (information system), rolling up to Tier 2 (the "Customer Platform" mission).
- **Assessment window:** FY26 Q2; valid 12 months or until a triggering change.
## 2. Assumptions, Constraints, and Risk Model
- **Assumptions:** A financially motivated external adversary of moderate-to-high capability is actively targeting the sector; internal users are trusted but fallible.
- **Constraints:** Assessment is architecture- and scan-driven; no red-team engagement was run this cycle.
- **Risk model:** Factors = threat source, threat event, vulnerability/predisposing condition, likelihood, impact. Adversarial threat events are mapped to MITRE ATT&CK.
- **Scales:** Five-level qualitative (Very Low → Very High). Risk computed via the 800-30 Rev 1 reference 5×5 matrix (see `references/standards.md`). This matrix was agreed during Prepare and is locked for the cycle.
## 3. Threat Sources (Appendix D)
| Source | Type | Characterization |
|---|---|---|
| Organized cybercrime group | Adversarial | High capability, financial intent, opportunistic + targeted |
| Authorized employee | Accidental | Misconfiguration / human error |
| Hardware/software failure | Structural | Storage, service, or dependency failure |
| Regional power / cloud-region outage | Environmental | Low frequency, availability impact |
## 4. Threat Events (Appendix E)
| ID | Threat event | Source | ATT&CK |
|---|---|---|---|
| R-01 | Adversary phishes employee credentials, then moves laterally to the IdP | Adversarial | T1566, T1021 |
| R-02 | Adversary exploits an unpatched edge VPN to deploy ransomware | Adversarial | T1190 |
| R-04 | Employee misconfigures a data-lake bucket to public | Accidental | — |
| R-03 | SIEM storage disk fails, corrupting un-backed-up logs | Structural | — |
## 5. Vulnerabilities and Predisposing Conditions (Appendix F)
| Threat event | Vulnerabilities / conditions |
|---|---|
| R-01 | No phishing-resistant MFA; flat internal network (no segmentation) |
| R-02 | VPN appliance missing a critical patch; internet-exposed management plane |
| R-04 | No preventive SCP/guardrail; broad write permissions on storage |
| R-03 | No RAID; no offsite/immutable backup of SIEM data |
## 6. Risk Register
*(generated by `scripts/process.py`; likelihood × impact → risk on the 800-30 5×5 matrix, ranked highest-first)*
| ID | Threat event | Source | Asset | ATT&CK | Likelihood | Impact | Risk | Key vulnerabilities | Treatment | Residual | Owner |
|---|---|---|---|---|---|---|---|---|---|---|---|
| R-01 | Phish → lateral movement to IdP | Adversarial | Identity provider | T1566, T1021 | High | Very High | **Very High** | No phishing-resistant MFA; flat network | Mitigate | Moderate | IAM Lead |
| R-02 | Ransomware via unpatched edge VPN | Adversarial | VPN concentrator | T1190 | Moderate | Very High | **High** | Missing critical patch | Mitigate | Low | Infra |
| R-04 | Public S3 misconfiguration | Accidental | Data lake | — | Moderate | High | **Moderate** | No SCP guardrail | Mitigate | Low | Cloud |
| R-03 | Disk failure corrupts logs | Structural | SIEM storage | — | Low | Moderate | **Low** | No RAID; no offsite backup | Accept | Low | SOC |
## 7. Top Risks Summary (for leadership)
1. **R-01 — Very High.** A successful phish into our identity provider is the single most damaging plausible event: it grants broad access and, on a flat network, fast lateral movement. **Recommendation:** deploy phishing-resistant MFA (FIDO2) and segment the IdP — this is the highest-leverage control this fiscal year.
2. **R-02 — High.** Edge-VPN ransomware is a sector-common entry path. **Recommendation:** emergency-patch the appliance, restrict the management plane, and validate offline backups.
3. **R-04 — Moderate.** Cloud misconfiguration is likely but bounded; a preventive SCP guardrail collapses the likelihood cheaply.
## 8. Maintenance Plan
- **Cadence:** Full re-assessment annually; register reviewed quarterly.
- **Re-assessment triggers:** new internet-facing system, major architecture change, any incident affecting in-scope assets, or significant new threat intel (e.g., active exploitation of a component we run).
- **Tracking:** Treatment progress and risk-acceptance signatures recorded in the GRC tool; residual risk re-scored after each control lands to show year-over-year movement.
@@ -0,0 +1,77 @@
# NIST SP 800-30 — Standards & Reference
## Primary standard
### NIST SP 800-30 Revision 1 — Guide for Conducting Risk Assessments
- **Publisher**: NIST
- **Published**: September 2012
- **Scope**: The risk-assessment component of the broader risk-management process.
- **URL**: https://csrc.nist.gov/pubs/sp/800/30/r1/final
## Companion standards
| Document | Role |
|---|---|
| NIST SP 800-39 | Managing Information Security Risk — three-tier context (Tier 1 organization, Tier 2 mission/business process, Tier 3 information system). |
| NIST SP 800-37 Rev 2 | Risk Management Framework — risk assessment feeds the Prepare, Select, and Authorize steps. |
| NIST SP 800-53 Rev 5 | Control catalog — source of mitigating controls chosen in risk treatment. |
| FIPS 199 / FIPS 200 | Security categorization (L/M/H per C/I/A) and minimum requirements. |
| MITRE ATT&CK | Adversarial threat-event enumeration and traceability. |
| FAIR (Open Group) | Optional quantitative risk model (dollar-range loss exposure). |
## The four-step process (800-30 Rev 1)
1. **Prepare** — purpose, scope, assumptions/constraints, sources, risk model and scales.
2. **Conduct** — tasks 2a2f below.
3. **Communicate** — risk register + briefing.
4. **Maintain** — monitoring and refresh.
### Conduct tasks and their reference appendices
| Task | Appendix | Output |
|---|---|---|
| Identify threat sources | D | Adversarial / Accidental / Structural / Environmental sources |
| Identify threat events | E | Specific events (map adversarial to ATT&CK) |
| Identify vulnerabilities & predisposing conditions | F | Weaknesses + conditions affecting impact likelihood |
| Determine likelihood | G | Likelihood of initiation/occurrence and of adverse impact |
| Determine impact | H | Magnitude of harm |
| Determine risk | I | Risk level = f(likelihood, impact) |
## Threat source types (Appendix D)
- **Adversarial** — individuals, groups, organizations, nation-states. Characterize by capability, intent, and targeting.
- **Accidental** — erroneous actions by authorized users.
- **Structural** — failures of equipment, software, or environmental controls.
- **Environmental** — natural or man-made disasters, infrastructure outages.
## Assessment scales (qualitative / semi-quantitative)
800-30 uses five-level scales. A common qualitative mapping:
| Level | Semi-quantitative (010) |
|---|---|
| Very Low | 04 |
| Low | 520 |
| Moderate | 2179 |
| High | 8095 |
| Very High | 96100 |
### Reference 5×5 risk matrix (likelihood × impact → risk)
| Likelihood ↓ / Impact → | Very Low | Low | Moderate | High | Very High |
|---|---|---|---|---|---|
| Very High | Very Low | Low | Moderate | High | Very High |
| High | Very Low | Low | Moderate | High | Very High |
| Moderate | Very Low | Low | Moderate | Moderate | High |
| Low | Very Low | Low | Low | Low | Moderate |
| Very Low | Very Low | Very Low | Very Low | Low | Low |
> Document whichever matrix the organization adopts during Prepare; the engine in `scripts/process.py` defaults to the table above and is configurable.
## NIST CSF 2.0 alignment
| CSF 2.0 ID | Relevance |
|---|---|
| GV.RM-01 | Risk management objectives established |
| ID.RA-01 | Vulnerabilities in assets identified |
| ID.RA-03 | Internal and external threats identified |
| ID.RA-04 | Potential impacts and likelihoods identified |
| ID.RA-05 | Threats, vulnerabilities, likelihoods, and impacts used to understand inherent risk and prioritize response |
## Risk treatment options
- **Mitigate** — implement/strengthen controls (re-score residual risk).
- **Transfer** — insurance or contractual shift.
- **Avoid** — discontinue the risk-generating activity.
- **Accept** — document residual risk with an authorizing signature within risk tolerance.
@@ -0,0 +1,227 @@
#!/usr/bin/env python3
"""
NIST SP 800-30 Rev 1 risk-register scoring engine.
Reads a risk-input JSON file describing threat events with their assessed
likelihood and impact, computes a risk level for each using the 800-30 5x5
reference matrix (configurable), ranks the register highest-risk-first, and
emits a Markdown risk register plus a top-risks summary.
Input JSON shape:
{
"assessment": {
"name": "Q2 FY26 Enterprise Risk Assessment",
"scope": "Internet-facing application tier",
"tier": 3
},
"matrix": { # OPTIONAL - overrides the default 800-30 matrix
"High": {"Very High": "Very High", ...}
},
"risks": [
{
"id": "R-01",
"threat_event": "Adversary phishes credentials and moves laterally",
"threat_source": "Adversarial",
"asset": "Customer portal / identity provider",
"attack_techniques": ["T1566", "T1021"],
"likelihood": "High",
"impact": "Very High",
"vulnerabilities": ["No phishing-resistant MFA", "Flat internal network"],
"treatment": "Mitigate",
"owner": "IAM Lead",
"residual_risk": "Moderate"
}
]
}
Likelihood / impact values must be one of:
Very Low | Low | Moderate | High | Very High
Usage:
python process.py --input risks.json [--output register.md] [--fail-on High]
python process.py --print-matrix
"""
import argparse
import json
import sys
LEVELS = ["Very Low", "Low", "Moderate", "High", "Very High"]
RANK = {lvl: i for i, lvl in enumerate(LEVELS)}
# 800-30 Rev 1 reference 5x5 matrix: MATRIX[likelihood][impact] -> risk level
MATRIX = {
"Very High": {"Very Low": "Very Low", "Low": "Low", "Moderate": "Moderate", "High": "High", "Very High": "Very High"},
"High": {"Very Low": "Very Low", "Low": "Low", "Moderate": "Moderate", "High": "High", "Very High": "Very High"},
"Moderate": {"Very Low": "Very Low", "Low": "Low", "Moderate": "Moderate", "High": "Moderate", "Very High": "High"},
"Low": {"Very Low": "Very Low", "Low": "Low", "Moderate": "Low", "High": "Low", "Very High": "Moderate"},
"Very Low": {"Very Low": "Very Low", "Low": "Very Low", "Moderate": "Very Low", "High": "Low", "Very High": "Low"},
}
def validate_level(value, field, rid):
if value not in LEVELS:
raise ValueError(
f"risk {rid}: {field} '{value}' is not a valid 800-30 level "
f"(expected one of {LEVELS})"
)
return value
def score_risk(risk, matrix):
rid = risk.get("id", "?")
likelihood = validate_level(risk.get("likelihood"), "likelihood", rid)
impact = validate_level(risk.get("impact"), "impact", rid)
level = matrix[likelihood][impact]
return level
def render_markdown(data, matrix):
meta = data.get("assessment", {})
risks = data.get("risks", [])
scored = []
for r in risks:
level = score_risk(r, matrix)
scored.append((r, level))
# rank highest risk first; tie-break by impact then likelihood
scored.sort(
key=lambda rl: (
RANK[rl[1]],
RANK[rl[0].get("impact", "Very Low")],
RANK[rl[0].get("likelihood", "Very Low")],
),
reverse=True,
)
lines = []
title = meta.get("name", "Risk Assessment")
lines.append(f"# Risk Register - {title}")
lines.append("")
if meta.get("scope"):
lines.append(f"- **Scope:** {meta['scope']}")
if meta.get("tier"):
lines.append(f"- **Risk-management tier (SP 800-39):** Tier {meta['tier']}")
lines.append(f"- **Risks assessed:** {len(scored)}")
lines.append("")
lines.append("Risk level computed from likelihood x impact on the NIST SP 800-30 Rev 1 5x5 matrix.")
lines.append("")
# main register
header = (
"| ID | Threat event | Source | Asset | ATT&CK | Likelihood | Impact "
"| Risk | Key vulnerabilities | Treatment | Residual | Owner |"
)
sep = "|" + "---|" * 12
lines.append(header)
lines.append(sep)
for r, level in scored:
attck = ", ".join(r.get("attack_techniques", [])) or "-"
vulns = "; ".join(r.get("vulnerabilities", [])) or "-"
lines.append(
"| {id} | {event} | {src} | {asset} | {attck} | {like} | {imp} "
"| **{risk}** | {vulns} | {treat} | {res} | {owner} |".format(
id=r.get("id", "-"),
event=r.get("threat_event", "-"),
src=r.get("threat_source", "-"),
asset=r.get("asset", "-"),
attck=attck,
like=r.get("likelihood", "-"),
imp=r.get("impact", "-"),
risk=level,
vulns=vulns,
treat=r.get("treatment", "-"),
res=r.get("residual_risk", "-"),
owner=r.get("owner", "-"),
)
)
# top risks summary
top = [rl for rl in scored if RANK[rl[1]] >= RANK["High"]]
lines.append("")
lines.append("## Top risks (High and above)")
lines.append("")
if not top:
lines.append("_No risks scored High or above._")
else:
for r, level in top:
lines.append(f"- **{level}** - {r.get('id','-')}: {r.get('threat_event','-')} "
f"(impact {r.get('impact','-')}, likelihood {r.get('likelihood','-')})")
# distribution
dist = {lvl: 0 for lvl in LEVELS}
for _, level in scored:
dist[level] += 1
lines.append("")
lines.append("## Risk distribution")
lines.append("")
lines.append("| Risk level | Count |")
lines.append("|---|---|")
for lvl in reversed(LEVELS):
lines.append(f"| {lvl} | {dist[lvl]} |")
return "\n".join(lines), scored, dist
def main():
ap = argparse.ArgumentParser(description="NIST SP 800-30 risk-register scoring engine")
ap.add_argument("--input", "-i", help="Path to risk-input JSON")
ap.add_argument("--output", "-o", help="Write Markdown register to this path")
ap.add_argument("--fail-on", choices=LEVELS,
help="Exit non-zero if any risk scores at or above this level (for pipelines)")
ap.add_argument("--print-matrix", action="store_true", help="Print the active risk matrix and exit")
args = ap.parse_args()
if args.print_matrix:
print("NIST SP 800-30 Rev 1 reference 5x5 matrix (likelihood x impact -> risk):\n")
hdr = "Likelihood \\ Impact | " + " | ".join(LEVELS)
print(hdr)
print("-" * len(hdr))
for like in reversed(LEVELS):
row = " | ".join(MATRIX[like][imp] for imp in LEVELS)
print(f"{like} | {row}")
return 0
if not args.input:
ap.error("--input is required unless --print-matrix is used")
try:
with open(args.input) as f:
data = json.load(f)
except (OSError, json.JSONDecodeError) as e:
print(f"ERROR: could not read input JSON: {e}", file=sys.stderr)
return 2
matrix = data.get("matrix", MATRIX)
try:
md, scored, dist = render_markdown(data, matrix)
except ValueError as e:
print(f"ERROR: {e}", file=sys.stderr)
return 2
if args.output:
with open(args.output, "w") as f:
f.write(md + "\n")
print(f"Risk register written to {args.output}", file=sys.stderr)
else:
print(md)
# summary to stderr
summary = ", ".join(f"{lvl}:{dist[lvl]}" for lvl in reversed(LEVELS) if dist[lvl])
print(f"Scored {len(scored)} risks ({summary}).", file=sys.stderr)
if args.fail_on:
threshold = RANK[args.fail_on]
breaches = [(r.get("id", "?"), lvl) for r, lvl in scored if RANK[lvl] >= threshold]
if breaches:
ids = ", ".join(f"{rid}={lvl}" for rid, lvl in breaches)
print(f"FAIL: {len(breaches)} risk(s) at or above {args.fail_on}: {ids}", file=sys.stderr)
return 1
return 0
if __name__ == "__main__":
sys.exit(main())
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to the Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by the Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding any notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. Please do not remove or change
the license header comment from a contributed file except when
necessary.
Copyright 2026 mukul975
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
@@ -0,0 +1,142 @@
---
name: executing-nist-rmf-authorization-to-operate
description: >-
Drive a federal system through the NIST Risk Management Framework (SP 800-37 Rev 2)
to an Authorization to Operate (ATO): Prepare, Categorize (FIPS 199), Select a control
baseline (FIPS 200 / SP 800-53 Rev 5), Implement, Assess (SP 800-53A), Authorize, and
Monitor continuously. Use when a system needs an ATO or a renewal, when working a
FISMA/FedRAMP authorization package, when building or reviewing an SSP, SAR, or POA&M,
when categorizing a system as Low/Moderate/High impact, when selecting or tailoring a
control baseline, or when standing up continuous monitoring (ConMon) after authorization.
Covers ATO, conditional ATO (cATO), and the artifacts assessors expect. Keywords: NIST
RMF, 800-37, ATO, authorization to operate, FISMA, FedRAMP, SSP, SAR, POA&M, FIPS 199,
FIPS 200, 800-53, 800-53A, control baseline, security categorization, continuous
monitoring, authorizing official, system boundary, ongoing authorization.
domain: cybersecurity
subdomain: compliance-governance
tags:
- nist-rmf
- nist-800-37
- ato
- fisma
- fedramp
- nist-800-53
- fips-199
- ssp
- poam
- continuous-monitoring
- governance
version: "1.0"
author: andrewibrah
license: Apache-2.0
nist_csf:
- GV.OC-03
- GV.RM-01
- ID.AM-08
- ID.RA-05
- PR.IR-01
mitre_attack:
- T1078
- T1190
- T1068
- T1210
- T1486
---
# Executing the NIST RMF to an Authorization to Operate (ATO)
## When to Use
- When a federal or federally-aligned system (or a FedRAMP cloud service) needs an **Authorization to Operate**, a re-authorization, or has fallen out of authorization.
- When you must produce or review the core authorization artifacts: **System Security Plan (SSP)**, **Security Assessment Report (SAR)**, and **Plan of Action & Milestones (POA&M)**.
- When categorizing a system's impact level (Low / Moderate / High) under **FIPS 199**.
- When selecting, tailoring, or implementing a **NIST SP 800-53 Rev 5** control baseline.
- When standing up **continuous monitoring (ConMon)** or pursuing **ongoing authorization / cATO** after an initial ATO.
## Prerequisites
- A defined **system** and **authorization boundary** (what's in, what's inherited, what's a leveraged service).
- An identified **Authorizing Official (AO)**, **System Owner**, and **ISSO**.
- The information types the system handles (use **SP 800-60** to map them to impact levels).
- For cloud: the provider's **Customer Responsibility Matrix (CRM)** and any inherited/leveraged ATO.
- Access to assessment evidence sources (config, scans, policies) for the Assess step.
## Workflow
NIST SP 800-37 Rev 2 defines **seven steps**. Prepare is the foundation; the rest run in order and then loop through Monitor.
### 0/1. Prepare (organization and system level)
Establish context: roles (AO, SO, ISSO, assessor), risk-management strategy and tolerance (ties to SP 800-39), a control baseline strategy, common controls available for inheritance, and the system's mission/business context. Define the **authorization boundary** precisely — scope creep here inflates the whole package.
### 2. Categorize (FIPS 199 + SP 800-60)
Determine the impact level for **confidentiality, integrity, and availability** for each information type, then take the **high-water mark** across the three to set the overall system categorization: **Low**, **Moderate**, or **High**. Document in the SSP. This single decision drives the entire control baseline.
### 3. Select (FIPS 200 + SP 800-53 Rev 5 + SP 800-53B)
Start from the SP 800-53B baseline matching the categorization (Low/Moderate/High). Then **tailor**: apply scoping guidance, select compensating controls where needed, and assign values to organization-defined parameters. Add overlays (e.g., privacy, FedRAMP). Record the tailored set and the rationale in the SSP. Identify which controls are **common (inherited)**, **system-specific**, or **hybrid**.
### 4. Implement
Deploy the selected controls and **document how each is implemented** in the SSP — the implementation statement, not just "yes." This is the artifact assessors read first; vague statements generate findings.
### 5. Assess (SP 800-53A Rev 5)
An independent assessor evaluates controls using the **examine / interview / test** methods against assessment objectives. Findings of "other than satisfied" become weaknesses. Output is the **Security Assessment Report (SAR)**. Remediate what you can before authorization; the rest flows to the POA&M.
### 6. Authorize
Assemble the **authorization package**: SSP + SAR + POA&M (plus supporting artifacts). The AO reviews **residual risk** and renders a decision:
- **ATO** — authorized, typically with a defined term and a ConMon expectation.
- **Conditional / cATO** — authorized subject to conditions or operating under an approved ongoing-authorization model.
- **Denial / DATO** — risk too high; system may not operate.
The decision and its rationale are captured in the **authorization decision document**.
### 7. Monitor (continuous monitoring)
Authorization is not a one-time gate. Maintain an ongoing posture: track control effectiveness, ingest scan/config drift, update the SSP on change, work the POA&M to closure, report per the ConMon plan, and feed significant changes back into reassessment. Mature programs move from periodic re-ATO to **ongoing authorization**.
## Key Concepts
| Concept | Definition |
|---|---|
| Authorization boundary | The set of components, data flows, and inherited services covered by the authorization. |
| FIPS 199 categorization | Low/Moderate/High per C/I/A; overall = high-water mark across the three. |
| Control baseline | The SP 800-53B starting control set for the categorization, before tailoring. |
| Tailoring | Adjusting the baseline via scoping, compensating controls, and parameter values. |
| Common / inherited control | A control provided by another entity (e.g., the platform) and inherited by the system. |
| SSP | System Security Plan — describes the system, boundary, and how each control is implemented. |
| SAR | Security Assessment Report — the assessor's findings on control effectiveness. |
| POA&M | Plan of Action & Milestones — tracked weaknesses with owners and remediation dates. |
| ATO / cATO / DATO | Authorize / conditional (ongoing) / denial of authorization to operate. |
| Authorizing Official (AO) | The senior official who accepts residual risk and signs the authorization. |
| ConMon | Continuous monitoring — ongoing control-effectiveness and risk tracking post-ATO. |
## Tools & Systems
- **NIST SP 800-37 Rev 2** — the RMF process (7 steps).
- **FIPS 199 / FIPS 200 / SP 800-60** — categorization and minimum requirements.
- **NIST SP 800-53 Rev 5 / 800-53B** — control catalog and baselines.
- **NIST SP 800-53A Rev 5** — assessment procedures (examine/interview/test).
- **OSCAL** — machine-readable SSP/SAR/POA&M (NIST's authorization-document format).
- **eMASS** (DoD) / **FedRAMP** templates — package management and submission.
- **GRC platforms** — Xacta, ServiceNow, RegScale, etc., to manage the package and ConMon.
- **NIST CSF 2.0** — cross-walks to communicate RMF posture in framework terms.
## Common Scenarios
- **New system pre-launch.** Run Categorize → Authorize before go-live; ATO is the gate to production.
- **Cloud service (FedRAMP).** Inherit the platform's controls, document the CRM split, and authorize the customer-responsible delta.
- **Re-authorization.** Triggered by term expiry or significant change; refresh SSP/SAR/POA&M and re-decide.
- **cATO / ongoing authorization.** Replace periodic re-ATO with continuous evidence and an approved ConMon model.
- **POA&M review.** Triage open weaknesses by risk, assign owners and dates, and report closure trend to the AO.
## Output Format
Produce an **Authorization Package summary** using `assets/template.md`, containing:
1. **System & boundary** — description, components, data flows, inherited services.
2. **Categorization** — FIPS 199 C/I/A and overall impact, with information-type rationale.
3. **Control baseline & tailoring** — baseline selected, tailoring decisions, common vs system-specific.
4. **Implementation status** — per-family implementation summary (from the SSP).
5. **Assessment results (SAR)** — findings by severity; what's satisfied vs other-than-satisfied.
6. **POA&M** — open weaknesses, risk, owner, milestone dates.
7. **Authorization decision** — ATO/cATO/DATO, term, conditions, residual-risk statement, AO.
8. **ConMon plan** — what's monitored, how often, reporting cadence, reassessment triggers.
Use `scripts/process.py` to select the right SP 800-53B baseline from a FIPS 199 categorization, summarize control-implementation status, and generate a POA&M table from a findings JSON.
@@ -0,0 +1,67 @@
# Authorization Package Summary (NIST RMF / SP 800-37 Rev 2) — Worked Example
> Filled example for a Moderate-impact federal web application seeking an initial ATO.
> Replace bracketed content for your own system.
## 1. System & Authorization Boundary
- **System name:** Citizen Services Portal (CSP)
- **System owner / ISSO / AO:** [SO name] / [ISSO name] / [AO name]
- **Description:** Public-facing web portal for benefit applications; React frontend, containerized API, managed Postgres, all in an authorized cloud (FedRAMP Moderate) tenant.
- **Boundary:** The application containers, API gateway, database, and CI/CD pipeline within the project's cloud account. **Inherited:** physical, environmental, and hypervisor controls from the FedRAMP-authorized platform (documented in the CRM).
- **Leveraged authorization:** Platform IaaS at FedRAMP Moderate.
## 2. FIPS 199 Categorization
*(generated by `scripts/process.py` from the information-type table; overall = high-water mark)*
| Objective | High-water mark |
|---|---|
| Confidentiality | Moderate |
| Integrity | Moderate |
| Availability | Moderate |
| **Overall system impact** | **Moderate** |
**Information types:** PII (C:Mod / I:Mod / A:Low), Eligibility records (C:Mod / I:Mod / A:Mod), Public content (C:Low / I:Mod / A:Mod).
**Selected SP 800-53B baseline:** Moderate. Privacy overlay applied (PII present).
## 3. Control Baseline & Tailoring
- **Baseline:** SP 800-53B Moderate + privacy controls (PT family).
- **Tailoring decisions:** PE family largely **inherited** from the platform (common controls). Organization-defined parameters set for AC-7 (lockout threshold = 5), AU-11 (log retention = 1 year), IA-5 (password/authenticator policy).
- **Allocation:** Common (inherited) — PE, parts of SC/CP; System-specific — AC, AU, SI, application-layer SC; Hybrid — IR, CM (platform + app split per CRM).
## 4. Control Implementation Status (from the SSP)
| Family | Implemented | Total | % |
|---|---|---|---|
| AC | 22 | 25 | 88% |
| AU | 14 | 16 | 88% |
| SC | 28 | 30 | 93% |
| SI | 12 | 14 | 86% |
| **Total** | **76** | **85** | **89%** |
*(Each implemented control carries an implementation statement in the SSP — not a bare "yes." Open items map to the POA&M below.)*
## 5. Assessment Results (SAR)
Independent assessment per SP 800-53A Rev 5 (examine / interview / test). Result: **3 controls "Other Than Satisfied"**, all with remediation plans. No Critical findings. Detailed evidence in the full SAR.
## 6. Plan of Action & Milestones (POA&M)
*(generated by `scripts/process.py`, sorted by severity)*
| ID | Control | Weakness | Severity | Status | Remediation | Owner | Milestone |
|---|---|---|---|---|---|---|---|
| F-001 | AC-7 | No account lockout on the portal login | High | Other Than Satisfied | Configure lockout after 5 failed attempts | App team | 2026-07-15 |
| F-002 | AU-6 | Audit logs not reviewed on a defined cadence | Moderate | Other Than Satisfied | Stand up weekly SIEM review + alerting | SOC | 2026-08-01 |
| F-003 | SI-2 | Two medium CVEs unpatched in a dependency | Moderate | Other Than Satisfied | Patch in next sprint; add Dependabot gate | App team | 2026-07-30 |
_Open High/Critical findings: 1 (F-001) — track to closure before/within ATO conditions._
## 7. Authorization Decision
- **Decision:** **ATO with conditions** (effectively a cATO posture).
- **Term:** 3 years, contingent on continuous monitoring and POA&M adherence.
- **Conditions:** Close F-001 (High) within 30 days of authorization; F-002 and F-003 per their milestones.
- **Residual-risk statement:** Residual risk is **Moderate and acceptable** given the compensating monitoring and the committed remediation timeline.
- **Authorizing Official:** [AO name], [date].
## 8. Continuous Monitoring (ConMon) Plan
- **Monitored continuously:** vulnerability scans (weekly), configuration drift (CM), POA&M status (monthly to the AO), control effectiveness sampling (quarterly).
- **Reporting cadence:** Monthly ConMon report; immediate notification of any High/Critical finding or significant change.
- **Reassessment triggers:** new external interface, change of categorization, major architecture change, or a significant incident.
- **Maturity goal:** Move from periodic re-ATO toward ongoing authorization as ConMon evidence stabilizes.
@@ -0,0 +1,71 @@
# NIST RMF / ATO — Standards & Reference
## Primary standard
### NIST SP 800-37 Revision 2 — Risk Management Framework for Information Systems and Organizations
- **Publisher**: NIST
- **Published**: December 2018
- **Scope**: A 7-step lifecycle for managing security and privacy risk and authorizing systems to operate.
- **URL**: https://csrc.nist.gov/pubs/sp/800/37/r2/final
## The seven RMF steps
| # | Step | Core question | Key inputs |
|---|---|---|---|
| 1 | Prepare | Are roles, strategy, and boundary set? | SP 800-39 risk strategy, common controls |
| 2 | Categorize | How bad is a loss of C/I/A? | FIPS 199, SP 800-60 |
| 3 | Select | Which controls apply? | FIPS 200, SP 800-53B baselines, SP 800-53 Rev 5 |
| 4 | Implement | How is each control built? | SSP implementation statements |
| 5 | Assess | Do the controls work? | SP 800-53A Rev 5; produces the SAR |
| 6 | Authorize | Is residual risk acceptable? | Package (SSP+SAR+POA&M); AO decision |
| 7 | Monitor | Is it still effective? | ConMon plan, scans, change management |
## Companion standards
| Document | Role |
|---|---|
| FIPS 199 | Security categorization — Low/Moderate/High per confidentiality, integrity, availability. |
| FIPS 200 | Minimum security requirements for federal information and systems. |
| NIST SP 800-60 Vol 1 & 2 | Maps information types to impact levels (input to FIPS 199). |
| NIST SP 800-53 Rev 5 | Control catalog — 20 control families. |
| NIST SP 800-53B | Control baselines (Low / Moderate / High) and the privacy baseline. |
| NIST SP 800-53A Rev 5 | Assessment procedures (examine / interview / test). |
| NIST SP 800-39 | Organization-wide risk management context (three tiers). |
| NIST SP 800-137 | Information Security Continuous Monitoring (ISCM) — the Monitor step. |
| OSCAL | Open Security Controls Assessment Language — machine-readable SSP/SAP/SAR/POA&M. |
## FIPS 199 categorization
For each information type, rate the impact of a loss of:
- **Confidentiality** — unauthorized disclosure
- **Integrity** — unauthorized modification/destruction
- **Availability** — disruption of access/use
Each at **Low / Moderate / High**. The **overall system impact level = the high-water mark** (highest single value) across all information types and all three objectives. That overall level selects the SP 800-53B baseline.
## SP 800-53 Rev 5 control families (20)
AC (Access Control), AT (Awareness & Training), AU (Audit & Accountability), CA (Assessment, Authorization & Monitoring), CM (Configuration Management), CP (Contingency Planning), IA (Identification & Authentication), IR (Incident Response), MA (Maintenance), MP (Media Protection), PE (Physical & Environmental Protection), PL (Planning), PM (Program Management), PS (Personnel Security), PT (PII Processing & Transparency), RA (Risk Assessment), SA (System & Services Acquisition), SC (System & Communications Protection), SI (System & Information Integrity), SR (Supply Chain Risk Management).
## Control allocation
- **Common (inherited)** — provided by another provider/platform; the system inherits the implementation and the evidence.
- **System-specific** — implemented and owned by this system.
- **Hybrid** — partly inherited, partly system-specific (responsibility split documented, e.g., in a FedRAMP CRM).
## Core authorization artifacts
| Artifact | Produced in step | Contents |
|---|---|---|
| SSP — System Security Plan | Select/Implement | System description, boundary, categorization, control implementation statements. |
| SAR — Security Assessment Report | Assess | Assessor findings: satisfied / other-than-satisfied, with evidence. |
| POA&M — Plan of Action & Milestones | Assess → Authorize | Open weaknesses, risk, remediation owner, milestone dates. |
| Authorization Decision Document | Authorize | ATO/cATO/DATO, term, conditions, residual-risk acceptance, AO signature. |
| ConMon Plan | Monitor | What's monitored, frequency, reporting cadence, reassessment triggers. |
## Authorization outcomes
- **ATO** — Authorization to Operate (often time-bound, e.g., up to 3 years, with ConMon).
- **cATO** — Conditional / ongoing authorization under an approved continuous model (increasingly preferred in DoD).
- **DATO** — Denial of Authorization to Operate.
## NIST CSF 2.0 alignment
| CSF 2.0 ID | Relevance |
|---|---|
| GV.OC-03 | Legal/regulatory requirements (FISMA) understood and managed. |
| GV.RM-01 | Risk-management objectives established and agreed. |
| ID.AM-08 | Systems managed across the lifecycle (authorization boundary). |
| ID.RA-05 | Risk used to inform prioritization and the authorization decision. |
| PR.IR-01 | Protective technology / controls implemented per the baseline. |
@@ -0,0 +1,199 @@
#!/usr/bin/env python3
"""
NIST RMF helper: FIPS 199 categorization -> SP 800-53B baseline selection,
control-implementation status summary, and POA&M generation from findings.
Input JSON shape:
{
"system": {"name": "Customer Portal", "ao": "Jane Roe"},
"information_types": [
{"name": "PII", "confidentiality": "Moderate", "integrity": "Moderate", "availability": "Low"},
{"name": "Authentication data", "confidentiality": "High", "integrity": "High", "availability": "Moderate"}
],
"implementation": { # OPTIONAL: per-family implemented/total counts
"AC": {"implemented": 20, "total": 25},
"AU": {"implemented": 10, "total": 16}
},
"findings": [ # OPTIONAL: assessor findings -> POA&M
{
"id": "F-001", "control": "AC-7", "weakness": "No account lockout on portal",
"severity": "High", "status": "Other Than Satisfied",
"remediation": "Configure lockout after 5 failed attempts",
"owner": "App team", "milestone": "2026-07-15"
}
]
}
Categorization rule (FIPS 199): overall impact = high-water mark across all
information types and all three objectives (C, I, A).
Usage:
python process.py --input system.json [--output package.md]
python process.py --input system.json --fail-open-high # exit 1 if any High finding open
"""
import argparse
import json
import sys
IMPACT = ["Low", "Moderate", "High"]
IMPACT_RANK = {v: i for i, v in enumerate(IMPACT)}
SEVERITY_RANK = {"Low": 0, "Moderate": 1, "Medium": 1, "High": 2, "Critical": 3}
# Indicative SP 800-53B baseline control counts by impact level.
# (Approximate; the authoritative counts live in SP 800-53B. Used here to
# communicate relative baseline size, not as a substitute for the catalog.)
BASELINE_SIZE = {"Low": "~150 controls", "Moderate": "~260 controls", "High": "~340 controls"}
def categorize(info_types):
"""Return (overall, per_objective_high) using the FIPS 199 high-water mark."""
highs = {"confidentiality": "Low", "integrity": "Low", "availability": "Low"}
for it in info_types:
for obj in highs:
val = it.get(obj, "Low")
if val not in IMPACT_RANK:
raise ValueError(f"information type '{it.get('name','?')}' has invalid {obj} '{val}'")
if IMPACT_RANK[val] > IMPACT_RANK[highs[obj]]:
highs[obj] = val
overall = max(highs.values(), key=lambda v: IMPACT_RANK[v])
return overall, highs
def render(data):
sysmeta = data.get("system", {})
info_types = data.get("information_types", [])
if not info_types:
raise ValueError("information_types is required to categorize the system")
overall, highs = categorize(info_types)
lines = []
lines.append(f"# Authorization Package Summary - {sysmeta.get('name','System')}")
lines.append("")
if sysmeta.get("ao"):
lines.append(f"- **Authorizing Official:** {sysmeta['ao']}")
lines.append("")
# categorization
lines.append("## FIPS 199 Categorization")
lines.append("")
lines.append("| Objective | High-water mark |")
lines.append("|---|---|")
lines.append(f"| Confidentiality | {highs['confidentiality']} |")
lines.append(f"| Integrity | {highs['integrity']} |")
lines.append(f"| Availability | {highs['availability']} |")
lines.append(f"| **Overall system impact** | **{overall}** |")
lines.append("")
lines.append(f"**Selected SP 800-53B baseline:** {overall} ({BASELINE_SIZE[overall]}). "
"Tailor from this baseline; document scoping, compensating controls, and "
"organization-defined parameter values in the SSP.")
lines.append("")
lines.append("### Information types")
lines.append("")
lines.append("| Information type | C | I | A |")
lines.append("|---|---|---|---|")
for it in info_types:
lines.append(f"| {it.get('name','-')} | {it.get('confidentiality','-')} "
f"| {it.get('integrity','-')} | {it.get('availability','-')} |")
lines.append("")
# implementation status
impl = data.get("implementation")
if impl:
lines.append("## Control Implementation Status (by family)")
lines.append("")
lines.append("| Family | Implemented | Total | % |")
lines.append("|---|---|---|---|")
tot_i = tot_t = 0
for fam, c in sorted(impl.items()):
i, t = c.get("implemented", 0), c.get("total", 0)
tot_i += i
tot_t += t
pct = f"{(100*i/t):.0f}%" if t else "-"
lines.append(f"| {fam} | {i} | {t} | {pct} |")
overall_pct = f"{(100*tot_i/tot_t):.0f}%" if tot_t else "-"
lines.append(f"| **Total** | **{tot_i}** | **{tot_t}** | **{overall_pct}** |")
lines.append("")
# POA&M
findings = data.get("findings", [])
open_high = []
if findings:
findings_sorted = sorted(
findings,
key=lambda f: SEVERITY_RANK.get(f.get("severity", "Low"), 0),
reverse=True,
)
lines.append("## Plan of Action & Milestones (POA&M)")
lines.append("")
lines.append("| ID | Control | Weakness | Severity | Status | Remediation | Owner | Milestone |")
lines.append("|---|---|---|---|---|---|---|---|")
for f in findings_sorted:
sev = f.get("severity", "-")
status = f.get("status", "-")
is_open = status.strip().lower() != "satisfied"
is_high = SEVERITY_RANK.get(sev, 0) >= SEVERITY_RANK["High"]
if is_open and is_high:
open_high.append(f)
lines.append("| {id} | {ctl} | {wk} | {sev} | {st} | {rem} | {own} | {ms} |".format(
id=f.get("id", "-"), ctl=f.get("control", "-"), wk=f.get("weakness", "-"),
sev=sev, st=status, rem=f.get("remediation", "-"),
own=f.get("owner", "-"), ms=f.get("milestone", "-"),
))
lines.append("")
lines.append(f"_Open High/Critical findings: {len(open_high)}_")
lines.append("")
# decision scaffold
lines.append("## Authorization Decision (to be completed by the AO)")
lines.append("")
lines.append("- **Decision:** [ ATO | cATO | DATO ]")
lines.append("- **Term / conditions:** ____")
lines.append("- **Residual-risk statement:** ____")
lines.append(f"- **Authorizing Official:** {sysmeta.get('ao','____')}")
return "\n".join(lines), overall, open_high
def main():
ap = argparse.ArgumentParser(description="NIST RMF baseline selector + POA&M generator")
ap.add_argument("--input", "-i", required=True, help="Path to system JSON")
ap.add_argument("--output", "-o", help="Write Markdown package summary to this path")
ap.add_argument("--fail-open-high", action="store_true",
help="Exit non-zero if any High/Critical finding remains open")
args = ap.parse_args()
try:
with open(args.input) as f:
data = json.load(f)
except (OSError, json.JSONDecodeError) as e:
print(f"ERROR: could not read input JSON: {e}", file=sys.stderr)
return 2
try:
md, overall, open_high = render(data)
except ValueError as e:
print(f"ERROR: {e}", file=sys.stderr)
return 2
if args.output:
with open(args.output, "w") as f:
f.write(md + "\n")
print(f"Package summary written to {args.output}", file=sys.stderr)
else:
print(md)
print(f"Overall categorization: {overall}. Open High/Critical findings: {len(open_high)}.",
file=sys.stderr)
if args.fail_open_high and open_high:
ids = ", ".join(f.get("id", "?") for f in open_high)
print(f"FAIL: {len(open_high)} open High/Critical finding(s): {ids}", file=sys.stderr)
return 1
return 0
if __name__ == "__main__":
sys.exit(main())
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to the Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by the Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding any notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. Please do not remove or change
the license header comment from a contributed file except when
necessary.
Copyright 2026 mukul975
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
@@ -0,0 +1,142 @@
---
name: implementing-hipaa-security-rule-safeguards
description: >-
Implement the HIPAA Security Rule (45 CFR Part 164 Subpart C) to protect electronic
protected health information (ePHI): conduct the required risk analysis, deploy the
administrative, physical, and technical safeguards, handle required vs addressable
implementation specifications, execute Business Associate Agreements, and stand up
breach-notification readiness. Use when an organization is a HIPAA covered entity or
business associate, when protecting ePHI, when preparing for an OCR audit or responding
to a breach, when performing a HIPAA Security Risk Analysis, when drafting or reviewing a
BAA, or when mapping security controls to the §164.308/310/312/314/316 safeguards. Notes
the 2025 NPRM proposed changes (not yet final). Keywords: HIPAA, HIPAA Security Rule,
ePHI, PHI, 45 CFR 164, risk analysis, administrative safeguards, physical safeguards,
technical safeguards, addressable, required, Business Associate Agreement, BAA, OCR,
breach notification, HITECH, covered entity, business associate.
domain: cybersecurity
subdomain: compliance-governance
tags:
- hipaa
- hipaa-security-rule
- ephi
- phi
- 45-cfr-164
- risk-analysis
- baa
- breach-notification
- ocr
- compliance
- governance
version: "1.0"
author: andrewibrah
license: Apache-2.0
nist_csf:
- GV.OC-03
- GV.RM-01
- ID.RA-01
- ID.RA-05
- PR.DS-01
- PR.AA-01
- DE.CM-01
mitre_attack:
- T1078
- T1566
- T1486
- T1530
- T1048
---
# Implementing HIPAA Security Rule Safeguards
## When to Use
- When an organization is a **covered entity** (health plan, clearinghouse, or provider transmitting electronic transactions) or a **business associate** handling **ePHI** on their behalf.
- When standing up or maturing controls to protect **electronic protected health information**.
- When performing the mandatory **HIPAA Security Risk Analysis** (§164.308(a)(1)(ii)(A)) — the single most-cited gap in OCR enforcement.
- When preparing for an **OCR audit/investigation** or responding to a suspected **breach**.
- When drafting, reviewing, or remediating a **Business Associate Agreement (BAA)**.
- When mapping existing security controls to the HIPAA safeguard standards and implementation specifications.
> Scope note: this skill covers the **Security Rule** (ePHI). The **Privacy Rule** (uses/disclosures of all PHI) and the **Breach Notification Rule** are related but distinct; this skill touches breach readiness and BAAs where they intersect security.
## Prerequisites
- A clear determination of the organization's **role** (covered entity vs business associate) and where ePHI lives, flows, and is stored (an ePHI data map).
- An **asset inventory** of systems that create, receive, maintain, or transmit ePHI.
- Knowledge of the current rule's structure (45 CFR §§164.302318) and the **required vs addressable** distinction.
- Awareness that a **2025 NPRM** proposes significant changes (see Workflow step 7 and `references/standards.md`) — track but do not assume them as in force.
## Workflow
### 1. Conduct the Security Risk Analysis (§164.308(a)(1)(ii)(A))
This is **required** and foundational. Inventory ePHI and systems, identify threats and vulnerabilities, assess current controls, determine likelihood and impact, and assign risk levels. (Pair with the NIST 800-30 methodology and HHS's SRA Tool.) Output is a documented, dated risk analysis — the artifact OCR asks for first.
### 2. Implement Administrative Safeguards (§164.308)
The largest section. Includes the **Security Management Process** (risk analysis, risk management, sanction policy, information-system activity review), assigned **security responsibility** (a named Security Official), **workforce security**, **information access management**, **security awareness and training**, **security incident procedures**, **contingency planning** (data backup, disaster recovery, emergency-mode operation), **evaluation**, and **BAAs** with business associates.
### 3. Implement Physical Safeguards (§164.310)
**Facility access controls**, **workstation use** and **workstation security**, and **device and media controls** (disposal, media re-use, accountability, data backup and storage).
### 4. Implement Technical Safeguards (§164.312)
**Access control** (unique user ID, emergency access, automatic logoff, encryption/decryption), **audit controls**, **integrity** (mechanisms to authenticate ePHI), **person/entity authentication**, and **transmission security** (integrity controls + encryption).
### 5. Resolve "Required" vs "Addressable" specifications
Under the current rule, each implementation specification is **Required** (must implement) or **Addressable** (assess whether reasonable and appropriate; if so implement, if not document why and implement an equivalent alternative). **Addressable does not mean optional** — it means make and document a risk-based decision.
### 6. Execute Business Associate Agreements (§164.314 / §164.308(b))
Every business associate that touches ePHI needs a BAA binding it to safeguard ePHI, report incidents, and flow requirements to subcontractors. Maintain the BAA inventory.
### 7. Track the 2025 NPRM proposed changes (NOT yet final)
HHS OCR published an NPRM (Jan 6, 2025) proposing to **remove the required/addressable distinction** (make nearly all specifications required), and to mandate **MFA**, **encryption of ePHI at rest and in transit**, **asset inventory and network maps**, **vulnerability scans every 6 months**, **annual penetration testing**, **72-hour restoration of certain systems/data**, and **annual risk-analysis updates**. **These are proposals** — the current rule remains in force until a final rule is published and effective. Plan toward them, but comply with what is current.
### 8. Stand up breach-notification readiness (45 CFR §§164.400414)
Define how you detect, assess (the four-factor risk assessment), and report breaches of unsecured PHI: to **individuals** and **HHS** (and **media** for breaches affecting 500+ in a state/jurisdiction), within the required timelines. Encryption to NIST standards renders PHI "secured" and is a safe harbor from breach notification.
### 9. Document everything (§164.316)
Maintain policies, procedures, and records of actions/decisions in writing, **retain for six years**, review periodically, and update in response to environmental or operational change.
## Key Concepts
| Concept | Definition |
|---|---|
| ePHI | Electronic protected health information — the Security Rule's scope. |
| Covered entity | Health plan, clearinghouse, or provider doing electronic transactions. |
| Business associate | A vendor that handles ePHI for a covered entity; bound by a BAA. |
| Risk analysis | Required, documented assessment of risks to ePHI (§164.308(a)(1)(ii)(A)). |
| Required vs addressable | Must-implement vs risk-based-decision implementation specifications. |
| Administrative / Physical / Technical safeguards | §164.308 / §164.310 / §164.312. |
| BAA | Business Associate Agreement — contractually binds vendors to safeguard ePHI. |
| Breach (unsecured PHI) | Triggers notification under §§164.400414; encryption is a safe harbor. |
| OCR | HHS Office for Civil Rights — enforces HIPAA. |
| Six-year retention | Documentation retention requirement (§164.316). |
## Tools & Systems
- **45 CFR Part 164 Subpart C** — the Security Rule text (and Subpart D, Breach Notification).
- **HHS Security Risk Assessment (SRA) Tool** — free guided risk analysis.
- **NIST SP 800-66 Rev 2** — implementing the HIPAA Security Rule (NIST guidance, maps to 800-53).
- **NIST SP 800-30** — risk-assessment methodology to ground the SRA.
- **GRC / compliance platforms** — to manage policies, the BAA inventory, and evidence.
- **Encryption / MFA / SIEM / audit-logging tooling** — to satisfy technical safeguards and the proposed mandates.
## Common Scenarios
- **OCR investigation after a breach.** First request is almost always the current, dated **risk analysis** and the **risk-management plan** — have them ready.
- **New SaaS handling ePHI.** Sign a **BAA** before any ePHI flows; confirm the vendor's safeguards.
- **Addressable spec you won't implement as written.** Document the risk-based rationale and the **equivalent alternative** you implemented instead.
- **Preparing for the proposed rule.** Pre-position MFA, at-rest/in-transit encryption, asset inventory, scanning, and pen-testing so a final rule is a small step, not a scramble.
- **Lost/stolen device.** If ePHI was encrypted to NIST standards, the safe harbor applies; if not, run the four-factor breach assessment and notify as required.
## Output Format
Produce a **HIPAA Security Rule Gap Assessment** using `assets/template.md`, containing:
1. **Role & ePHI scope** — covered entity vs BA; ePHI data map and systems.
2. **Risk analysis summary** — top risks to ePHI with likelihood/impact (feeds risk management).
3. **Safeguard status** — Administrative / Physical / Technical, each specification marked **Implemented / Partial / Gap** with required-vs-addressable noted.
4. **BAA inventory** — business associates and BAA status.
5. **Breach-notification readiness** — detection, four-factor assessment, notification workflow.
6. **2025 NPRM gap view** — readiness against the proposed mandates (clearly labeled proposed).
7. **Remediation plan** — prioritized, with owners and dates; required specs and risk-analysis gaps first.
Use `scripts/process.py` to score a safeguard-status JSON across the §164.308/310/312 standards, weight required gaps above addressable ones, and emit the gap table plus a remediation-priority list.
@@ -0,0 +1,65 @@
# HIPAA Security Rule Gap Assessment — Worked Example
> Filled example for a small outpatient clinic (covered entity).
> Replace bracketed content for your own organization.
## 1. Role & ePHI Scope
- **Role:** Covered Entity (outpatient provider doing electronic transactions).
- **ePHI locations:** EHR SaaS, the clinic's clearing workstation, encrypted backups, and a billing vendor (business associate).
- **ePHI data map:** Patient intake → EHR (SaaS, BAA in place) → claims to billing BA → encrypted backup. Reference diagram `ephi-flow-v2`.
## 2. Risk Analysis Summary (feeds Risk Management)
| Top risk to ePHI | Likelihood | Impact | Note |
|---|---|---|---|
| Phishing → EHR credential theft | High | High | No MFA on remote EHR access |
| Lost/stolen laptop with cached ePHI | Moderate | High | Disk encryption not enforced fleet-wide |
| Billing BA mishandles ePHI | Low | High | BAA present; vendor safeguards unverified |
> The risk analysis is **dated and documented** — this is the first artifact OCR requests.
## 3. Safeguard Status
*(scored by `scripts/process.py`; weighted readiness ≈ 62% in this example)*
| Specification | Section | Requirement | Status | Alt. documented |
|---|---|---|---|---|
| 164.308(a)(1)(ii)(A) Risk Analysis | Administrative | required | **gap** | — |
| 164.308(a)(1)(ii)(B) Risk Management | Administrative | required | partial | — |
| 164.308(a)(2) Assigned Security Responsibility | Administrative | required | implemented | — |
| 164.310(d)(2)(i) Disposal | Physical | required | implemented | — |
| 164.312(a)(1) Unique User ID | Technical | required | implemented | — |
| 164.312(a)(2)(iv) Encryption/Decryption | Technical | addressable | partial | no |
| 164.312(a)(2)(iii) Automatic Logoff | Technical | addressable | gap | **yes** (equivalent timeout via MDM documented) |
**OCR-priority flag:** Risk Analysis is a gap → remediate first.
## 4. BAA Inventory
| Business associate | Service | BAA status |
|---|---|---|
| EHR SaaS vendor | Records system | Signed, current |
| Billing vendor | Claims processing | Signed; request SOC 2 / safeguards attestation |
| Backup provider | Encrypted offsite backup | Signed, current |
## 5. Breach-Notification Readiness (§§164.400414)
- **Detection:** EHR + endpoint alerts route to the Security Official.
- **Assessment:** Documented **four-factor** procedure to decide whether a breach of unsecured PHI occurred.
- **Notification workflow:** Individuals within 60 days; HHS (annual log for <500, prompt for 500+); media for 500+ in-jurisdiction.
- **Safe harbor:** Enforce NIST-standard encryption so lost/stolen encrypted devices are "secured" and exempt from notification.
## 6. 2025 NPRM Gap View (PROPOSED — not yet final)
| Proposed mandate | Current state | Pre-position action |
|---|---|---|
| Mandatory MFA | Not enforced | Roll out MFA on all ePHI access |
| Encryption at rest & in transit | Partial | Enforce full-disk + TLS everywhere |
| Asset inventory + network map | Informal | Formalize and keep current |
| Vuln scans every 6 mo / annual pentest | Ad hoc | Schedule recurring scans + annual test |
| 72-hour restoration | Untested | Add RTO target + restore drills |
| Annual risk-analysis update | Irregular | Calendar annual refresh |
> These are **proposals**; comply with the current rule today and treat this column as a readiness runway.
## 7. Remediation Plan (prioritized)
1. **Risk Analysis (164.308(a)(1)(ii)(A)) — required gap, OCR-priority.** Complete and date a full SRA (use HHS SRA Tool + NIST 800-30). **Owner:** Security Official. **Due:** 30 days.
2. **Risk Management (164.308(a)(1)(ii)(B)) — required, partial.** Build the remediation plan that flows from the SRA. **Due:** 45 days.
3. **Encryption (164.312(a)(2)(iv)) — addressable, partial.** Enforce full-disk + in-transit encryption (also clears NPRM + breach safe harbor). **Due:** 60 days.
4. Verify the billing BA's safeguards (request SOC 2). **Due:** 60 days.
5. Re-run the scorer after each fix; target ≥ 95% weighted readiness with zero required gaps.
@@ -0,0 +1,88 @@
# HIPAA Security Rule — Standards & Reference
## Primary regulation
### HIPAA Security Rule — 45 CFR Part 164, Subpart C
- **Regulator**: U.S. Department of Health and Human Services, **Office for Civil Rights (OCR)**
- **Scope**: Security of **electronic** protected health information (ePHI) held or transmitted by covered entities and business associates.
- **Statutory basis**: HIPAA (1996) as amended by **HITECH** (2009).
- **eCFR**: https://www.ecfr.gov/current/title-45/subtitle-A/subchapter-C/part-164/subpart-C
## Rule structure (key sections)
| Section | Title |
|---|---|
| §164.302 | Applicability |
| §164.304 | Definitions |
| §164.306 | Security standards: general rules (flexibility, scalability) |
| §164.308 | **Administrative safeguards** |
| §164.310 | **Physical safeguards** |
| §164.312 | **Technical safeguards** |
| §164.314 | Organizational requirements (BAAs, group health plans) |
| §164.316 | Policies, procedures, and documentation (6-year retention) |
Breach Notification Rule: **45 CFR §§164.400414** (Subpart D).
## Administrative safeguards (§164.308) — standards
- Security Management Process — **Risk Analysis (R)**, **Risk Management (R)**, Sanction Policy (R), Information System Activity Review (R)
- Assigned Security Responsibility (named Security Official)
- Workforce Security (authorization/supervision, clearance, termination — Addressable)
- Information Access Management (isolating clearinghouse functions (R); access authorization/establishment/modification — Addressable)
- Security Awareness and Training (reminders, malware protection, log-in monitoring, password management — Addressable)
- Security Incident Procedures — Response and Reporting (R)
- Contingency Plan — **Data Backup Plan (R)**, **Disaster Recovery Plan (R)**, **Emergency Mode Operation Plan (R)**, Testing/Revision (A), Applications/Data Criticality Analysis (A)
- Evaluation (periodic)
- Business Associate Contracts (§164.308(b))
## Physical safeguards (§164.310) — standards
- Facility Access Controls (contingency operations, facility security plan, access control/validation, maintenance records — all Addressable)
- Workstation Use (R)
- Workstation Security (R)
- Device and Media Controls — **Disposal (R)**, **Media Re-use (R)**, Accountability (A), Data Backup and Storage (A)
## Technical safeguards (§164.312) — standards
- Access Control — **Unique User Identification (R)**, **Emergency Access Procedure (R)**, Automatic Logoff (A), Encryption and Decryption (A)
- Audit Controls (R)
- Integrity — Mechanism to Authenticate ePHI (A)
- Person or Entity Authentication (R)
- Transmission Security — Integrity Controls (A), Encryption (A)
> (R) = Required, (A) = Addressable, under the **current** rule.
## Required vs Addressable
- **Required**: must be implemented as specified.
- **Addressable**: assess whether the specification is reasonable and appropriate; if yes, implement; if no, **document why** and implement an **equivalent alternative measure** if reasonable. Addressable is **not** optional.
## Breach Notification (45 CFR §§164.400414)
- Applies to breaches of **unsecured PHI**.
- **Four-factor risk assessment** to determine whether a breach occurred (nature/extent of PHI, who used/received it, whether it was actually acquired/viewed, mitigation).
- Notify **individuals without unreasonable delay and within 60 days**; notify **HHS** (annually for <500; without unreasonable delay and within 60 days for 500+); notify **media** for breaches affecting **500+** residents of a state/jurisdiction.
- **Safe harbor**: PHI encrypted to HHS/NIST-specified standards is "secured" and not subject to breach notification.
## 2025 NPRM — PROPOSED changes (NOT yet final)
- **Citation**: 90 FR 800, RIN 0945-AA22, published **January 6, 2025**; comment period closed March 7, 2025.
- **Status**: **Proposed only.** The current Security Rule remains in force until a final rule is published and becomes effective. Track at https://www.federalregister.gov.
- **Notable proposals**:
- Remove the **required/addressable** distinction — make (nearly) all implementation specifications **required**.
- Mandatory **multi-factor authentication**.
- Mandatory **encryption of ePHI at rest and in transit**.
- **Asset inventory** and **network maps**, updated regularly.
- **Vulnerability scans at least every 6 months** and **penetration testing at least annually**.
- **72-hour restoration** of certain systems/data after an incident.
- **Annual** risk-analysis updates and written documentation of compliance reviews.
- **Typical effective/compliance timing if finalized**: effective ~60 days after publication; compliance ~180 days after effective (subject to the final rule).
## Supporting NIST guidance
| Document | Role |
|---|---|
| NIST SP 800-66 Rev 2 (2024) | Implementing the HIPAA Security Rule; maps safeguards to SP 800-53 controls. |
| NIST SP 800-30 Rev 1 | Risk-assessment methodology underpinning the required risk analysis. |
| HHS SRA Tool | Free guided Security Risk Assessment for smaller organizations. |
## NIST CSF 2.0 alignment
| CSF 2.0 ID | Relevance |
|---|---|
| GV.OC-03 | Legal/regulatory (HIPAA) requirements understood. |
| GV.RM-01 | Risk-management objectives established. |
| ID.RA-01 / ID.RA-05 | Vulnerabilities identified; risk informs prioritization (the risk analysis). |
| PR.DS-01 | Data-at-rest protection (encryption of ePHI). |
| PR.AA-01 | Identity/authentication (unique IDs, MFA). |
| DE.CM-01 | Monitoring (audit controls, activity review). |
@@ -0,0 +1,223 @@
#!/usr/bin/env python3
"""
HIPAA Security Rule safeguard gap-assessment scorer.
Scores a safeguard-status inventory across the Administrative (164.308),
Physical (164.310), and Technical (164.312) safeguards. Required gaps are
weighted above addressable gaps, and any gap in the Risk Analysis or Risk
Management specifications is escalated (these are the most-cited OCR findings).
Emits a gap table, a weighted readiness score, and a prioritized remediation list.
Input JSON shape:
{
"org": {"name": "Northstar Clinic", "role": "Covered Entity"},
"safeguards": [
{
"id": "164.308(a)(1)(ii)(A)", "section": "308",
"name": "Risk Analysis", "requirement": "required",
"status": "gap"
},
{
"id": "164.312(a)(2)(iv)", "section": "312",
"name": "Encryption and Decryption", "requirement": "addressable",
"status": "partial",
"alternative_documented": false
}
]
}
requirement: required | addressable
status: implemented | partial | gap
Usage:
python process.py --input safeguards.json [--output gap.md]
python process.py --input safeguards.json --fail-on-required-gap
"""
import argparse
import json
import sys
SECTION_NAMES = {
"308": "Administrative (§164.308)",
"310": "Physical (§164.310)",
"312": "Technical (§164.312)",
}
VALID_REQ = {"required", "addressable"}
VALID_STATUS = {"implemented", "partial", "gap"}
# status -> credit fraction toward "implemented"
CREDIT = {"implemented": 1.0, "partial": 0.5, "gap": 0.0}
# weighting: required safeguards count more toward the score
WEIGHT = {"required": 2, "addressable": 1}
# Specifications whose absence OCR cites most often -> escalate
HIGH_PRIORITY_KEYS = ("risk analysis", "risk management")
def score(data):
sgs = data.get("safeguards", [])
if not sgs:
raise ValueError("safeguards list is required")
total_weight = 0.0
earned_weight = 0.0
required_gaps = []
addressable_gaps = []
escalated = []
by_section = {}
rows = []
for s in sgs:
sid = s.get("id", "?")
req = s.get("requirement")
status = s.get("status")
if req not in VALID_REQ:
raise ValueError(f"{sid}: requirement '{req}' invalid (required|addressable)")
if status not in VALID_STATUS:
raise ValueError(f"{sid}: status '{status}' invalid (implemented|partial|gap)")
section = str(s.get("section", "")).replace("164.", "").strip()
sec_rec = by_section.setdefault(section, {"implemented": 0, "partial": 0, "gap": 0})
sec_rec[status] += 1
w = WEIGHT[req]
total_weight += w
earned_weight += w * CREDIT[status]
name = s.get("name", "")
is_high = any(k in name.lower() for k in HIGH_PRIORITY_KEYS)
# an addressable item with a documented equivalent alternative is acceptable
addressable_ok = (
req == "addressable"
and status != "implemented"
and s.get("alternative_documented") is True
)
if status in ("gap", "partial") and not addressable_ok:
if req == "required":
required_gaps.append(s)
else:
addressable_gaps.append(s)
if is_high:
escalated.append(s)
rows.append((sid, section, name, req, status, s.get("alternative_documented", None), is_high))
readiness = (100.0 * earned_weight / total_weight) if total_weight else 0.0
return {
"readiness": readiness,
"required_gaps": required_gaps,
"addressable_gaps": addressable_gaps,
"escalated": escalated,
"by_section": by_section,
"rows": rows,
}
def render(data, res):
org = data.get("org", {})
lines = []
lines.append(f"# HIPAA Security Rule Gap Assessment - {org.get('name','Organization')}")
lines.append("")
if org.get("role"):
lines.append(f"- **Role:** {org['role']}")
lines.append(f"- **Weighted readiness:** **{res['readiness']:.0f}%** "
"(required specifications weighted 2x addressable)")
lines.append(f"- **Required gaps:** {len(res['required_gaps'])} | "
f"Addressable gaps (no documented alternative): {len(res['addressable_gaps'])}")
lines.append("")
if res["escalated"]:
lines.append("> **OCR-priority gap detected:** Risk Analysis / Risk Management is "
"incomplete. This is the most-cited HIPAA finding - remediate first.")
lines.append("")
# status by section
lines.append("## Status by safeguard section")
lines.append("")
lines.append("| Section | Implemented | Partial | Gap |")
lines.append("|---|---|---|---|")
for sec in sorted(res["by_section"]):
r = res["by_section"][sec]
label = SECTION_NAMES.get(sec, sec)
lines.append(f"| {label} | {r['implemented']} | {r['partial']} | {r['gap']} |")
lines.append("")
# full table
lines.append("## Safeguard detail")
lines.append("")
lines.append("| Specification | Section | Requirement | Status | Alt. documented |")
lines.append("|---|---|---|---|---|")
for sid, sec, name, req, status, alt, _ in res["rows"]:
altdisp = "-" if alt is None else ("yes" if alt else "no")
secdisp = SECTION_NAMES.get(sec, sec)
lines.append(f"| {sid} {name} | {secdisp} | {req} | {status} | {altdisp} |")
lines.append("")
# remediation priority
lines.append("## Remediation priority")
lines.append("")
order = []
order += [(s, "ESCALATED (Risk Analysis/Mgmt)") for s in res["escalated"]]
order += [(s, "Required gap") for s in res["required_gaps"] if s not in res["escalated"]]
order += [(s, "Addressable - implement or document alternative") for s in res["addressable_gaps"]]
if not order:
lines.append("No outstanding gaps. Maintain documentation and re-evaluate on change.")
else:
seen = set()
i = 1
for s, why in order:
key = s.get("id")
if key in seen:
continue
seen.add(key)
lines.append(f"{i}. **{s.get('id')}** {s.get('name','')} - {why} "
f"(currently {s.get('status')}).")
i += 1
return "\n".join(lines)
def main():
ap = argparse.ArgumentParser(description="HIPAA Security Rule safeguard gap-assessment scorer")
ap.add_argument("--input", "-i", required=True, help="Path to safeguard-status JSON")
ap.add_argument("--output", "-o", help="Write Markdown gap assessment to this path")
ap.add_argument("--fail-on-required-gap", action="store_true",
help="Exit non-zero if any required specification is partial/gap")
args = ap.parse_args()
try:
with open(args.input) as f:
data = json.load(f)
except (OSError, json.JSONDecodeError) as e:
print(f"ERROR: could not read input JSON: {e}", file=sys.stderr)
return 2
try:
res = score(data)
md = render(data, res)
except ValueError as e:
print(f"ERROR: {e}", file=sys.stderr)
return 2
if args.output:
with open(args.output, "w") as f:
f.write(md + "\n")
print(f"Gap assessment written to {args.output}", file=sys.stderr)
else:
print(md)
print(f"Readiness {res['readiness']:.0f}%; required gaps {len(res['required_gaps'])}; "
f"escalated {len(res['escalated'])}.", file=sys.stderr)
if args.fail_on_required_gap and res["required_gaps"]:
ids = ", ".join(s.get("id", "?") for s in res["required_gaps"])
print(f"FAIL: {len(res['required_gaps'])} required specification gap(s): {ids}", file=sys.stderr)
return 1
return 0
if __name__ == "__main__":
sys.exit(main())
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to the Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by the Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding any notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. Please do not remove or change
the license header comment from a contributed file except when
necessary.
Copyright 2026 mukul975
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
@@ -0,0 +1,148 @@
---
name: managing-third-party-vendor-risk
description: >-
Build and run a third-party / vendor risk management (TPRM) program aligned to NIST
SP 800-161 C-SCRM and NIST CSF 2.0 GV.SC: inventory and tier vendors by risk, send the
right due-diligence questionnaire (SIG, CAIQ), review evidence (SOC 2, ISO 27001,
pen-test reports), set contractual security and right-to-audit clauses, monitor vendors
continuously, manage Nth-party / subcontractor risk, and offboard securely. Use when an
organization needs to assess a new vendor before onboarding, when standing up or maturing
a vendor-risk program, when tiering a vendor portfolio, when reviewing a SOC 2 or CAIQ,
when writing security requirements into a contract or DPA, when a vendor suffers a breach,
or when managing supply-chain / software supply-chain risk. Keywords: third-party risk,
vendor risk management, TPRM, supply chain risk, C-SCRM, NIST 800-161, vendor tiering,
SIG questionnaire, CAIQ, SOC 2, ISO 27001, right to audit, continuous monitoring, security
ratings, fourth-party risk, Nth-party, vendor offboarding, due diligence.
domain: cybersecurity
subdomain: compliance-governance
tags:
- third-party-risk
- vendor-risk-management
- tprm
- supply-chain-risk
- c-scrm
- nist-800-161
- soc2
- caiq
- continuous-monitoring
- governance
version: "1.0"
author: andrewibrah
license: Apache-2.0
nist_csf:
- GV.SC-01
- GV.SC-04
- GV.SC-06
- GV.SC-07
- ID.RA-05
- GV.OC-03
mitre_attack:
- T1199
- T1195
- T1078
- T1190
- T1567
---
# Managing Third-Party Vendor Risk
## When to Use
- When assessing a **new vendor** before onboarding, especially one that will handle sensitive data, connect to your network, or be embedded in a critical process.
- When **standing up or maturing** a third-party risk management (TPRM) program and you need a repeatable tiering + assessment workflow.
- When **tiering an existing vendor portfolio** so effort matches risk.
- When **reviewing vendor evidence** — a SOC 2 Type II report, ISO 27001 certificate, CAIQ, or pen-test summary — and you need to know what to look for.
- When writing **security and privacy requirements into a contract / DPA**, including breach-notification SLAs and right-to-audit.
- When a vendor (or their subcontractor) suffers a **breach** and you must assess exposure.
- When managing **software supply-chain** and **Nth-party** (fourth-party and beyond) risk.
## Prerequisites
- A **vendor inventory** (who you use, for what, and what data/access each has).
- A defined **risk-tiering model** (criteria and thresholds) agreed with the business.
- Access to standardized **questionnaires** (Shared Assessments **SIG**, CSA **CAIQ**) and a way to collect evidence.
- Clarity on your own **regulatory obligations** that flow down to vendors (e.g., HIPAA BAAs, CMMC flowdown, GDPR processor terms, PCI).
- Stakeholders identified: procurement, legal, security, data owner, and the business sponsor.
## Workflow
### 1. Inventory and classify vendors
Catalog every third party and capture: data sensitivity handled, type of access (network, physical, none), business criticality, and regulatory scope. You cannot manage what you have not inventoried — shadow vendors are a common blind spot.
### 2. Tier by inherent risk
Score each vendor on inherent-risk factors (data sensitivity, access, criticality, regulatory scope, spend/concentration) and assign a **tier** (e.g., Critical / High / Moderate / Low). The tier drives **how deep** the assessment goes and **how often** you reassess. A payroll processor with PII and system access is not the same risk as a stock-photo subscription.
### 3. Run tier-appropriate due diligence
- **Critical/High:** full **SIG** (or SIG Core), request **SOC 2 Type II** and/or **ISO 27001**, recent **pen-test** summary, and evidence of an incident-response capability. Consider an assessor call.
- **Moderate:** **SIG Lite** or **CAIQ**, plus key attestations.
- **Low:** lightweight questionnaire / self-attestation.
### 4. Review evidence critically
Don't just collect — **read**:
- **SOC 2 Type II:** check scope, the Trust Services Criteria covered, the audit **period** (not just the date), and especially the **exceptions/deviations** and any qualified opinion. A clean cover page can hide noted exceptions.
- **ISO 27001:** confirm the **scope statement** and the Statement of Applicability actually cover the service you're buying.
- **CAIQ:** look for "no" answers and CCM domains left blank.
- **Pen-test:** age, scope, and whether highs/criticals were remediated.
### 5. Identify gaps and decide
Compare findings against your control requirements. For each gap: accept, require remediation (with a date), add a compensating control on your side, or walk away. Record the **residual risk** and a risk-owner decision.
### 6. Codify in the contract / DPA
Bake requirements into the agreement: security control obligations, **breach-notification timeline**, data-handling and return/destruction terms, **right-to-audit / right to assessment evidence**, subcontractor (Nth-party) flowdown, and liability/insurance. Contracts are where TPRM gets teeth.
### 7. Monitor continuously
Tiering is not a one-time gate. For higher tiers: periodic reassessment, **security-ratings** feeds, breach/news monitoring, certificate-expiry tracking, and watching for material changes (acquisition, region change, new subprocessors). Re-tier on change.
### 8. Manage Nth-party and concentration risk
Map critical **fourth parties** (your vendor's key subprocessors) and watch for **concentration** (many vendors riding on the same upstream provider) — a single upstream outage or breach can hit your whole portfolio at once.
### 9. Offboard securely
On termination: revoke access and credentials, confirm **data return or certified destruction**, remove integrations/API keys, and update the inventory. Un-offboarded vendors are standing risk.
## Key Concepts
| Concept | Definition |
|---|---|
| Inherent risk | Risk a vendor poses before controls — drives tiering. |
| Residual risk | Risk remaining after the vendor's (and your) controls. |
| Vendor tier | Risk band (Critical/High/Moderate/Low) setting assessment depth and cadence. |
| SIG | Shared Assessments Standardized Information Gathering questionnaire (full / Lite / Core). |
| CAIQ | CSA Consensus Assessments Initiative Questionnaire (maps to the Cloud Controls Matrix). |
| SOC 2 Type II | Attestation on control design **and** operating effectiveness over a period. |
| Right to audit | Contractual right to assess the vendor or obtain assessment evidence. |
| Nth-party / fourth-party | Your vendor's vendors (and beyond) — indirect supply-chain risk. |
| Concentration risk | Many vendors depending on the same upstream provider. |
| C-SCRM | Cybersecurity Supply Chain Risk Management (NIST SP 800-161). |
## Tools & Systems
- **NIST SP 800-161 Rev 1** — Cybersecurity Supply Chain Risk Management practices.
- **NIST CSF 2.0 — GV.SC** — the supply-chain risk-management category (program backbone).
- **Shared Assessments SIG** and **CSA CAIQ / STAR registry** — standardized questionnaires.
- **SOC 2 / ISO 27001 / PCI AOC / pen-test reports** — vendor evidence.
- **Security-ratings services** (e.g., BitSight/SecurityScorecard-style) — continuous external signal.
- **TPRM platforms** — OneTrust, ProcessUnity, Prevalent, ServiceNow VRM, etc., to manage the workflow and inventory.
- **GDPR DPA / HIPAA BAA / CMMC flowdown** — regulatory contract instruments.
## Common Scenarios
- **New SaaS onboarding.** Tier it, send the right questionnaire, read the SOC 2 exceptions, set contract terms, then approve with documented residual risk.
- **Portfolio has 400 vendors, no tiers.** Tier first; concentrate assessment effort on the Critical/High tail rather than spreading thin.
- **Vendor breach in the news.** Pull the vendor record, assess data/access exposure, invoke the breach-notification clause, and require a post-incident report.
- **Auditor asks for your TPRM program.** Show the tiering model, the assessment cadence, and evidence of continuous monitoring mapped to GV.SC.
- **Critical fourth party identified.** Document the dependency and the concentration risk; build a contingency for that upstream provider.
## Output Format
Produce a **Vendor Risk Assessment** using `assets/template.md`, containing:
1. **Vendor profile** — service, data handled, access type, business criticality, regulatory scope.
2. **Inherent-risk tier** — score and resulting tier, with rationale.
3. **Due-diligence performed** — questionnaire used and evidence collected (SOC 2 period, ISO scope, pen-test age).
4. **Findings** — gaps with severity, including notable SOC 2 exceptions.
5. **Decision & residual risk** — approve/conditional/reject, with risk-owner sign-off.
6. **Contractual requirements** — security terms, breach SLA, right-to-audit, subprocessor flowdown.
7. **Monitoring & reassessment plan** — cadence, signals watched, re-tier triggers.
8. **Nth-party notes** — critical subprocessors and concentration risk.
Use `scripts/process.py` to compute a vendor's inherent-risk tier from a profile JSON, set the assessment depth and reassessment cadence, and flag missing evidence for the assigned tier.
@@ -0,0 +1,65 @@
# Vendor Risk Assessment — Worked Example
> Filled example for a payroll-processing vendor (regulated PII, deep integration).
> Replace bracketed content for your own vendor.
## 1. Vendor Profile
- **Vendor:** PayWorks
- **Service:** Payroll processing (SaaS)
- **Data handled:** Employee PII, bank details (regulated).
- **Access type:** System access (API + SSO into HRIS).
- **Business criticality:** High — a multi-day outage would block payroll.
- **Regulatory scope:** PII / state payroll requirements.
## 2. Inherent-Risk Tier
*(scored by `scripts/process.py`)*
| Factor | Value | Points |
|---|---|---|
| Data sensitivity | regulated | 4 |
| Access | system | 4 |
| Criticality | high | 4 |
| Integration | deep | 2 |
| Regulated scope | PII | 2 |
| Concentration | single payroll source | 1 |
| **Total** | | **17 → Tier: Critical** |
**Rationale:** regulated data + system access + high criticality place this in the top tier; assess deeply and monitor continuously.
## 3. Due Diligence Performed
- **Questionnaire:** Full SIG requested.
- **SOC 2:** Type II, **12-month** period obtained.
- **ISO 27001:** Certificate obtained — scope statement confirmed to cover the payroll service.
- **Pen-test:** Summary from 5 months ago; highs/criticals remediated.
## 4. Findings
| Finding | Severity | Note |
|---|---|---|
| SOC 2 exception: one quarter of incomplete access reviews | Moderate | Vendor provided remediation evidence; accept with monitoring |
| No customer-managed encryption keys | Low | Within risk tolerance for this data set |
| Two critical fourth parties (cloud + email) | Info | Concentration noted (see §8) |
> The SOC 2 cover page was clean — the exception was found in the body. Always read the deviations and CUECs.
## 5. Decision & Residual Risk
- **Decision:** **Approve — Conditional.**
- **Condition:** Vendor confirms completion of the access-review remediation within 60 days.
- **Residual risk:** **Moderate, accepted** by [data owner / risk owner], [date].
## 6. Contractual Requirements
- Security obligations mapped to our baseline (encryption, access control, logging).
- **Breach notification within 48 hours** of discovery.
- Data return / **certified destruction** within 30 days of termination.
- **Right to audit** or to receive a current SOC 2 annually.
- **Subprocessor flowdown** + prior notice of new subprocessors.
- Cyber-insurance minimum and liability terms.
- **DPA** executed (PII processing).
## 7. Monitoring & Reassessment Plan
- **Cadence:** Full reassessment **annually** (Critical tier).
- **Continuous signals:** security-ratings feed, breach/news monitoring, SOC 2 / ISO expiry tracking.
- **Re-tier triggers:** ownership change, new region/subprocessor, material breach, scope expansion.
## 8. Nth-Party / Concentration Notes
- **Critical fourth parties:** cloud IaaS provider and transactional email provider (from the SOC 2 subservice list).
- **Concentration risk:** our HRIS and PayWorks both ride the same cloud region — a single regional outage hits payroll and HR together. Contingency: documented manual-payroll fallback for one cycle.
@@ -0,0 +1,67 @@
# Third-Party / Vendor Risk Management — Standards & Reference
## Primary standards & frameworks
| Source | Role |
|---|---|
| **NIST SP 800-161 Rev 1** (May 2022) | Cybersecurity Supply Chain Risk Management (C-SCRM) practices for systems and organizations. URL: https://csrc.nist.gov/pubs/sp/800/161/r1/final |
| **NIST CSF 2.0 — GV.SC** | The Cybersecurity Supply Chain Risk Management category; the governance backbone for a TPRM program. |
| **NIST SP 800-37 / 800-53 (SR family)** | Supply Chain Risk Management controls (SR-x) within the broader control catalog. |
| **ISO/IEC 27036** | Information security for supplier relationships. |
| **Shared Assessments** | SIG questionnaire + Third Party Risk Management framework. |
| **CSA CAIQ / Cloud Controls Matrix (CCM) / STAR** | Cloud-vendor self-assessment and registry. |
## NIST CSF 2.0 — GV.SC subcategories (selected)
| ID | Outcome |
|---|---|
| GV.SC-01 | A cyber supply-chain risk-management program/strategy is established and agreed. |
| GV.SC-03 | Supply-chain risk management is integrated into cybersecurity and ERM. |
| GV.SC-04 | Suppliers are known and prioritized by criticality. |
| GV.SC-05 | Requirements to address supply-chain risk are established in contracts. |
| GV.SC-06 | Due diligence is performed to reduce risk before entering relationships. |
| GV.SC-07 | Supplier risks are understood, monitored, and managed over the relationship. |
| GV.SC-08 | Suppliers are included in incident planning, response, and recovery. |
| GV.SC-10 | Supply-chain risk is managed through to relationship termination. |
## Vendor tiering — typical inherent-risk factors
- **Data sensitivity** handled (regulated PII/PHI/CHD, IP, none).
- **Access type** (network/system access, physical access, none).
- **Business criticality** (would an outage stop operations?).
- **Regulatory scope** (HIPAA, PCI, GDPR, CMMC flowdown).
- **Integration depth** (API/identity federation vs standalone).
- **Concentration / spend** (single-source, large dependency).
Tiers commonly: **Critical / High / Moderate / Low** — each mapped to an assessment depth and a reassessment cadence.
## Due-diligence instruments
| Instrument | What it is |
|---|---|
| SIG (Full / Core / Lite) | Shared Assessments standardized questionnaire; depth scales with tier. |
| CAIQ | CSA questionnaire mapped to the Cloud Controls Matrix. |
| SOC 2 Type II | AICPA attestation on control **design and operating effectiveness over a period** (Trust Services Criteria: Security required; Availability, Confidentiality, Processing Integrity, Privacy optional). |
| SOC 2 Type I | Design only, at a point in time (weaker assurance than Type II). |
| ISO/IEC 27001 certificate + SoA | Certified ISMS; check the **scope statement** covers the purchased service. |
| Penetration-test summary | Independent testing; check age, scope, and remediation of highs/criticals. |
| PCI AOC | Attestation of Compliance for card-data handlers. |
## Reading a SOC 2 critically
- Confirm the **report type** (II > I) and the **audit period** length.
- Check the **scope / system description** matches the service you buy.
- Read the **exceptions / deviations** and the auditor's opinion (unqualified vs qualified).
- Review **complementary user-entity controls (CUECs)** — what the vendor expects **you** to do.
- Note the **subservice organizations** (their critical fourth parties).
## Contractual security terms to require
- Security control obligations (map to your baseline).
- **Breach-notification timeline** (e.g., notify within X hours of discovery).
- Data handling, location, and **return/certified destruction** on exit.
- **Right to audit** or to receive current assessment evidence.
- **Subcontractor (Nth-party) flowdown** and prior-approval of new subprocessors.
- Liability, indemnity, and cyber-insurance requirements.
- Regulatory instruments: **DPA** (GDPR), **BAA** (HIPAA), CMMC flowdown.
## Continuous monitoring signals
Security-ratings feeds, breach/news monitoring, certificate/attestation expiry, new subprocessor notices, ownership/region changes, and periodic re-questionnaire on cadence by tier.
## Nth-party & concentration risk
- **Fourth-party** = your vendor's vendors; map the critical ones.
- **Concentration risk** = many vendors depending on the same upstream (e.g., one cloud region or one auth provider) — a single upstream failure can be systemic.
@@ -0,0 +1,211 @@
#!/usr/bin/env python3
"""
Third-party vendor inherent-risk tiering and evidence-gap checker.
Scores a vendor's inherent risk from a profile, assigns a tier
(Critical/High/Moderate/Low), sets the assessment depth and reassessment
cadence for that tier, and flags evidence that is missing or stale for the
assigned tier.
Input JSON shape:
{
"vendor": {"name": "PayWorks", "service": "Payroll processing"},
"profile": {
"data_sensitivity": "regulated", # regulated | confidential | internal | public
"access": "system", # system | network | physical | none
"criticality": "high", # high | medium | low
"regulated_scope": ["PII"], # list; non-empty raises risk
"integration": "deep", # deep | moderate | none
"concentration": true # single-source / large dependency
},
"evidence": { # OPTIONAL; what you have on file
"sig": "core", # full | core | lite | caiq | none
"soc2_type": "II", # II | I | none
"soc2_period_months": 12,
"iso27001": true,
"pentest_age_months": 8
}
}
Usage:
python process.py --input vendor.json [--output assessment.md]
python process.py --input vendor.json --fail-on-evidence-gap
"""
import argparse
import json
import sys
# inherent-risk points per factor
DATA_POINTS = {"regulated": 4, "confidential": 3, "internal": 1, "public": 0}
ACCESS_POINTS = {"system": 4, "network": 3, "physical": 2, "none": 0}
CRIT_POINTS = {"high": 4, "medium": 2, "low": 1}
INTEG_POINTS = {"deep": 2, "moderate": 1, "none": 0}
# tier thresholds on total inherent score (max ~17)
def tier_for(score):
if score >= 13:
return "Critical"
if score >= 9:
return "High"
if score >= 5:
return "Moderate"
return "Low"
# per-tier expectations
TIER_PLAYBOOK = {
"Critical": {
"depth": "Full SIG + SOC 2 Type II (12-month period) + ISO 27001 + recent pen-test + assessor call",
"cadence": "Reassess annually; continuous security-ratings monitoring",
"require": {"sig": ("full", "core"), "soc2_type": ("II",), "iso27001": True, "pentest_max_months": 12},
},
"High": {
"depth": "SIG Core + SOC 2 Type II + pen-test summary",
"cadence": "Reassess annually",
"require": {"sig": ("full", "core"), "soc2_type": ("II",), "iso27001": False, "pentest_max_months": 18},
},
"Moderate": {
"depth": "SIG Lite or CAIQ + key attestations",
"cadence": "Reassess every 2 years",
"require": {"sig": ("full", "core", "lite", "caiq"), "soc2_type": ("II", "I"), "iso27001": False, "pentest_max_months": None},
},
"Low": {
"depth": "Lightweight questionnaire / self-attestation",
"cadence": "Reassess every 3 years or on change",
"require": {"sig": ("full", "core", "lite", "caiq", "none"), "soc2_type": ("II", "I", "none"), "iso27001": False, "pentest_max_months": None},
},
}
def score_inherent(p):
breakdown = {}
breakdown["data_sensitivity"] = DATA_POINTS.get(p.get("data_sensitivity", "internal"), 1)
breakdown["access"] = ACCESS_POINTS.get(p.get("access", "none"), 0)
breakdown["criticality"] = CRIT_POINTS.get(p.get("criticality", "low"), 1)
breakdown["integration"] = INTEG_POINTS.get(p.get("integration", "none"), 0)
breakdown["regulated_scope"] = 2 if p.get("regulated_scope") else 0
breakdown["concentration"] = 1 if p.get("concentration") else 0
total = sum(breakdown.values())
return total, breakdown
def check_evidence(tier, ev):
req = TIER_PLAYBOOK[tier]["require"]
gaps = []
sig = (ev.get("sig") or "none").lower()
if sig not in req["sig"]:
gaps.append(f"Questionnaire '{sig}' insufficient for {tier} (need one of {', '.join(req['sig'])})")
soc = (ev.get("soc2_type") or "none")
if soc not in req["soc2_type"]:
gaps.append(f"SOC 2 type '{soc}' insufficient for {tier} (need {', '.join(req['soc2_type'])})")
if soc == "II" and ev.get("soc2_period_months", 0) < 6:
gaps.append("SOC 2 Type II period under 6 months - limited operating-effectiveness assurance")
if req["iso27001"] and not ev.get("iso27001"):
gaps.append(f"ISO 27001 certificate expected for {tier}")
pmax = req["pentest_max_months"]
if pmax is not None:
age = ev.get("pentest_age_months")
if age is None:
gaps.append(f"No pen-test on file (expected within {pmax} months for {tier})")
elif age > pmax:
gaps.append(f"Pen-test is {age} months old (>{pmax} for {tier}) - request a current test")
return gaps
def render(data):
vendor = data.get("vendor", {})
profile = data.get("profile", {})
evidence = data.get("evidence", {})
if not profile:
raise ValueError("profile is required to tier the vendor")
total, breakdown = score_inherent(profile)
tier = tier_for(total)
play = TIER_PLAYBOOK[tier]
gaps = check_evidence(tier, evidence) if evidence else ["No evidence provided - collect tier-appropriate evidence"]
lines = []
lines.append(f"# Vendor Risk Assessment - {vendor.get('name','Vendor')}")
lines.append("")
if vendor.get("service"):
lines.append(f"- **Service:** {vendor['service']}")
lines.append(f"- **Inherent-risk score:** {total} -> **Tier: {tier}**")
lines.append("")
lines.append("## Inherent-risk breakdown")
lines.append("")
lines.append("| Factor | Value | Points |")
lines.append("|---|---|---|")
lines.append(f"| Data sensitivity | {profile.get('data_sensitivity','-')} | {breakdown['data_sensitivity']} |")
lines.append(f"| Access | {profile.get('access','-')} | {breakdown['access']} |")
lines.append(f"| Criticality | {profile.get('criticality','-')} | {breakdown['criticality']} |")
lines.append(f"| Integration | {profile.get('integration','-')} | {breakdown['integration']} |")
lines.append(f"| Regulated scope | {', '.join(profile.get('regulated_scope', [])) or 'none'} | {breakdown['regulated_scope']} |")
lines.append(f"| Concentration | {profile.get('concentration', False)} | {breakdown['concentration']} |")
lines.append(f"| **Total** | | **{total}** |")
lines.append("")
lines.append(f"## {tier}-tier playbook")
lines.append("")
lines.append(f"- **Assessment depth:** {play['depth']}")
lines.append(f"- **Reassessment cadence:** {play['cadence']}")
lines.append("")
lines.append("## Evidence gaps")
lines.append("")
if not gaps:
lines.append(f"Evidence on file meets the {tier}-tier bar. Proceed to findings review and contracting.")
else:
for g in gaps:
lines.append(f"- {g}")
lines.append("")
lines.append("## Next steps")
lines.append("")
lines.append("1. Close the evidence gaps above (or document risk-accepted exceptions).")
lines.append("2. Review collected evidence critically (SOC 2 exceptions, ISO scope, CAIQ 'no' answers).")
lines.append("3. Record findings, residual risk, and a risk-owner decision.")
lines.append("4. Codify security terms, breach SLA, right-to-audit, and subprocessor flowdown in the contract.")
lines.append("5. Enroll in continuous monitoring per the cadence above.")
return "\n".join(lines), tier, gaps
def main():
ap = argparse.ArgumentParser(description="Vendor inherent-risk tiering + evidence-gap checker")
ap.add_argument("--input", "-i", required=True, help="Path to vendor profile JSON")
ap.add_argument("--output", "-o", help="Write Markdown assessment to this path")
ap.add_argument("--fail-on-evidence-gap", action="store_true",
help="Exit non-zero if any evidence gap remains for the tier")
args = ap.parse_args()
try:
with open(args.input) as f:
data = json.load(f)
except (OSError, json.JSONDecodeError) as e:
print(f"ERROR: could not read input JSON: {e}", file=sys.stderr)
return 2
try:
md, tier, gaps = render(data)
except ValueError as e:
print(f"ERROR: {e}", file=sys.stderr)
return 2
if args.output:
with open(args.output, "w") as f:
f.write(md + "\n")
print(f"Assessment written to {args.output}", file=sys.stderr)
else:
print(md)
print(f"Tier: {tier}; evidence gaps: {len(gaps)}.", file=sys.stderr)
if args.fail_on_evidence_gap and gaps:
print(f"FAIL: {len(gaps)} evidence gap(s) for {tier} tier.", file=sys.stderr)
return 1
return 0
if __name__ == "__main__":
sys.exit(main())