Skip to content

Commit

Permalink
Implement data processing policy for common controls (#485)
Browse files Browse the repository at this point in the history
* bump data localization for russia policy for 15.3

* add rule sets for cc 15.2; add unit tests

* change defaultSafe to false
  • Loading branch information
mitchelbaker-cisa authored Oct 31, 2024
1 parent 670b268 commit 2b9a8bc
Show file tree
Hide file tree
Showing 3 changed files with 370 additions and 7 deletions.
311 changes: 310 additions & 1 deletion Testing/RegoTests/commoncontrols/commoncontrols15_test.rego
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,316 @@ test_AccessControl_Correct_V1 if {
}
#--

# 15.2 TODO

#
# GWS.COMMONCONTROLS.15.2v0.3
#--
test_DataProcessing_OUs_Correct_V1 if {
# Test 1 event
PolicyId := "GWS.COMMONCONTROLS.15.2v0.3"
Output := tests with input as {
"commoncontrols_logs": {"items": [
{
"id": {"time": "2024-10-20T00:02:28.672Z"},
"events": [{
"parameters": [
{"name": "NEW_VALUE", "value": "true"},
{"name": "SETTING_NAME", "value": "DataProcessingRequirementsProto limit_to_storage_location"},
{"name": "ORG_UNIT_NAME", "value": "Test Top-Level OU"},
{"name": "APPLICATION_NAME", "value": "Data regions"}
]
}]
}
]},
"tenant_info": {
"topLevelOU": "Test Top-Level OU"
}
}

RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId]
count(RuleOutput) == 1
RuleOutput[0].RequirementMet
not RuleOutput[0].NoSuchEvent
RuleOutput[0].ReportDetails == "Requirement met in all OUs and groups."
}

test_DataProcessing_OUs_Correct_V2 if {
# Test inheritance with root and sub OUs
PolicyId := "GWS.COMMONCONTROLS.15.2v0.3"
Output := tests with input as {
"commoncontrols_logs": {"items": [
{
"id": {"time": "2024-10-20T00:02:28.672Z"},
"events": [{
"parameters": [
{"name": "NEW_VALUE", "value": "true"},
{"name": "SETTING_NAME", "value": "DataProcessingRequirementsProto limit_to_storage_location"},
{"name": "ORG_UNIT_NAME", "value": "Test Top-Level OU"},
{"name": "APPLICATION_NAME", "value": "Data regions"}
]
}]
},
{
"id": {"time": "2024-10-19T00:02:28.672Z"},
"events": [{
"parameters": [
{"name": "NEW_VALUE", "value": "true"},
{"name": "SETTING_NAME", "value": "DataProcessingRequirementsProto limit_to_storage_location"},
{"name": "ORG_UNIT_NAME", "value": "Test Second-Level OU"},
{"name": "APPLICATION_NAME", "value": "Data regions"}
]
}]
}
]},
"tenant_info": {
"topLevelOU": "Test Top-Level OU"
}
}

RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId]
count(RuleOutput) == 1
RuleOutput[0].RequirementMet
not RuleOutput[0].NoSuchEvent
RuleOutput[0].ReportDetails == "Requirement met in all OUs and groups."
}

test_DataProcessing_OUs_Incorrect_V1 if {
# Test incorrect root OU
PolicyId := "GWS.COMMONCONTROLS.15.2v0.3"
Output := tests with input as {
"commoncontrols_logs": {"items": [
{
"id": {"time": "2024-10-20T00:02:28.672Z"},
"events": [{
"parameters": [
{"name": "NEW_VALUE", "value": "false"},
{"name": "SETTING_NAME", "value": "DataProcessingRequirementsProto limit_to_storage_location"},
{"name": "ORG_UNIT_NAME", "value": "Test Top-Level OU"},
{"name": "APPLICATION_NAME", "value": "Data regions"}
]
}]
}
]},
"tenant_info": {
"topLevelOU": "Test Top-Level OU"
}
}

RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId]
count(RuleOutput) == 1
not RuleOutput[0].RequirementMet
not RuleOutput[0].NoSuchEvent
RuleOutput[0].ReportDetails == concat("", [
"The following OUs are non-compliant:<ul>",
"<li>Test Top-Level OU: Data processing in the region selected for data at rest is set to OFF</li>",
"</ul>"
])
}

