Policy resource
Summary of the new feature / enhancement
Looking at existing Azure policies defined in https://github.com/Azure/azure-policy/blob/master/samples/GuestConfiguration/package-samples/configurations/AzureWindowsBaseline/AzureWindowsBaseline.mof, it seems that it may be useful to have a common Policy resource that can leverage use another resource for the actual get and set, but has a way within the config to have a custom test:
Here's an example policy in mof:
instance of ASM_Registry as $ASM_Registry26ref
{
RuleId = "{a002b800-92a4-45cb-bbee-76c91739ddff}";
AzId = "AZ-WIN-00175";
BaselineId = "{982a79a8-1c46-4fdf-8cfd-60afedf7ad96}";
OriginalBaselineId = "{9c2bc3d1-8668-48e5-ac5f-281718d52174}";
Name = "Disable SMB v1 server";
Severity = "Critical";
Hive = "HKEY_LOCAL_MACHINE";
Path = "SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Parameters";
Value = "SMB1";
Type = "REG_DWORD";
ExpectedValue = "0";
RemediateValue = "0";
Remediate = true;
AnalyzeOperation = "EQUALSORNOTEXISTS";
ServerTypeFilter = "ServerType = [Domain Controller, Domain Member, Workgroup Member]";
OSFilter = "OSVersion = [WS2008, WS2008R2, WS2012, WS2012R2, WS2016]";
Enabled = true;
ResourceID = "Disable SMB v1 server";
ModuleName = "AzureOSBaseline";
ModuleVersion = "1.0";
ConfigurationName = "AzureOSBaseline";
};
Here's what it could look like in DSCv3:
name: Disable SMB v1 server
type: Microsoft.DSC/Policy
properties:
audit:
resource:
type: Microsoft.Windows/Registry
properties:
keyPath: HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters
valueName: SMB1
expected:
valueData:
DWord: 0
analyzeOperation: EqualsOrNotExist
remediation:
apply:
_exist: false
In this example if the SMB1 property exists or doesn't equal 0, then the remediation is to delete it.
Proposed technical implementation details (optional)
No response
Thinking about this, it might make sense to simplify this by having the ability to inform dsc how to perform a test could be under a meta property:
name: Disable SMB v1 server
type: Microsoft.Windows/Registry
metadata:
Microsoft.DSC:
policy:
testOperation: EqualsOrNotExist
remediation:
_exist: false
properties:
keyPath: HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters
valueName: SMB1
valueData:
DWord: 0
I think I prefer this rather than adding another group type resource. Adapters would have to advertise they support the policy (or other name) capability.
In this case, I think I disagree about group resource vs capability/metadata - this is a specific behavior to apply to other, existing resources for a specific model. I'm also not a huge fan of the remediation field in metadata/Microsoft.DSC/remediation - it splits cognition between reviewing the properties and the metadata to understand what the set operation will do.
On the other hand, I find the Microsoft.DSC/Policy[^1] resource to be very readable. I would make it slightly more explicit by requiring the remediation field to specify a resource instance (type and properties together) - I might use one resource for audit and another for remediation.
Maybe something like:
name: Disable SMB v1 server
type: Microsoft.DSC/Audit
properties:
analyzeOperation: EqualsOrNotExist
# resource sent as-is to `get`
resource:
type: Microsoft.Windows/Registry
properties:
keyPath: HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters
valueName: SMB1
# Audit resource only checks result of get against key-value pairs in expected
expected:
valueData: { DWord: 0 }
# remediation sent as-is to set
remediation:
type: Microsoft.Windows/Registry
properties:
keyPath: HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters
valueName: SMB1
_exist: false
With slightly more work on the resource side itself, the remediation field could be simplified for cases where you are using the same resource for set by merging the values:
name: Disable SMB v1 server
type: Microsoft.DSC/Audit
properties:
analyzeOperation: EqualsOrNotExist
# resource sent as-is to `get`
resource:
type: Microsoft.Windows/Registry
properties:
keyPath: HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters
valueName: SMB1
# Audit resource only checks result of get against key-value pairs in expected
expected:
valueData: { DWord: 0 }
# remediation merged on top of resource to send to set - only specify type/etc if needed.
remediation:
properties:
_exist: false
It's also worth noting that regardless of what we do for this sort of resource, we can't get purely static analysis of either instance from the JSON schema, I don't think. We could maybe do it with some clever $ref to JSON pointers (the value of expected must always adhere to the schema of the resource defined by resource) but I think it very likely that this will require runtime validation - not a bad thing, but worth keeping in mind for editors and higher order tools.
[^1]: Recommend not naming this capability or resource in DSC policy to avoid conflation with DSC settings/policy as discussed in #282.