Today I’m starting a series of blog posts where I will explore new features we have added to PowerShell PKI module, version 3.7. First post is dedicated to security descriptors.

Major changes in PSPKI

Within PSPKI module, we had an ability to manage security descriptors (access control lists) for Certification Authority can certificate template objects. Only Certification authority ACL was implemented using standard APIs provided by .NET Framework. Certificate template ACL management was implemented using pure PowerShell wrapper around Active Directory ACL object. This was done to abstract certificate template ACL management which includes very few rights (such as Read, Write, Enroll, Autoenroll) over Active Directory native ACL which includes a lot of sophisticated rights. For example, compare this simplified (and most used) ACL editor:

image

to this:

image

The list is huge and quite sophisticated. In fact, standard certificate template ACL uses later security descriptor and I doubt that anyone really uses this advanced ACL editor to manage certificate template access. In this version, we have implemented a managed wrapper around Active Directory security descriptor with only relevant pieces and left all complex work behind the scenes.

In addition to CA, certificate templates, with Online Responder addition, we’ve added managed Online Responder ACL API as well. All ACL-related objects within the module use standard and unified API and unified PowerShell cmdlets. Here are relevant APIs:

All these classes inherit and implement abstract CommonObjectSecurity class. Using this approach, we enhance and standardize our own ACL API implementation. In addition to API unification, PowerShell commands are unified as well.

Read Access Control Lists

here is a list of PS commands to read ACLs:

All these commands accept corresponding objects as input:

PS C:\> Connect-CA | Get-CertificationAuthorityAcl

Path                                    Owner                                   Access
----                                    -----                                   ------
                                        BUILTIN\Administrators                  NT AUTHORITY\Authenticated Users All...


PS C:\> Get-CertificateTemplate -Name WebServer | Get-CertificateTemplateAcl

Path                                    Owner                                   Access
----                                    -----                                   ------
                                        CONTOSO\Enterprise Admins               NT AUTHORITY\Authenticated Users All...


PS C:\> Connect-OnlineResponder | Get-OnlineResponderAcl

Path                                    Owner                                   Access
----                                    -----                                   ------
                                        BUILTIN\Administrators                  NT AUTHORITY\NETWORK SERVICE Allow  ...


PS C:\>

All access control entries are stored in Access property:

PS C:\> (Connect-OnlineResponder | Get-OnlineResponderAcl).Access


OnlineResponderRights : Read, Request
Rights                : Read, Request
AccessControlType     : Allow
IdentityReference     : NT AUTHORITY\NETWORK SERVICE
IsInherited           : False
InheritanceFlags      : None
PropagationFlags      : None

OnlineResponderRights : Manage, Read
Rights                : Manage, Read
AccessControlType     : Allow
IdentityReference     : BUILTIN\Administrators
IsInherited           : False
InheritanceFlags      : None
PropagationFlags      : None



PS C:\>

Add Access Control Entries

Use Add-*Acl commands to add new entry to ACL or add extra rights to existing access control entries and use Set-*Acl to write changes to security descriptors.

Add-*Acl only modify runtime object without committing changes to security descriptor, they are committed using Set-*Acl commands:

PS C:\> Connect-OnlineResponder | Get-OnlineResponderAcl | Add-OnlineResponderAcl -Identity "OCSP Admins" -AccessType Al
low -AccessMask "Read, Manage" | Set-OnlineResponderAcl | select -ExpandProperty Access


OnlineResponderRights : Read, Request
Rights                : Read, Request
AccessControlType     : Allow
IdentityReference     : NT AUTHORITY\NETWORK SERVICE
IsInherited           : False
InheritanceFlags      : None
PropagationFlags      : None

OnlineResponderRights : Manage, Read
Rights                : Manage, Read
AccessControlType     : Allow
IdentityReference     : BUILTIN\Administrators
IsInherited           : False
InheritanceFlags      : None
PropagationFlags      : None

OnlineResponderRights : Manage, Read
Rights                : Manage, Read
AccessControlType     : Allow
IdentityReference     : CONTOSO\OCSP Admins
IsInherited           : False
InheritanceFlags      : None
PropagationFlags      : None



PS C:\>

And reflected changes in UI:

image

Very similar syntax is used to manage Certification Authorities and certificate templates. The only difference is –AccessMask parameter which offers object-specific access rights. We’ve updated examples to reflect unified syntax and some practices. We had a case with customer where certificate template was bloated with access control entries of users, groups. The ACL was extremely huge. And due to this, CA failed to issue certificate because CA wasn’t be able to determine if requester has appropriate permissions. In all cases your ACL must be as clean as possible and use AGDLP concept and should never add principals (users or computers) directly to ACL. That is, principal accounts are added to global or universal (though, universal are not very recommended) groups, then global group is added to domain local group, say “OCSP Admins” and only domain local group is assigned appropriate permissions on the object. And when you want to add principal access to object, add it to corresponding groups. This eliminates frequent ACL change.

Certificate templates are stored in Active Directory configuration naming context which is replicated across entire forest, thus AGDLP is shortened to AGP. You should assign certificate permissions only to global groups. Permissions on CAs, Online Responders follow full AGDLP concept.

Remove Access Control Entries

Use Remove-*Acl  commands to revoke access permissions to objects or completely clear ACL from all access control entries and use Set-*Acl to write changes to security descriptors. Single principal can have multiple access rights and we can retract only all permissions assigned to entity for Allow and Deny access types. That is, specified identity is removed from ACL completely.

Remove-*Acl only modify runtime object without committing changes to security descriptor, they are committed using Set-*Acl commands.

Write Access Control List

As it was mentioned, Add-*Acl and Remove-*Acl commands change security descriptor in runtime (memory) and do not commit changes to securable’s ACL. Changes are committed after calling Set-*Acl commands:

These commands are very simple to call as they accept only security security descriptor as input parameter. Depending on a context, additional switch parameters are added to immediately apply changes. For example, ADCS Certification Authority read configuration upon service start and do not monitor changes. Thus, any changes in configuration, will become effective only when service starts next time and you need to restart the service if changes must be applied immediately.

Leave a Comment





This site uses Akismet to reduce spam. Learn how your comment data is processed.