test_DataProcessing_OUs_Incorrect_V2 if {
# Test incorrect second-level OU
PolicyId := "GWS.COMMONCONTROLS.15.2v0.3"
Output := tests with input as {
"commoncontrols_logs": {"items": [
{
"id": {"time": "2024-10-20T00:02:28.672Z"},
"events": [{
"parameters": [
{"name": "NEW_VALUE", "value": "true"},
{"name": "SETTING_NAME", "value": "DataProcessingRequirementsProto limit_to_storage_location"},
{"name": "ORG_UNIT_NAME", "value": "Test Top-Level OU"},
{"name": "APPLICATION_NAME", "value": "Data regions"}
]
}]
},
{
"id": {"time": "2024-10-19T00:02:28.672Z"},
"events": [{
"parameters": [
{"name": "NEW_VALUE", "value": "false"},
{"name": "SETTING_NAME", "value": "DataProcessingRequirementsProto limit_to_storage_location"},
{"name": "ORG_UNIT_NAME", "value": "Test Second-Level OU"},
{"name": "APPLICATION_NAME", "value": "Data regions"}
]
}]
}
]},
"tenant_info": {
"topLevelOU": "Test Top-Level OU"
}
}

RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId]
count(RuleOutput) == 1
not RuleOutput[0].RequirementMet
not RuleOutput[0].NoSuchEvent
RuleOutput[0].ReportDetails == concat("", [
"The following OUs are non-compliant:<ul>",
"<li>Test Second-Level OU: Data processing in the region selected for data at rest is set to OFF</li>",
"</ul>"
])
}

test_DataProcessing_OUs_Groups_Incorrect_V1 if {
# Test for correct root OU but with an incorrect group event
PolicyId := "GWS.COMMONCONTROLS.15.2v0.3"
Output := tests with input as {
"commoncontrols_logs": {"items": [
{
"id": {"time": "2024-10-20T00:02:28.672Z"},
"events": [{
"parameters": [
{"name": "NEW_VALUE", "value": "true"},
{"name": "SETTING_NAME", "value": "DataProcessingRequirementsProto limit_to_storage_location"},
{"name": "ORG_UNIT_NAME", "value": "Test Top-Level OU"},
{"name": "APPLICATION_NAME", "value": "Data regions"}
]
}]
},
{
"id": {"time": "2024-10-19T00:02:28.672Z"},
"events": [{
"parameters": [
{"name": "NEW_VALUE", "value": "false"},
{"name": "SETTING_NAME", "value": "DataProcessingRequirementsProto limit_to_storage_location"},
{"name": "GROUP_EMAIL", "value": "Test Group 1"},
{"name": "APPLICATION_NAME", "value": "Data regions"}
]
}]
}
]},
"tenant_info": {
"topLevelOU": "Test Top-Level OU"
}
}

RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId]
count(RuleOutput) == 1
not RuleOutput[0].RequirementMet
not RuleOutput[0].NoSuchEvent
RuleOutput[0].ReportDetails == concat("", [
"The following groups are non-compliant:<ul>",
"<li>Test Group 1: Data processing in the region selected for data at rest is set to OFF</li>",
"</ul>"
])
}

test_DataProcessing_OUs_Groups_Incorrect_V2 if {
# Test for correct root OU but with incorrect group events
PolicyId := "GWS.COMMONCONTROLS.15.2v0.3"
Output := tests with input as {
"commoncontrols_logs": {"items": [
{
"id": {"time": "2024-10-20T00:02:28.672Z"},
"events": [{
"parameters": [
{"name": "NEW_VALUE", "value": "true"},
{"name": "SETTING_NAME", "value": "DataProcessingRequirementsProto limit_to_storage_location"},
{"name": "ORG_UNIT_NAME", "value": "Test Top-Level OU"},
{"name": "APPLICATION_NAME", "value": "Data regions"}
]
}]
},
{
"id": {"time": "2024-10-19T00:02:28.672Z"},
"events": [{
"parameters": [
{"name": "NEW_VALUE", "value": "false"},
{"name": "SETTING_NAME", "value": "DataProcessingRequirementsProto limit_to_storage_location"},
{"name": "GROUP_EMAIL", "value": "Test Group 1"},
{"name": "APPLICATION_NAME", "value": "Data regions"}
]
}]
},
{
"id": {"time": "2024-10-19T00:02:28.672Z"},
"events": [{
"parameters": [
{"name": "NEW_VALUE", "value": "false"},
{"name": "SETTING_NAME", "value": "DataProcessingRequirementsProto limit_to_storage_location"},
{"name": "GROUP_EMAIL", "value": "Test Group 2"},
{"name": "APPLICATION_NAME", "value": "Data regions"}
]
}]
}
]},
"tenant_info": {
"topLevelOU": "Test Top-Level OU"
}
}

RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId]
count(RuleOutput) == 1
not RuleOutput[0].RequirementMet
not RuleOutput[0].NoSuchEvent
RuleOutput[0].ReportDetails == concat("", [
"The following groups are non-compliant:<ul>",
"<li>Test Group 1: Data processing in the region selected for data at rest is set to OFF</li>",
"<li>Test Group 2: Data processing in the region selected for data at rest is set to OFF</li>",
"</ul>"
])
}

