mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-26 03:34:37 +03:00
Merge pull request #71 from andrewibrah/add-grc-skills
Add 5 skills: GRC (800-30, RMF, CMMC, HIPAA, TPRM)
This commit is contained in:
@@ -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.1–3.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 Low–Very High, or semi-quantitative 0–10). Lock these now.
|
||||
|
||||
### 2. Conduct the assessment
|
||||
Work through the analytic tasks in order. The 800-30 appendices provide the reference taxonomies (D–I).
|
||||
|
||||
**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 D–I 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 2a–2f 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 (0–10) |
|
||||
|---|---|
|
||||
| Very Low | 0–4 |
|
||||
| Low | 5–20 |
|
||||
| Moderate | 21–79 |
|
||||
| High | 80–95 |
|
||||
| Very High | 96–100 |
|
||||
|
||||
### 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.302–318) 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.400–414)
|
||||
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.400–414; 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.400–414)
|
||||
- **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.400–414** (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.400–414)
|
||||
- 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())
|
||||
Reference in New Issue
Block a user