@@ -1231,6 +1231,116 @@ scratch_unmount := {"metadata": [remove_scratch_mount], "allowed": true} {
12311231 }
12321232}
12331233
1234+ # Registry changes validation
1235+ default registry_changes := {" allowed" : false }
1236+
1237+ # Helper function to compare registry keys
1238+ registry_keys_match (policy_key, input_key) {
1239+ policy_key.hive == input_key.Hive
1240+ policy_key.name == input_key.Name
1241+ # Volatile field comparison (default to false if not specified)
1242+ policy_volatile := object.get (policy_key, " volatile" , false )
1243+ input_volatile := object.get (input_key, " Volatile" , false )
1244+ policy_volatile == input_volatile
1245+ }
1246+
1247+ # Helper function to compare registry values
1248+ # STRING type
1249+ registry_value_matches (policy_value, input_value) {
1250+ registry_keys_match (policy_value.key, input_value.Key)
1251+ policy_value.name == input_value.Name
1252+ policy_value.type == input_value.Type
1253+ policy_value.type == " String"
1254+ policy_value.string_value == input_value.StringValue
1255+ }
1256+
1257+ # EXPANDED_STRING type (uses StringValue field)
1258+ registry_value_matches (policy_value, input_value) {
1259+ registry_keys_match (policy_value.key, input_value.Key)
1260+ policy_value.name == input_value.Name
1261+ policy_value.type == input_value.Type
1262+ policy_value.type == " ExpandedString"
1263+ policy_value.string_value == input_value.StringValue
1264+ }
1265+
1266+ # MULTI_STRING type (uses StringValue field)
1267+ registry_value_matches (policy_value, input_value) {
1268+ registry_keys_match (policy_value.key, input_value.Key)
1269+ policy_value.name == input_value.Name
1270+ policy_value.type == input_value.Type
1271+ policy_value.type == " MultiString"
1272+ policy_value.string_value == input_value.StringValue
1273+ }
1274+
1275+ # D_WORD type
1276+ registry_value_matches (policy_value, input_value) {
1277+ registry_keys_match (policy_value.key, input_value.Key)
1278+ policy_value.name == input_value.Name
1279+ policy_value.type == input_value.Type
1280+ policy_value.type == " DWord"
1281+ policy_value.dword_value == input_value.DWordValue
1282+ }
1283+
1284+ # Q_WORD type
1285+ registry_value_matches (policy_value, input_value) {
1286+ registry_keys_match (policy_value.key, input_value.Key)
1287+ policy_value.name == input_value.Name
1288+ policy_value.type == input_value.Type
1289+ policy_value.type == " QWord"
1290+ policy_value.qword_value == input_value.QWordValue
1291+ }
1292+
1293+ # BINARY type
1294+ registry_value_matches (policy_value, input_value) {
1295+ registry_keys_match (policy_value.key, input_value.Key)
1296+ policy_value.name == input_value.Name
1297+ policy_value.type == input_value.Type
1298+ policy_value.type == " Binary"
1299+ policy_value.binary_value == input_value.BinaryValue
1300+ }
1301+
1302+ # CUSTOM_TYPE - both CustomType field and BinaryValue must match
1303+ registry_value_matches (policy_value, input_value) {
1304+ registry_keys_match (policy_value.key, input_value.Key)
1305+ policy_value.name == input_value.Name
1306+ policy_value.type == input_value.Type
1307+ policy_value.type == " CustomType"
1308+ policy_value.custom_type == input_value.CustomType
1309+ policy_value.binary_value == input_value.BinaryValue
1310+ }
1311+
1312+ # NONE type - no value to compare, just key and name
1313+ registry_value_matches (policy_value, input_value) {
1314+ registry_keys_match (policy_value.key, input_value.Key)
1315+ policy_value.name == input_value.Name
1316+ policy_value.type == input_value.Type
1317+ policy_value.type == " None"
1318+ }
1319+
1320+ # Filter input registry values to only include those that match policy
1321+ filtered_registry_values (input_values, policy_values) := [input_val |
1322+ input_val := input_values[_]
1323+ some policy_val in policy_values
1324+ registry_value_matches (policy_val, input_val)
1325+ ]
1326+
1327+ registry_changes := {" allowed" : true } {
1328+ containers := data .metadata.matches[input .containerID]
1329+ container := containers[_]
1330+
1331+ # Check if container has registry_changes defined in policy
1332+ container.registry_changes
1333+
1334+ # If input has registry changes, filter to only matching ones
1335+ input .registryChanges.AddValues
1336+ matched_values := filtered_registry_values (input .registryChanges.AddValues, container.registry_changes.add_values)
1337+
1338+ # Build result with filtered AddValues
1339+ result := {
1340+ " AddValues" : matched_values
1341+ }
1342+ }
1343+
12341344reason := {
12351345 " errors" : errors,
12361346 " error_objects" : error_objects
0 commit comments