filegrc 0.6.5 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/model/v4.json +82 -72
- package/package.json +1 -1
- package/src/cli.js +64 -0
- package/src/content-readiness.js +11 -0
- package/src/files.js +5 -0
- package/src/index.js +1 -0
- package/src/policy-activation.js +84 -0
- package/src/program-lifecycle.js +4 -0
- package/src/program-path.js +11 -10
- package/src/program-readiness.js +237 -37
- package/src/server.js +8 -0
- package/src/validate.js +23 -17
- package/src/web.js +123 -7
- package/src/workflow.js +21 -0
package/model/v4.json
CHANGED
|
@@ -553,7 +553,7 @@
|
|
|
553
553
|
},
|
|
554
554
|
"framework": {
|
|
555
555
|
"title": "Framework and criteria sources",
|
|
556
|
-
"description": "Confirm that the active framework records match the SOC 2 categories and description criteria
|
|
556
|
+
"description": "Confirm that the active framework records match the SOC 2 categories and description criteria selected for this program.",
|
|
557
557
|
"reviewPoints": [
|
|
558
558
|
"Confirm the selected Trust Services Categories match the service and planned audit.",
|
|
559
559
|
"Confirm any other legal, contractual, privacy, or security framework the service must follow.",
|
|
@@ -716,11 +716,10 @@
|
|
|
716
716
|
"collection": "people",
|
|
717
717
|
"description": "People who own, approve, review, or perform program work, or receive access and training. Record each person’s actual organization job title here and keep named program authority in dated Appointments. Keep detailed personnel records in the HR system.",
|
|
718
718
|
"guidance": {
|
|
719
|
-
"policyBasis": "The information security policy
|
|
719
|
+
"policyBasis": "The information security policy assigns work to named people and requires onboarding, training, role-change, and offboarding records.",
|
|
720
720
|
"cadence": "Create before assigning work or access, update the job title after organizational changes, review Appointments separately, and mark inactive only after active Appointments are ended or transferred. Training is due within 30 days of starting and annually.",
|
|
721
721
|
"sourceResourceIds": [
|
|
722
|
-
"policy-information-security"
|
|
723
|
-
"policy-employee-handbook"
|
|
722
|
+
"policy-information-security"
|
|
724
723
|
],
|
|
725
724
|
"obligationActivityTypes": [
|
|
726
725
|
"training",
|
|
@@ -817,8 +816,7 @@
|
|
|
817
816
|
"policyBasis": "The information security policy assigns named authority and accountability, while workforce procedures require responsibility changes and departures to be reviewed and transferred.",
|
|
818
817
|
"cadence": "Create when management assigns a named responsibility. End the Appointment and create a new one when the holder changes. Reassign every linked responsibility before a holder departs.",
|
|
819
818
|
"sourceResourceIds": [
|
|
820
|
-
"policy-information-security"
|
|
821
|
-
"policy-employee-handbook"
|
|
819
|
+
"policy-information-security"
|
|
822
820
|
]
|
|
823
821
|
},
|
|
824
822
|
"required": [
|
|
@@ -1051,7 +1049,7 @@
|
|
|
1051
1049
|
"cadence": "The security and risk oversight group meets at least quarterly. Update membership after responsibility or personnel changes, and preserve a chair who is separate from the policy owner.",
|
|
1052
1050
|
"sourceResourceIds": [
|
|
1053
1051
|
"policy-information-security",
|
|
1054
|
-
"document-
|
|
1052
|
+
"document-security-incident-recovery-plan"
|
|
1055
1053
|
],
|
|
1056
1054
|
"obligationActivityTypes": [
|
|
1057
1055
|
"meeting"
|
|
@@ -1130,7 +1128,7 @@
|
|
|
1130
1128
|
"collection": "systems",
|
|
1131
1129
|
"description": "The complete bounded system being governed or examined, including its services, boundary, information, Components, Controls, dependencies, and continuity objectives.",
|
|
1132
1130
|
"guidance": {
|
|
1133
|
-
"policyBasis": "A SOC 2 program starts with the bounded System
|
|
1131
|
+
"policyBasis": "A SOC 2 program starts with the bounded System and the service commitments and system requirements the company has chosen to meet.",
|
|
1134
1132
|
"cadence": "Define before selecting Components and Controls. Review after material service, boundary, architecture, information, continuity, or audit-scope changes.",
|
|
1135
1133
|
"reviewPoints": [
|
|
1136
1134
|
"Describe the complete service boundary rather than a single tool or provider.",
|
|
@@ -1255,12 +1253,10 @@
|
|
|
1255
1253
|
"collection": "assets",
|
|
1256
1254
|
"description": "Important devices, media, software, records, and other items tracked through acquisition, custody, use, return, and disposal. Assets support controls but do not define the service boundary.",
|
|
1257
1255
|
"guidance": {
|
|
1258
|
-
"policyBasis": "The information security
|
|
1256
|
+
"policyBasis": "The information security policy requires important assets to have owners and custodians, protection based on classification, and secure return or disposal.",
|
|
1259
1257
|
"cadence": "Record acquisition and assignment, review the inventory annually, update custody on change, and retire assets when use ends.",
|
|
1260
1258
|
"sourceResourceIds": [
|
|
1261
|
-
"policy-information-security"
|
|
1262
|
-
"policy-mobile-computing-communications",
|
|
1263
|
-
"policy-data-protection-handling"
|
|
1259
|
+
"policy-information-security"
|
|
1264
1260
|
],
|
|
1265
1261
|
"obligationActivityTypes": [
|
|
1266
1262
|
"inventory-review"
|
|
@@ -1399,7 +1395,7 @@
|
|
|
1399
1395
|
"cadence": "Follow the linked review Obligation. Starter governed documents are reviewed at least annually and after material changes or use, with an approver who is separate from the owner.",
|
|
1400
1396
|
"sourceResourceIds": [
|
|
1401
1397
|
"policy-information-security",
|
|
1402
|
-
"document-
|
|
1398
|
+
"document-security-incident-recovery-plan"
|
|
1403
1399
|
],
|
|
1404
1400
|
"obligationActivityTypes": [
|
|
1405
1401
|
"policy-review",
|
|
@@ -1637,12 +1633,11 @@
|
|
|
1637
1633
|
"recordPath": "{id}/evidence.json",
|
|
1638
1634
|
"description": "A retained export, report, screenshot, signed record, fixed file, or approved external reference. FileGRC operating records may support an audit directly without wrappers.",
|
|
1639
1635
|
"guidance": {
|
|
1640
|
-
"policyBasis": "The information security
|
|
1636
|
+
"policyBasis": "The information security policy requires retained proof from authoritative Components when FileGRC operating records do not contain the full result.",
|
|
1641
1637
|
"cadence": "Create an Evidence Artifact only for a real retained artifact or approved reference. Identify its source Component or source records, Controls, collection and verification facts, coverage, revision, and classification.",
|
|
1642
1638
|
"emptyState": "No Evidence Artifacts have been collected. Add one only when a real retained artifact or approved external reference exists.",
|
|
1643
1639
|
"sourceResourceIds": [
|
|
1644
|
-
"policy-information-security"
|
|
1645
|
-
"policy-data-protection-handling"
|
|
1640
|
+
"policy-information-security"
|
|
1646
1641
|
]
|
|
1647
1642
|
},
|
|
1648
1643
|
"required": [
|
|
@@ -2045,12 +2040,11 @@
|
|
|
2045
2040
|
"collection": "obligations",
|
|
2046
2041
|
"description": "Reusable schedules for recurring or event-driven work. Obligations feed the Work Queue; completion records and linked Evidence prove that the work occurred. Obligations are not required for SOC 2.",
|
|
2047
2042
|
"guidance": {
|
|
2048
|
-
"policyBasis": "
|
|
2049
|
-
"cadence": "
|
|
2043
|
+
"policyBasis": "FileGRC uses Obligations to turn approved schedules into owned, dated work linked to scope and required proof. An enabled Obligation remains dormant until every governing Policy is active and effective.",
|
|
2044
|
+
"cadence": "Configure and enable the schedule during Control implementation. Do not create occurrences while a governing Policy is approved but inactive. When the Policy becomes active and effective, use the later of the recurrence anchor and activation date, then create a separate completion record for every period.",
|
|
2050
2045
|
"sourceResourceIds": [
|
|
2051
2046
|
"policy-information-security",
|
|
2052
|
-
"
|
|
2053
|
-
"document-business-continuity-disaster-recovery"
|
|
2047
|
+
"document-security-incident-recovery-plan"
|
|
2054
2048
|
]
|
|
2055
2049
|
},
|
|
2056
2050
|
"required": [
|
|
@@ -2403,8 +2397,7 @@
|
|
|
2403
2397
|
"Use an external, zero-population, or not-applicable conclusion only when it is factually true for the current scope."
|
|
2404
2398
|
],
|
|
2405
2399
|
"sourceResourceIds": [
|
|
2406
|
-
"policy-information-security"
|
|
2407
|
-
"policy-data-protection-handling"
|
|
2400
|
+
"policy-information-security"
|
|
2408
2401
|
]
|
|
2409
2402
|
},
|
|
2410
2403
|
"required": [
|
|
@@ -2537,8 +2530,7 @@
|
|
|
2537
2530
|
"Before marking it not applicable, confirm that management is not responsible for the action."
|
|
2538
2531
|
],
|
|
2539
2532
|
"sourceResourceIds": [
|
|
2540
|
-
"policy-information-security"
|
|
2541
|
-
"policy-data-protection-handling"
|
|
2533
|
+
"policy-information-security"
|
|
2542
2534
|
]
|
|
2543
2535
|
},
|
|
2544
2536
|
"required": [
|
|
@@ -2660,16 +2652,15 @@
|
|
|
2660
2652
|
"collection": "controls",
|
|
2661
2653
|
"description": "Management's actual Control implementation, mapped to Requirements, bounded Systems, operating Components, and authoritative evidence-source Components.",
|
|
2662
2654
|
"guidance": {
|
|
2663
|
-
"policyBasis": "Controls translate approved Policies and applicable Requirements into owned procedures that management can operate and prove.
|
|
2664
|
-
"cadence": "Before marking
|
|
2655
|
+
"policyBasis": "Controls translate approved Policies and applicable Requirements into owned procedures that management can operate and prove. FileGRC does not infer technical implementation from policy prose. Configuration facts belong in Controls, Components, Systems, governed schedules, and Evidence.",
|
|
2656
|
+
"cadence": "A Control may be implemented while its governing Policy is approved but inactive. Before marking it implemented, record its owner, actual procedure in Record Markdown, bounded System scope, operation pattern, authoritative evidence-source Components, implementation date, and enabled calendar or event schedules. Confirm each source Component is active, has the evidence role required by the Control family and current access owners, and includes repeatable retrieval instructions in Record Markdown. Enabled schedules remain dormant until their governing Policies are active and effective.",
|
|
2665
2657
|
"reviewPoints": [
|
|
2666
2658
|
"Confirm the Control is needed for the applicable Requirements, customer Commitments, and current service boundary.",
|
|
2667
2659
|
"Confirm the procedure describes what people actually do.",
|
|
2668
2660
|
"Use a not-applicable, external, or zero-population conclusion only when it is factually true for the current scope."
|
|
2669
2661
|
],
|
|
2670
2662
|
"sourceResourceIds": [
|
|
2671
|
-
"policy-information-security"
|
|
2672
|
-
"policy-data-protection-handling"
|
|
2663
|
+
"policy-information-security"
|
|
2673
2664
|
],
|
|
2674
2665
|
"obligationActivityTypes": [
|
|
2675
2666
|
"risk-assessment",
|
|
@@ -3218,11 +3209,10 @@
|
|
|
3218
3209
|
"collection": "exceptions",
|
|
3219
3210
|
"description": "An approved, time-bound departure from a Policy or Control. Record its scope, reason, risk, compensating Controls, owner, approval, and expiry. An Exception record is not required for SOC 2 unless a departure is approved.",
|
|
3220
3211
|
"guidance": {
|
|
3221
|
-
"policyBasis": "The information security
|
|
3212
|
+
"policyBasis": "The information security policy allows departures only with a business reason, assessed risk, compensating safeguards, approval, and an expiry or review date.",
|
|
3222
3213
|
"cadence": "Approve before the departure begins, follow its linked review Obligation or expiry, and close or renew it through a new risk decision.",
|
|
3223
3214
|
"sourceResourceIds": [
|
|
3224
|
-
"policy-information-security"
|
|
3225
|
-
"policy-data-protection-handling"
|
|
3215
|
+
"policy-information-security"
|
|
3226
3216
|
]
|
|
3227
3217
|
},
|
|
3228
3218
|
"required": [
|
|
@@ -3451,10 +3441,10 @@
|
|
|
3451
3441
|
"pluralTitle": "Policies",
|
|
3452
3442
|
"group": "governance",
|
|
3453
3443
|
"collection": "policies",
|
|
3454
|
-
"description": "Management-approved
|
|
3444
|
+
"description": "Management-approved requirements for the program. Approval accepts the requirements; activation makes them effective. Store the Policy text in Markdown and its owner, separate approver, scope, status, dates, and linked Controls in the record.",
|
|
3455
3445
|
"guidance": {
|
|
3456
|
-
"policyBasis": "
|
|
3457
|
-
"cadence": "Move a draft through review and approval
|
|
3446
|
+
"policyBasis": "A Policy says what the company commits to do by the date it takes effect. Approval means the company accepts those commitments. It does not prove the work is done. Controls and operating records describe how the company meets them and provide the proof.",
|
|
3447
|
+
"cadence": "Move a draft through independent review and approval without requiring every linked Control to be implemented. During Step 3, finish Controls, Components, evidence sources, governed plans, and schedules, review the per-Policy activation assessment, then activate the approved revision on its real effective date. Do not backdate adoption. The approver is usually internal and may be external, but must be separate from the owner and from the CPA auditor role. Review at least annually and after material changes.",
|
|
3458
3448
|
"sourceResourceIds": [
|
|
3459
3449
|
"policy-information-security"
|
|
3460
3450
|
],
|
|
@@ -3674,7 +3664,7 @@
|
|
|
3674
3664
|
"collection": "policy-reviews",
|
|
3675
3665
|
"description": "The result of a scheduled or change-driven review of Policies or governed Documents, including reviewers, decision, evidence, and follow-up. Edit the source record separately when changes are approved.",
|
|
3676
3666
|
"guidance": {
|
|
3677
|
-
"policyBasis": "
|
|
3667
|
+
"policyBasis": "The Information Security Policy and Security Incident and Recovery Plan require periodic review and another review after specified material changes.",
|
|
3678
3668
|
"cadence": "Complete annually and after a triggering change, incident, disruption, or policy condition. Link the exact scope, reviewers, result, and evidence.",
|
|
3679
3669
|
"reviewPoints": [
|
|
3680
3670
|
"Read the current Policy or governed Document.",
|
|
@@ -3683,7 +3673,7 @@
|
|
|
3683
3673
|
],
|
|
3684
3674
|
"sourceResourceIds": [
|
|
3685
3675
|
"policy-information-security",
|
|
3686
|
-
"document-
|
|
3676
|
+
"document-security-incident-recovery-plan"
|
|
3687
3677
|
],
|
|
3688
3678
|
"obligationActivityTypes": [
|
|
3689
3679
|
"policy-review"
|
|
@@ -3811,12 +3801,10 @@
|
|
|
3811
3801
|
"collection": "attestations",
|
|
3812
3802
|
"description": "One person’s acknowledgement, training completion, certification, or assigned-work confirmation. Bind it to the exact content revision and signed Evidence when required.",
|
|
3813
3803
|
"guidance": {
|
|
3814
|
-
"policyBasis": "The information security policy
|
|
3804
|
+
"policyBasis": "The information security policy requires people to complete assigned training and acknowledge applicable responsibilities.",
|
|
3815
3805
|
"cadence": "Assign during onboarding, within 30 days for security training, annually for recurring training, and after material content changes that require acknowledgement.",
|
|
3816
3806
|
"sourceResourceIds": [
|
|
3817
|
-
"policy-information-security"
|
|
3818
|
-
"policy-data-protection-handling",
|
|
3819
|
-
"policy-employee-handbook"
|
|
3807
|
+
"policy-information-security"
|
|
3820
3808
|
],
|
|
3821
3809
|
"obligationActivityTypes": [
|
|
3822
3810
|
"training"
|
|
@@ -3972,11 +3960,11 @@
|
|
|
3972
3960
|
"collection": "meetings",
|
|
3973
3961
|
"description": "One governance meeting, including its chair, attendees, agenda, minutes, decisions, raised issues, Evidence, and assigned follow-up.",
|
|
3974
3962
|
"guidance": {
|
|
3975
|
-
"policyBasis": "The information security policy requires recorded security and risk oversight. The
|
|
3963
|
+
"policyBasis": "The information security policy requires recorded security and risk oversight. The Security Incident and Recovery Plan requires management review of exercises and unresolved risks.",
|
|
3976
3964
|
"cadence": "Hold security and risk oversight meetings at least quarterly. Create one immutable meeting record and Markdown minutes for each occurrence.",
|
|
3977
3965
|
"sourceResourceIds": [
|
|
3978
3966
|
"policy-information-security",
|
|
3979
|
-
"document-
|
|
3967
|
+
"document-security-incident-recovery-plan"
|
|
3980
3968
|
],
|
|
3981
3969
|
"obligationActivityTypes": [
|
|
3982
3970
|
"meeting"
|
|
@@ -4118,11 +4106,10 @@
|
|
|
4118
4106
|
"collection": "training",
|
|
4119
4107
|
"description": "Reusable training content and assignment rules, including audience, trigger, completion window, passing criteria, and linked Policies and Controls. Obligations define assignment schedules. Individual completions belong in Attestations.",
|
|
4120
4108
|
"guidance": {
|
|
4121
|
-
"policyBasis": "The information security
|
|
4109
|
+
"policyBasis": "The information security policy requires security training and added role-specific instruction when a person’s responsibilities or data access warrant it.",
|
|
4122
4110
|
"cadence": "Assign security training at onboarding, complete it within 30 days, repeat at least annually, and reassign after relevant material changes or incidents.",
|
|
4123
4111
|
"sourceResourceIds": [
|
|
4124
|
-
"policy-information-security"
|
|
4125
|
-
"policy-data-protection-handling"
|
|
4112
|
+
"policy-information-security"
|
|
4126
4113
|
],
|
|
4127
4114
|
"obligationActivityTypes": [
|
|
4128
4115
|
"training"
|
|
@@ -4243,11 +4230,10 @@
|
|
|
4243
4230
|
"collection": "risks",
|
|
4244
4231
|
"description": "One identified threat or business impact that needs treatment or ongoing tracking. Record its owner, ratings, response, affected scope, Controls, acceptance, and follow-up.",
|
|
4245
4232
|
"guidance": {
|
|
4246
|
-
"policyBasis": "The information security
|
|
4233
|
+
"policyBasis": "The information security policy requires identified Risks to have an owner, rating, treatment decision, target date, and time-bound approval when accepted.",
|
|
4247
4234
|
"cadence": "Assess the register at least annually and after material changes. Review High and Critical risks at least quarterly and accepted risks by their review date.",
|
|
4248
4235
|
"sourceResourceIds": [
|
|
4249
|
-
"policy-information-security"
|
|
4250
|
-
"policy-data-protection-handling"
|
|
4236
|
+
"policy-information-security"
|
|
4251
4237
|
],
|
|
4252
4238
|
"obligationActivityTypes": [
|
|
4253
4239
|
"risk-assessment"
|
|
@@ -4417,7 +4403,7 @@
|
|
|
4417
4403
|
"collection": "risk-assessments",
|
|
4418
4404
|
"description": "One approved evaluation of a defined scope using the program’s risk method. It records participants, Systems, Vendors, conclusions, Evidence, and the Risks created or reassessed.",
|
|
4419
4405
|
"guidance": {
|
|
4420
|
-
"policyBasis": "The information security
|
|
4406
|
+
"policyBasis": "The information security policy requires periodic and change-driven assessment of threats, assets, obligations, Controls, likelihood, impact, and treatment.",
|
|
4421
4407
|
"cadence": "Complete at least annually and after a material change that could alter risk. Record new and changed risks instead of hiding them in the summary.",
|
|
4422
4408
|
"reviewPoints": [
|
|
4423
4409
|
"Confirm the assessment covered the real service, material dependencies, data, commitments, and recent changes.",
|
|
@@ -4425,8 +4411,7 @@
|
|
|
4425
4411
|
"Confirm no material risk was left out."
|
|
4426
4412
|
],
|
|
4427
4413
|
"sourceResourceIds": [
|
|
4428
|
-
"policy-information-security"
|
|
4429
|
-
"policy-data-protection-handling"
|
|
4414
|
+
"policy-information-security"
|
|
4430
4415
|
],
|
|
4431
4416
|
"obligationActivityTypes": [
|
|
4432
4417
|
"risk-assessment"
|
|
@@ -4629,11 +4614,10 @@
|
|
|
4629
4614
|
"collection": "vendors",
|
|
4630
4615
|
"description": "External organizations and commercial relationships, including contracts, due diligence, risk reviews, monitoring, assurance reports, dates, and general information-access facts.",
|
|
4631
4616
|
"guidance": {
|
|
4632
|
-
"policyBasis": "The information security
|
|
4617
|
+
"policyBasis": "The information security policy requires an inventory of important providers, risk-based review before access or reliance, suitable contract terms, and ongoing monitoring.",
|
|
4633
4618
|
"cadence": "Create for a material external provider relationship. Review critical and high-risk Vendors at least annually and after material relationship, service, access, or incident changes. Do not create a Component unless a supplied capability also meets the Component inclusion rules.",
|
|
4634
4619
|
"sourceResourceIds": [
|
|
4635
|
-
"policy-information-security"
|
|
4636
|
-
"policy-data-protection-handling"
|
|
4620
|
+
"policy-information-security"
|
|
4637
4621
|
],
|
|
4638
4622
|
"obligationActivityTypes": [
|
|
4639
4623
|
"inventory-review",
|
|
@@ -4750,7 +4734,7 @@
|
|
|
4750
4734
|
"collection": "vendor-reviews",
|
|
4751
4735
|
"description": "One due-diligence or periodic review of a Vendor, covering the service, data, access, assurance, recovery, incidents, contracts, Risks, Evidence, and follow-up.",
|
|
4752
4736
|
"guidance": {
|
|
4753
|
-
"policyBasis": "The information security
|
|
4737
|
+
"policyBasis": "The information security policy requires review before a Vendor handles sensitive data or supports important services, plus periodic review of higher-risk providers.",
|
|
4754
4738
|
"cadence": "Complete before access, at least annually for Critical and High-risk vendors, and after material service changes or incidents.",
|
|
4755
4739
|
"reviewPoints": [
|
|
4756
4740
|
"Confirm the review covers the Vendor’s current services, connected Systems, data access, criticality, subservice role, and contract terms.",
|
|
@@ -4758,8 +4742,7 @@
|
|
|
4758
4742
|
"Make the approve, conditional, or reject decision match the risks and assign any needed follow-up."
|
|
4759
4743
|
],
|
|
4760
4744
|
"sourceResourceIds": [
|
|
4761
|
-
"policy-information-security"
|
|
4762
|
-
"policy-data-protection-handling"
|
|
4745
|
+
"policy-information-security"
|
|
4763
4746
|
],
|
|
4764
4747
|
"obligationActivityTypes": [
|
|
4765
4748
|
"vendor-review"
|
|
@@ -4887,11 +4870,10 @@
|
|
|
4887
4870
|
"collection": "access-grants",
|
|
4888
4871
|
"description": "One Person’s or Service Account’s access to one System, including business need, privilege, request, approval, provisioning, expiry, removal, ticket, and Evidence.",
|
|
4889
4872
|
"guidance": {
|
|
4890
|
-
"policyBasis": "The information security
|
|
4873
|
+
"policyBasis": "The information security policy requires unique identity, documented business need, least privilege, approval, authorized provisioning, and prompt removal.",
|
|
4891
4874
|
"cadence": "Record every grant and material change. Remove access at or before notice for involuntary or high-risk departures and within 24 hours for other departures.",
|
|
4892
4875
|
"sourceResourceIds": [
|
|
4893
|
-
"policy-information-security"
|
|
4894
|
-
"policy-data-protection-handling"
|
|
4876
|
+
"policy-information-security"
|
|
4895
4877
|
]
|
|
4896
4878
|
},
|
|
4897
4879
|
"required": [
|
|
@@ -5065,7 +5047,7 @@
|
|
|
5065
5047
|
"collection": "access-reviews",
|
|
5066
5048
|
"description": "One review of a defined access population for a date or period, including Systems, reviewers, Access Grant decisions, exceptions, approval, Evidence, and source revision.",
|
|
5067
5049
|
"guidance": {
|
|
5068
|
-
"policyBasis": "The information security
|
|
5050
|
+
"policyBasis": "The information security policy requires System owners to periodically confirm least privilege and remove dormant, expired, excessive, or unneeded access.",
|
|
5069
5051
|
"cadence": "Review privileged and production access at least quarterly and other important-system access at least annually.",
|
|
5070
5052
|
"reviewPoints": [
|
|
5071
5053
|
"Confirm the review population is complete for every System and exact date or period in scope.",
|
|
@@ -5073,8 +5055,7 @@
|
|
|
5073
5055
|
"Confirm every removal, change, or exception has follow-up."
|
|
5074
5056
|
],
|
|
5075
5057
|
"sourceResourceIds": [
|
|
5076
|
-
"policy-information-security"
|
|
5077
|
-
"policy-data-protection-handling"
|
|
5058
|
+
"policy-information-security"
|
|
5078
5059
|
],
|
|
5079
5060
|
"obligationActivityTypes": [
|
|
5080
5061
|
"access-review"
|
|
@@ -5586,11 +5567,10 @@
|
|
|
5586
5567
|
"collection": "incidents",
|
|
5587
5568
|
"description": "One suspected or confirmed security or privacy event, with severity, timeline, scope, owner, affected Systems and Vendors, Evidence, Findings, and corrective work. An Incident record is not required for SOC 2 when no incident occurred.",
|
|
5588
5569
|
"guidance": {
|
|
5589
|
-
"policyBasis": "The information security
|
|
5570
|
+
"policyBasis": "The information security policy requires prompt reporting, investigation, containment, recovery, evidence preservation, and review of notification duties.",
|
|
5590
5571
|
"cadence": "Create on report or detection, update material events as they progress, and complete a retrospective within one week after a material incident.",
|
|
5591
5572
|
"sourceResourceIds": [
|
|
5592
|
-
"policy-information-security"
|
|
5593
|
-
"policy-data-protection-handling"
|
|
5573
|
+
"policy-information-security"
|
|
5594
5574
|
]
|
|
5595
5575
|
},
|
|
5596
5576
|
"required": [
|
|
@@ -5773,11 +5753,11 @@
|
|
|
5773
5753
|
"collection": "exercises",
|
|
5774
5754
|
"description": "One continuity, recovery, incident, or privacy simulation, including scenario, objective, participants, scope, result, Evidence, Findings, and follow-up.",
|
|
5775
5755
|
"guidance": {
|
|
5776
|
-
"policyBasis": "The information security policy requires incident-response testing. The
|
|
5756
|
+
"policyBasis": "The information security policy requires incident-response testing. The Security Incident and Recovery Plan requires exercises and another review after material change or disruption.",
|
|
5777
5757
|
"cadence": "Test incident response and continuity at least annually. Repeat after a material change when the prior exercise no longer represents the environment.",
|
|
5778
5758
|
"sourceResourceIds": [
|
|
5779
5759
|
"policy-information-security",
|
|
5780
|
-
"document-
|
|
5760
|
+
"document-security-incident-recovery-plan"
|
|
5781
5761
|
],
|
|
5782
5762
|
"obligationActivityTypes": [
|
|
5783
5763
|
"exercise"
|
|
@@ -5911,7 +5891,7 @@
|
|
|
5911
5891
|
"collection": "backup-tests",
|
|
5912
5892
|
"description": "One restore or recovery test, including the Systems and operators involved, timing, recovery result, reviewer, Evidence, Findings, and follow-up.",
|
|
5913
5893
|
"guidance": {
|
|
5914
|
-
"policyBasis": "The information security policy and
|
|
5894
|
+
"policyBasis": "The information security policy and Security Incident and Recovery Plan require protected backups, monitored failures, and tested proof that important data can be restored and used.",
|
|
5915
5895
|
"cadence": "Test restoration at least annually for important systems and after recovery changes that could invalidate prior evidence.",
|
|
5916
5896
|
"reviewPoints": [
|
|
5917
5897
|
"Confirm the test restored the intended Systems and data.",
|
|
@@ -5920,7 +5900,7 @@
|
|
|
5920
5900
|
],
|
|
5921
5901
|
"sourceResourceIds": [
|
|
5922
5902
|
"policy-information-security",
|
|
5923
|
-
"document-
|
|
5903
|
+
"document-security-incident-recovery-plan"
|
|
5924
5904
|
],
|
|
5925
5905
|
"obligationActivityTypes": [
|
|
5926
5906
|
"backup-test"
|
|
@@ -6224,10 +6204,10 @@
|
|
|
6224
6204
|
"collection": "data-requests",
|
|
6225
6205
|
"description": "One privacy, contractual, or other data request tracked by opaque reference, with scope, due date, decision, Evidence, and completion. Data Request tracking is not required for a SOC 2 Security-only report.",
|
|
6226
6206
|
"guidance": {
|
|
6227
|
-
"policyBasis": "The
|
|
6207
|
+
"policyBasis": "The information security policy requires applicable requests to reach a responsible owner, meet the governing deadline, and keep erasable personal data out of immutable Git history.",
|
|
6228
6208
|
"cadence": "Create on receipt, set the deadline from applicable law or contract, verify identity outside this repository when needed, and record completion.",
|
|
6229
6209
|
"sourceResourceIds": [
|
|
6230
|
-
"policy-
|
|
6210
|
+
"policy-information-security"
|
|
6231
6211
|
]
|
|
6232
6212
|
},
|
|
6233
6213
|
"required": [
|
|
@@ -7391,6 +7371,7 @@
|
|
|
7391
7371
|
"profileId": {
|
|
7392
7372
|
"type": "enum",
|
|
7393
7373
|
"values": [
|
|
7374
|
+
"endpoint-verification",
|
|
7394
7375
|
"inventory-review",
|
|
7395
7376
|
"log-review",
|
|
7396
7377
|
"network-review",
|
|
@@ -9318,6 +9299,23 @@
|
|
|
9318
9299
|
"incident"
|
|
9319
9300
|
]
|
|
9320
9301
|
},
|
|
9302
|
+
"endpoint-verification": {
|
|
9303
|
+
"title": "Endpoint verification",
|
|
9304
|
+
"completionType": "control-activity",
|
|
9305
|
+
"completionResourceTypes": [
|
|
9306
|
+
"control-activity"
|
|
9307
|
+
],
|
|
9308
|
+
"recurrenceModes": [
|
|
9309
|
+
"calendar",
|
|
9310
|
+
"event"
|
|
9311
|
+
],
|
|
9312
|
+
"scopeResourceTypes": [
|
|
9313
|
+
"system",
|
|
9314
|
+
"asset",
|
|
9315
|
+
"component"
|
|
9316
|
+
],
|
|
9317
|
+
"completionProfile": "endpoint-verification"
|
|
9318
|
+
},
|
|
9321
9319
|
"inventory-review": {
|
|
9322
9320
|
"title": "Inventory review",
|
|
9323
9321
|
"completionType": "control-activity",
|
|
@@ -9964,6 +9962,18 @@
|
|
|
9964
9962
|
}
|
|
9965
9963
|
},
|
|
9966
9964
|
"completionProfiles": {
|
|
9965
|
+
"endpoint-verification": {
|
|
9966
|
+
"title": "Endpoint verification",
|
|
9967
|
+
"resourceType": "control-activity",
|
|
9968
|
+
"requiredFacts": [
|
|
9969
|
+
"performerIds",
|
|
9970
|
+
"scopeResourceIds",
|
|
9971
|
+
"method",
|
|
9972
|
+
"result",
|
|
9973
|
+
"reviewerIds",
|
|
9974
|
+
"completedAt"
|
|
9975
|
+
]
|
|
9976
|
+
},
|
|
9967
9977
|
"inventory-review": {
|
|
9968
9978
|
"title": "Inventory review",
|
|
9969
9979
|
"resourceType": "control-activity",
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -41,6 +41,7 @@ import {
|
|
|
41
41
|
setupExternalReviewerGovernance
|
|
42
42
|
} from "./external-reviewer.js";
|
|
43
43
|
import { relativeToWorkspace, resolveDataPath } from "./paths.js";
|
|
44
|
+
import { activatePolicies, planPolicyActivation, scaffoldPolicyActivation } from "./policy-activation.js";
|
|
44
45
|
import { buildAgentProgramPath } from "./program-path.js";
|
|
45
46
|
import { assessEvidenceMap, assessProgramReadiness } from "./program-readiness.js";
|
|
46
47
|
import { resolveProgram } from "./program.js";
|
|
@@ -432,6 +433,12 @@ export async function runCli(argv = process.argv.slice(2)) {
|
|
|
432
433
|
console.log(`\n${stage.title}`);
|
|
433
434
|
for (const item of stage.items) console.log(`${item.status.toUpperCase()}\t${item.title}\t${item.message}`);
|
|
434
435
|
}
|
|
436
|
+
if (result.policyActivations.length) {
|
|
437
|
+
console.log("\nPolicy activation assessments");
|
|
438
|
+
for (const policy of result.policyActivations) {
|
|
439
|
+
console.log(`${policy.label.toUpperCase()}\t${policy.title}\t${policy.gapCount} implementation gaps`);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
435
442
|
if (result.canStartCandidatePeriod && !result.operating) {
|
|
436
443
|
console.log(`\nEvidence Ready: management can start the candidate Type 2 period on or after ${result.suggestedCandidatePeriodStart || result.asOf}.`);
|
|
437
444
|
}
|
|
@@ -588,6 +595,27 @@ export async function runCli(argv = process.argv.slice(2)) {
|
|
|
588
595
|
else console.log(`Confirmed ${result.assessment.configuration.title}.`);
|
|
589
596
|
return result;
|
|
590
597
|
}
|
|
598
|
+
if (command === "activate-policies") {
|
|
599
|
+
if (flags.scaffold) {
|
|
600
|
+
const result = await scaffoldPolicyActivation(root, { programId: flags.program });
|
|
601
|
+
console.log(JSON.stringify(result, null, 2));
|
|
602
|
+
return result;
|
|
603
|
+
}
|
|
604
|
+
const payload = await readSetupPayload(positionals[0]);
|
|
605
|
+
const options = {
|
|
606
|
+
...payload,
|
|
607
|
+
policyIds: flags.policy ? String(flags.policy).split(",").filter(Boolean) : payload.policyIds,
|
|
608
|
+
effectiveOn: flags["effective-on"] || payload.effectiveOn,
|
|
609
|
+
confirmed: flags.yes === true
|
|
610
|
+
};
|
|
611
|
+
const result = flags.preview
|
|
612
|
+
? await planPolicyActivation(root, options)
|
|
613
|
+
: await withWorkflowDelta(root, () => activatePolicies(root, options));
|
|
614
|
+
if (flags.json) console.log(JSON.stringify(result, null, 2));
|
|
615
|
+
else if (flags.preview) console.log(`Policy activation preview: ${result.policyIds.length} Policies effective ${result.effectiveOn}.`);
|
|
616
|
+
else console.log(`Activated ${result.policyIds.length} Policies effective ${result.effectiveOn}.`);
|
|
617
|
+
return result;
|
|
618
|
+
}
|
|
591
619
|
if (command === "trigger") {
|
|
592
620
|
const result = await withWorkflowDelta(root, () => createObligationEvent(root, {
|
|
593
621
|
eventType: positionals[0],
|
|
@@ -1025,6 +1053,7 @@ Usage:
|
|
|
1025
1053
|
filegrc next-audit-cycle <prior-audit-id> [cycle.json|-] --start YYYY-MM-DD --end YYYY-MM-DD [--preview|--yes] [--json]
|
|
1026
1054
|
filegrc review-applicability [--scaffold --type requirement|control|commitment|complementary-control] [decisions.json|-] [--preview|--yes] [--json]
|
|
1027
1055
|
filegrc review-collection <resource-type> [--scaffold | review.json|-] [--preview|--yes] [--json]
|
|
1056
|
+
filegrc activate-policies [--scaffold | activation.json|-] [--effective-on YYYY-MM-DD] [--preview|--yes] [--json]
|
|
1028
1057
|
filegrc trigger <event-type> (--occurred-on YYYY-MM-DD | --occurred-at RFC3339) [--risk-level normal|high] [--subject resource-id[,resource-id]] [--title text] [--json]
|
|
1029
1058
|
filegrc evidence-packet [--audit audit-id] [--start YYYY-MM-DD] [--end YYYY-MM-DD] [--output .filegrc/path] [--preview] [--require-ready] [--json]
|
|
1030
1059
|
filegrc get [resource-type] <id> [--mutation]
|
|
@@ -1174,6 +1203,26 @@ Options:
|
|
|
1174
1203
|
--help Show this help`);
|
|
1175
1204
|
return;
|
|
1176
1205
|
}
|
|
1206
|
+
if (command === "activate-policies") {
|
|
1207
|
+
console.log(`Usage:
|
|
1208
|
+
filegrc activate-policies --scaffold [--program id]
|
|
1209
|
+
filegrc activate-policies <activation.json|-> [--effective-on YYYY-MM-DD] [--preview|--yes] [--json]
|
|
1210
|
+
|
|
1211
|
+
Review and atomically activate selected approved Policies at the end of Step 3.
|
|
1212
|
+
The scaffold includes every required, approved, inactive Policy and its current
|
|
1213
|
+
revision. A past effective date is rejected.
|
|
1214
|
+
|
|
1215
|
+
Options:
|
|
1216
|
+
--scaffold Print a cutover payload without writing
|
|
1217
|
+
--program <id> Program to assess when more than one active Program exists
|
|
1218
|
+
--effective-on <date> Shared effective date for the selected Policies
|
|
1219
|
+
--preview Validate and show the atomic updates without writing
|
|
1220
|
+
--yes Confirm and apply the reviewed cutover
|
|
1221
|
+
--json Print the result as JSON
|
|
1222
|
+
--root <path> Workspace path
|
|
1223
|
+
--help Show this help`);
|
|
1224
|
+
return;
|
|
1225
|
+
}
|
|
1177
1226
|
if (command === "evidence-map") {
|
|
1178
1227
|
console.log(`Usage:
|
|
1179
1228
|
filegrc evidence-map [options]
|
|
@@ -1220,6 +1269,7 @@ function agentOverview(model) {
|
|
|
1220
1269
|
prepareAudit: "filegrc prepare-audit <audit-id>",
|
|
1221
1270
|
reconcile: "filegrc reconcile --preview --json",
|
|
1222
1271
|
externalReviewerSetup: "filegrc external-reviewer-setup [--scaffold | <reviewer.json|-> --preview] --json",
|
|
1272
|
+
policyActivation: "filegrc activate-policies [--scaffold | <activation.json|-> --preview] --json",
|
|
1223
1273
|
nextAuditCycle: "filegrc next-audit-cycle <prior-audit-id> --start <date> --end <date> --preview --json",
|
|
1224
1274
|
reviewApplicability: "filegrc review-applicability <decisions.json|-> --preview --json",
|
|
1225
1275
|
reviewCollection: "filegrc review-collection <resource-type> [--scaffold | <review.json|-> --preview] --json",
|
|
@@ -1371,6 +1421,8 @@ function buildProgramPathResult(model, readiness, auditReadiness) {
|
|
|
1371
1421
|
currentStep: { id: currentStep.id, number: currentStep.number, title: currentStep.title },
|
|
1372
1422
|
evidenceReady: readiness.evidenceReady,
|
|
1373
1423
|
operating: readiness.operating,
|
|
1424
|
+
policyActivations: readiness.policyActivations,
|
|
1425
|
+
policyLibraryProposals: readiness.policyLibraryProposals,
|
|
1374
1426
|
stages
|
|
1375
1427
|
};
|
|
1376
1428
|
}
|
|
@@ -1418,6 +1470,8 @@ function summarizeProgramPath(result) {
|
|
|
1418
1470
|
currentStep: result.currentStep,
|
|
1419
1471
|
evidenceReady: result.evidenceReady,
|
|
1420
1472
|
operating: result.operating,
|
|
1473
|
+
policyActivations: result.policyActivations,
|
|
1474
|
+
policyLibraryProposals: result.policyLibraryProposals,
|
|
1421
1475
|
stages: result.stages.map((stage) => ({
|
|
1422
1476
|
id: stage.id,
|
|
1423
1477
|
number: stage.number,
|
|
@@ -1439,6 +1493,8 @@ function nextProgramPath(result) {
|
|
|
1439
1493
|
currentStep: result.currentStep,
|
|
1440
1494
|
evidenceReady: result.evidenceReady,
|
|
1441
1495
|
operating: result.operating,
|
|
1496
|
+
policyActivations: result.policyActivations,
|
|
1497
|
+
policyLibraryProposals: result.policyLibraryProposals,
|
|
1442
1498
|
step: stage ? {
|
|
1443
1499
|
id: stage.id,
|
|
1444
1500
|
number: stage.number,
|
|
@@ -1562,6 +1618,14 @@ function summarizeProgramReadiness(result) {
|
|
|
1562
1618
|
scopeCounts: Object.fromEntries(
|
|
1563
1619
|
Object.entries(result.scope).map(([name, ids]) => [name.replace(/Ids$/, ""), ids.length])
|
|
1564
1620
|
),
|
|
1621
|
+
policyActivations: result.policyActivations.map(({ policyId, title, state, label, gapCount }) => ({
|
|
1622
|
+
policyId,
|
|
1623
|
+
title,
|
|
1624
|
+
state,
|
|
1625
|
+
label,
|
|
1626
|
+
gapCount
|
|
1627
|
+
})),
|
|
1628
|
+
policyLibraryProposals: result.policyLibraryProposals,
|
|
1565
1629
|
unresolvedOwnership: {
|
|
1566
1630
|
count: unresolvedOwnership.length,
|
|
1567
1631
|
byReason: ownershipReasons,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function openPlaceholderCount(source) {
|
|
2
|
+
if (!source) return 0;
|
|
3
|
+
const matches = source.match(
|
|
4
|
+
/\{\{[^}\n]+\}\}|\b(?:TODO|TBD)\b|\[(?:complete|confirm|describe|insert|name|replace|select|specify|todo|tbd)[^\]\n]*\]/giu
|
|
5
|
+
);
|
|
6
|
+
return matches?.length || 0;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function substantiveMarkdown(source) {
|
|
10
|
+
return (source.match(/[\p{L}\p{N}][\p{L}\p{N}'’-]*/gu) || []).length >= 10;
|
|
11
|
+
}
|
package/src/files.js
CHANGED
|
@@ -2,6 +2,7 @@ import { createHash, randomUUID } from "node:crypto";
|
|
|
2
2
|
import { constants, link, lstat, mkdir, open, readFile, rename, rm, stat } from "node:fs/promises";
|
|
3
3
|
import { basename, dirname, join, resolve } from "node:path";
|
|
4
4
|
import { getResourceDefinition, loadModel } from "../model/index.js";
|
|
5
|
+
import { openPlaceholderCount } from "./content-readiness.js";
|
|
5
6
|
import { serializeWorkspaceMutation, workspaceValidationDeferred } from "./mutation.js";
|
|
6
7
|
import { isCanonicalDataPath, resolveDataPath, resolveWorkspaceRoot } from "./paths.js";
|
|
7
8
|
import { markdownEntries } from "./resource-markdown.js";
|
|
@@ -755,6 +756,10 @@ async function prepareApprovalBinding(loaded, record, contentWrites, previousRec
|
|
|
755
756
|
throw error;
|
|
756
757
|
}
|
|
757
758
|
}
|
|
759
|
+
const placeholders = openPlaceholderCount(source);
|
|
760
|
+
if (placeholders) {
|
|
761
|
+
throw new Error(`Cannot approve or activate ${record.title} while its ${item.label} Markdown contains ${placeholders} open ${placeholders === 1 ? "placeholder" : "placeholders"}. Complete the facts and review the exact content first.`);
|
|
762
|
+
}
|
|
758
763
|
revisions[item.path] = contentRevision(source);
|
|
759
764
|
}
|
|
760
765
|
nextRecord[bindingField] = revisions;
|
package/src/index.js
CHANGED
|
@@ -51,6 +51,7 @@ export {
|
|
|
51
51
|
export { generateModelDocumentation } from "./model-docs.js";
|
|
52
52
|
export { renderMarkdown } from "./markdown.js";
|
|
53
53
|
export { migrateModel, planModelMigration } from "./model-migration.js";
|
|
54
|
+
export { activatePolicies, planPolicyActivation, scaffoldPolicyActivation } from "./policy-activation.js";
|
|
54
55
|
export {
|
|
55
56
|
completeObligationAction,
|
|
56
57
|
completeObligationEvent,
|