test_DataProcessing_OUs_Groups_Incorrect_V3 if {
# Test for both incorrect OUs and group events
PolicyId := "GWS.COMMONCONTROLS.15.2v0.3"
Output := tests with input as {
"commoncontrols_logs": {"items": [
{
"id": {"time": "2024-10-20T00:02:28.672Z"},
"events": [{
"parameters": [
{"name": "NEW_VALUE", "value": "false"},
{"name": "SETTING_NAME", "value": "DataProcessingRequirementsProto limit_to_storage_location"},
{"name": "ORG_UNIT_NAME", "value": "Test Top-Level OU"},
{"name": "APPLICATION_NAME", "value": "Data regions"}
]
}]
},
{
"id": {"time": "2024-10-19T00:02:28.672Z"},
"events": [{
"parameters": [
{"name": "NEW_VALUE", "value": "false"},
{"name": "SETTING_NAME", "value": "DataProcessingRequirementsProto limit_to_storage_location"},
{"name": "GROUP_EMAIL", "value": "Test Group 1"},
{"name": "APPLICATION_NAME", "value": "Data regions"}
]
}]
},
{
"id": {"time": "2024-10-19T00:02:28.672Z"},
"events": [{
"parameters": [
{"name": "NEW_VALUE", "value": "false"},
{"name": "SETTING_NAME", "value": "DataProcessingRequirementsProto limit_to_storage_location"},
{"name": "GROUP_EMAIL", "value": "Test Group 2"},
{"name": "APPLICATION_NAME", "value": "Data regions"}
]
}]
}
]},
"tenant_info": {
"topLevelOU": "Test Top-Level OU"
}
}

RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId]
count(RuleOutput) == 1
not RuleOutput[0].RequirementMet
not RuleOutput[0].NoSuchEvent
RuleOutput[0].ReportDetails == concat("", [
"The following OUs are non-compliant:<ul>",
"<li>Test Top-Level OU: Data processing in the region selected for data at rest is set to OFF</li>",
"</ul><br>",
"The following groups are non-compliant:<ul>",
"<li>Test Group 1: Data processing in the region selected for data at rest is set to OFF</li>",
"<li>Test Group 2: Data processing in the region selected for data at rest is set to OFF</li>",
"</ul>"
])
}
#--


#
# GWS.COMMONCONTROLS.15.3v0.3
Expand Down
63 changes: 58 additions & 5 deletions rego/Commoncontrols.rego
Original file line number Diff line number Diff line change
Expand Up @@ -1787,18 +1787,71 @@ tests contains {
}
#--


#
# Baseline GWS.COMMONCONTROLS.15.2v0.3
#--
# TODO access actual API capabilities for 15.2, the following check is a placeholder.
NonCompliantOUs15_2 contains {
"Name": OU,
"Value": "Data processing in the region selected for data at rest is set to OFF"
} if {
some OU in utils.OUsWithEvents
SettingName := "DataProcessingRequirementsProto limit_to_storage_location"
Events := utils.FilterEventsOU(LogEvents, SettingName, OU)
count(Events) > 0
LastEvent := utils.GetLastEvent(Events)
LastEvent.NewValue != "true"
LastEvent.NewValue != "DELETE_APPLICATION_SETTING"
}

NonCompliantGroups15_2 contains {
"Name": Group,
"Value": "Data processing in the region selected for data at rest is set to OFF"
} if {
some Group in utils.GroupsWithEvents
SettingName := "DataProcessingRequirementsProto limit_to_storage_location"
Events := utils.FilterEventsGroup(LogEvents, SettingName, Group)
# Ignore groups without any events.
count(Events) > 0
LastEvent := utils.GetLastEvent(Events)
LastEvent.NewValue != "true"
LastEvent.NewValue != "DELETE_APPLICATION_SETTING"
}

tests contains {
"PolicyId": "GWS.COMMONCONTROLS.15.2v0.3",
"Criticality": "Shall/Not-Implemented",
"ReportDetails": "Currently not able to be tested automatically; please manually check.",
"ActualValue": "",
"RequirementMet": false,
"Criticality": "Shall",
"ReportDetails": utils.NoSuchEventDetails(DefaultSafe, utils.TopLevelOU),
"ActualValue": "No relevant event for the top-level OU in the current logs",
"RequirementMet": DefaultSafe,
"NoSuchEvent": true
}
if {
DefaultSafe := false
SettingName := "DataProcessingRequirementsProto limit_to_storage_location"
Events := utils.FilterEventsOU(LogEvents, SettingName, utils.TopLevelOU)
count(Events) == 0
}

tests contains {
"PolicyId": "GWS.COMMONCONTROLS.15.2v0.3",
"Criticality": "Shall",
"ReportDetails": utils.ReportDetails(NonCompliantOUs15_2, NonCompliantGroups15_2),
"ActualValue": {"NonCompliantOUs": NonCompliantOUs15_2, "NonCompliantGroups": NonCompliantGroups15_2},
"RequirementMet": Status,
"NoSuchEvent": false
}
if {
SettingName := "DataProcessingRequirementsProto limit_to_storage_location"
Events := utils.FilterEventsOU(LogEvents, SettingName, utils.TopLevelOU)
count(Events) > 0

Conditions := {