The TameMyCerts policy module for Microsoft Active Directory Certificate Services

1 What is TameMyCerts and why would you need it?

TameMyCerts is a policy module for Microsoft Active Directory Certificate Services (AD CS) enterprise certification authorities that enables security automation for a lot of use cases in the PKI field.

It is developed in germany by PKI expert Uwe Gradenegger (https://www.gradenegger.eu/), with contributions from all over the world.

The module supports, amongst other functions, inspecting certificate requests for certificate templates that allow the subject information to be specified by the enrollee against a defined policy. If any of the requested identities violates the defined rules, the certificate request automatically gets denied by the certification authority. Requested identities can also be mapped against Active Directory to apply restrictions based on group memberships, or even to pull certificate content from AD.

Therefore, the TameMyCerts policy module for Microsoft Active Directory Certificate Services helps you to tame your certs! It has already proven itself in countless productive deployments of enterprise-grade scale.

TameMyCerts is Open Source Software. Find it on GitHub (https://github.com/Sleepw4lker/TameMyCerts).

For enterprise deployments, commercial support and maintenance agreements are being offered as well.

1.1 The need for a policy module

Enterprises in a modern, digitalized, highly connected world strongly rely on digital certificates. Certificates are used for a variety of use cases like…

  • Authentication to on-premises or cloud resources.
  • Enabling remote access for users for them to be able to work remotely from anywhere, with any kind of device.
  • Securing web-based transactions.
  • Ensuring authenticity in electronic document workflows.

Organizations around the world rely on Microsoft Active Directory Certificate Services (AD CS) (https://learn.microsoft.com/en-us/windows-server/identity/ad-cs/active-directory-certificate-services-overview) for issuing digital certificates within their Microsoft identity ecosystem. Microsoft AD CS is a suite of roles provided by the Microsoft Windows Server operating system. Its main role is the certification authority (CA), which is responsible for processing certificate requests and issuing digital certificates.

The core of a digital certificate is the identity it provides. A CAs main responsibility is to verify and attest the enrollees identity. Trusting a certification authority means trusting the content of the digital certificates it is issuing and the identities it attests.

1.2 Online and offline certificate templates

AD CS uses the concept of certificate templates to define rules that shall be applied to incoming certificate requests and issued certificates.

AD CS knows of two kinds of certificate templates and requests:

  • Online certificate templates and requests: Identities in the issued certificate are determined by the certification authority, based on information on the enrollee which is pulled from Active Directory.
  • Offline certificate templates and requests: Identities in the issued certificate are provided by the enrollee during the enrollment process. The certification authority has no control over it, allowing enrollees to virtually request any identity from the CA and thus putting the environment at risk for identity spoofing.

The fact whether a certificate template qualifies as online or offline derives from the settings within the “Subject” tab of the certificate template settings.

Online certificate template
Offline certificate template

AD CS was originally designed around the Microsoft Active Directory ecosystem and as such to heavily rely on online certificate templates for authentication of enrollees and ensuring their identities.

However, many modern use cases require switching the certification authority to use offline certificate templates, where the certification authority has no control over the issued certificates content. This opens up a large surface for various attacks against the certification authority. In a worst case, the entire Active Directory environment of a company could be compromised because of an abused certification authority or certificate template (refer to https://posts.specterops.io/certified-pre-owned-d95910965cd2 for further details).

1.3 Policy modules

AD CS uses on the concept of policy modules (https://learn.microsoft.com/en-us/windows/win32/seccrypto/certificate-services-architecture) to determine if a certificate shall be issued. A policy module is a piece of software that is loaded into the certification authority process on start-up of the CA service. Think of it as a plug-in.

A policy module for AD CS has two main purposes:

  • Modify content of issued certificates, such as determining the Subject Distringuished Name (DN) and adding extensions to an issued certificate.
  • Decide whether a certificate request shall be issued, put into pending state, or get denied.
How a policy module is integrated into AD CS’ functionality (© Microsoft)

Microsoft designed AD CS in a way so that custom policy modules could be developed by individual contributors to enhance the provided functionality. TameMyCerts is such a policy module, which allows to extend the functionality that is provided by AD CS. Unique about TameMyCerts is that it is made available to the public via a free license.

1.4 Use Cases for the TameMyCerts policy module

Refer to the Typical use cases for the TameMyCerts policy module chapter in the Appendix section of the document to learn more on typical use cases where TameMyCerts can add value.

1.5 How TameMyCerts works

The caveat in developing a custom policy module is that there can only be one module active at a time. Usually this means that all the functionality of the Windows Default policy module would have to be re-implemented by the custom module, which is complex and prone to errors.

TameMyCerts solves the issue: It shims the Windows Default policy module, which means all the original functionality is preserved, but additional checks can be performed afterwards.

TameMyCerts passes incoming certificate requests to the Windows Default policy module and only gets active afterwards, if a configuration has been made. This means all certificate templates that don’t have a policy configuration file specified are completely left untouched and behave exactly as without having TameMyCerts installed.

Approval flow of TameMyCerts

This approach was adopted from a code sample that initially was published by Microsoft (a mirror can be found at https://github.com/Sleepw4lker/capolmod) and is in alignment with their recommendations for the development of custom policy modules (https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2003/cc783853(v=ws.10)#certificate-services-architecture).

1.5.1 How TameMyCerts applies its rules to certificate requests

You configure your certificate templates as usual. You then define your rules in eXtended Markup Language (XML) files, one per certificate template you want to “tame”. During installation, you point TameMyCerts to the path where it shall search for your configuration files. If there is no configuration file defined for a given certificate template, TameMyCerts does not apply any additional logic, thus preserving the original behavior of the Windows Default policy module.

2 Prerequisites

TameMyCerts is intended to be installed on a server with the Certification Authority role installed.

2.1 Supported certification authority modes

The following modes for the certification authority role are supported by TameMyCerts:

CA mode Support status
Enterprise Root supported
Enterprise Issuing supported
Standalone Root not supported
Standalone Issuing not supported

2.2 Supported operating systems

The module was successfully tested and is supported with the following operating systems:

  • Microsoft Windows Server 2025
  • Microsoft Windows Server 2022
  • Microsoft Windows Server 2019
  • Microsoft Windows Server 2016

Other Microsoft Windows Server operating systems may work but are not supported.

2.3 Software prerequisites

TameMyCerts requires the .NET Desktop Runtime 8.0 (https://dotnet.microsoft.com/en-us/download/dotnet/8.0).

3 Installing the TameMyCerts policy module

Ensure that the prerequisites are being met by the destination machine prior to installing TameMyCerts.

If you signed up for a maintenance contract, you get a ZIP file containing the module binary as well as an installer script and some example configuration files to get you started.

To install the module, first create a directory on the certification authority where you intend to store the policy configuration files.

Policy directory for TameMyCerts

Then run install.ps1 as local Administrator. The script will register the module, create the required registry values and configure the policy module as the active one for the certification authority.

The installation script restarts the certification authority service during installation and uninstallation.

You must specify the -PolicyDirectory Parameter which specifies the local path for the XML configuration files you define for each certificate template.

Example:

.\install.ps1 -PolicyDirectory C:\PolicyFiles
Installing TameMyCerts

Afterwards, TameMyCerts is automatically enabled as the active policy module, which can be reviewed in the properties dialog of the certification authority in the certification authority management console (certsrv.msc).

TameMyCerts is now the active policy module

As the policy module daisy-chains the Windows default policy module, it also uses all of its registry settings. Therefore, the install script copies this data from the Windows Default module registry key to a new one for the TameMyCerts policy module. Each change you perform with certutil commands that would configure the Windows Default policy module is now written to the TameMyCerts policy module registry key. Should you decide to uninstall it later on, use the provided installer script as well to ensure the settings get copied back so that they stay consistent.

3.1 Upgrading from a previous version

The process of upgrading from a previous version is the same as installing the module. Simply proceed as you would install TameMyCerts for the first time.

Depending on the version you previously used, it may be necessary to adjust your policy configuration files. Refer to the upgrade instructions in the Technical Reference section of the document.

3.2 Uninstalling the TameMyCerts policy module

To uninstall the module, run install.ps1 as Administrator. You must specify the -Uninstall parameter.

The installation script restarts the certification authority service during installation and uninstallation.

Example:

.\install.ps1 -Uninstall
Uninstalling TameMyCerts

The script will unregister the module, copy the registry settings back and configure the Windows Default policy module as the active one.

4 Configuring the TameMyCerts policy module

The TameMyCerts policy module uses eXtended Markup Language (XML) files to describe what shall be done with incoming certificate requests for a given certificate template. This approach has the benefit that changes can easily be tracked with version control systems like Git and annotated with inline comments.

4.1 Creating a policy configuration file

Create a policy configuration file in XML format for each certificate template you want to apply a policy for in the folder you specified during Installing the TameMyCerts policy module.

Policy directory for TameMyCerts

Please ensure the file is encoded as UTF-8 if you plan to support special characters like german “Umlauts”.

Name the file exactly as the certificate template (“cn” LDAP attribute) that shall get examined.

For example, if your certificate template is named “TameMyCertsWebServer”, you create a policy configuration file named “TameMyCertsWebServer.xml”. You can get the object name of the certificate template from the certificate template management console or via Windows PowerShell.

Note that certificate template names allow several characters that are not valid for file names (e.g. “<>|*?\/). If you have such a template, simply omit these characters when naming the file.

Getting the certificate template name from the certificate template management console (in the “Change Names” option of the certificate template)
Getting the certificate template name from the certification authority PowerShell

Each policy configuration file starts with a basic definition of a CertificateRequestPolicy as shown below:

<CertificateRequestPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <!-- Directives go here -->
</CertificateRequestPolicy>

The distribution package of TameMyCerts contains various example files (https://github.com/Sleepw4lker/TameMyCerts/tree/main/examples) to get started with the most common use cases.

The policy configuration files get loaded when an incoming certificate request is processed. Therefore it is not necessary to restart the certification authority service after a policy configuration file has been created or changed. As long as the configuration file does not change, subsequent certificate requests for the same certificate template will be served from an internal cache.

If TameMyCerts is not able to parse the policy configuration file (e.g. because of a syntax error), the certificate request gets denied and an entry is written into the servers event log, pointing to the possible cause of the issue.

You can now configure the file as desired. Some of the settings described in subsequent chapters apply only to offline requests and will have no effect when configured for online certificate templates.

4.1.1 Examples

A basic policy configuration file that restricts all certificate request for a given offline certificate template to having a commonName of “Hello World”, and nothing else. All certificate requests that do not comply with these settings will get denied.

<CertificateRequestPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Subject>
    <SubjectRule>
      <Field>commonName</Field>
      <Mandatory>true</Mandatory>
      <Patterns>
        <Pattern>
          <Expression>^Hello World$</Expression>
        </Pattern>
      </Patterns>
    </SubjectRule>
  </Subject>
</CertificateRequestPolicy>

4.2 Global settings

TameMyCerts supports the following flags to modify global (affecting request processing regardless of template configuration) behavior.

Flag Numerical value Description
TMC_DENY_IF_NO_POLICY 0x1 Denies certificate request in case there is no policy configuration defined. Note that this causes the certification authority to globally deny all certificate requests by default until a policy configuration has been defined the published certificate templates (“failure-close” configuration).
TMC_WARN_ONLY_ON_INSECURE_FLAGS 0x2 Causes the policy module to not deny a certificate request when it contains the “san” request attribute and the EDITF_ATTRIBUTESUBJECTALTNAME2 flag has been enabled on the certification authority. Refer to section Denying certificate requests for insecure combinations for more information. It is recommended to not enable this flag.
TMC_DONT_RESOLVE_NESTED_GROUP_MEMBERSHIPS 0x4 Instructs Directory Services Mapping to not resolve nested Group Memberships using the use the msds-TokenGroupNames (https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/1d810083-9741-4b0a-999b-30d9f2bc1f95) Active Directory Attribute.

4.2.1 Configuring

Flags can be combined with each other.

To enable one or more flags, enter the following commands into an elevated (“run as Administrator”) command prompt (the example uses the TMC_DENY_IF_NO_POLICY flag with numerical value of 0x1, adjust to your needs):

certutil -setreg Policy\TmcFlags +0x1

To disable a flag, enter the following commands into an elevated (“run as Administrator”) command prompt (the example uses the TMC_DENY_IF_NO_POLICY flag with numerical value of 0x1, adjust to your needs):

certutil -setreg Policy\TmcFlags -0x1

As registry settings are applied on service startup, the certification authority service must be restarted for the settings to apply after a change.

net stop certsvc
net start certsvc

4.3 Audit only mode

Applies to online and offline certificate templates.

TameMyCerts supports an Audit-only mode, in which certificate requests get allowed regardless of the verification result. This helps by sharpending policies before applying them to existing deployments. If a certificate request would be denied in regular mode, TameMyCerts will log this to the event log of the certification authority to allow administrators further research.

Also refer to the How it works section to get an understanding of the verification flow.

Audit only mode is enabled for this certificate template. Policy violations will get logged, but the certificate will get issued.

4.3.1 Configuring

You enable Audit only mode by configuring the AuditOnly directive.

<AuditOnly>true</AuditOnly>

4.4 Configuring rules for the key pair of a CSR

Applies to online and offline certificate templates.

The “Windows Default” policy is only capable to enforce a minimum key length, but not the key algorithm and not the maximum key length to be used. This may lead to issuance of certificates using weak keys, e.g. when submitting a request using a small RSA key to a certificate template that is configured to use an ECC key.

A certificate request violating key rules was denied by TameMyCerts

4.4.1 Configuring

You can specify the following parameters for the private key:

The MinimumKeyLength directive specifies the minimum key length the certificate request must use. Defaults to “0” (any key size is allowed). Though the Windows Default policy module also verifies this, this may become handy in a migration scenario where you publish the same template both on the old and new certification authority and plan to increase key size when switching to the new one whilst keeping the productive system unchanged.

The MaximumKeyLength directive specifies the maximum key length the certificate request can use. Defaults to “0” (any key size is allowed).

The key algorithm is automatically determined based on the settings of the used certificate template and is enforced automatically.

4.4.2 Examples

Key size must exactly be 384 bits, assuming the certificate template uses an ECC key and specifies a minimum key size of 384 bits (thus minimum and maximum key size are equal).

<MaximumKeyLength>384</MaximumKeyLength>

Key size must exactly be 384 bits, assuming the certificate template uses an ECC key and specifies a lower key size.

<MinimumKeyLength>384</MinimumKeyLength>
<MaximumKeyLength>384</MaximumKeyLength>

Key size must be between 2048 and 4096 bits, assuming the certificate template uses an RSA key and specifies a lower key size.

<MinimumKeyLength>2048</MinimumKeyLength>
<MaximumKeyLength>4096</MaximumKeyLength>

4.5 Configuring rules to restrict cryprographic providers creating a CSR

Applies to online and offline certificate templates.

Certificate requests can contain information about which cryptographic provider (https://www.gradenegger.eu/en/basics-cryptographic-service-provider-csp-and-key-storage-provider-ksp/) was used to create the key pair. This information can be used to apply a policy which providers are permitted to get a certificate issued and which are not.

Please be aware that only certificate requests that have been made with the Microsoft API (e.g. Autoenrollment, MMC, certreq, PSCertificateEnrollment (https://www.powershellgallery.com/packages/PSCertificateEnrollment) and similar apps) will contain information about the provider that was used to create the certificate request.

Please be also aware that the provider information may potentially be manipulated by the enrollee during the request creation process. Therefore, this method is less secure than serious attestation methods for TPMs (https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/component-updates/tpm-key-attestation) or Smartcards.

A certificate request using a disallowed cryprographic provider was denied by TameMyCerts
A certificate request using a cryprographic provider that is not whitelisted was denied by TameMyCerts

4.5.1 Configuring

The AllowedCryptoProviders directive contains a list of one or more Cryptographic Service Provider (CSP) or Key Storage Provider (KSP) names that are permitted for the creation of the certificate requests private key. For example, you could configure a certificate template to use the machines Trusted Platform Module (TPM) by specifying the Microsoft Platform Crypto Provider and a fallback to the Microsoft Software Key Storage Provider, whereas the policy for TameMyCerts would only permit requests for the Microsoft Platform Crypto Provider to be issued. This way, you could identify machines where the TPM is in a nonfunctional state by evaluating denied certificate requests.

The DisallowedCryptoProviders directive contains a list of one or more Cryptographic Service Provider (CSP) or Key Storage Provider (KSP) names that are disallowed for the creation of the certificate requests private key.

Configured values are processed case-insensitive.

Key Storage Providers shipped with Windows include:

  • Microsoft Passport Key Storage Provider
  • Microsoft Platform Crypto Provider
  • Microsoft Smart Card Key Storage Provider
  • Microsoft Software Key Storage Provider

Cryptographic Service Provider shipped with Windows include:

  • Microsoft Base Cryptographic Provider v1.0
  • Microsoft Base DSS and Diffie-Hellman Cryptographic Provider
  • Microsoft Base DSS Cryptographic Provider
  • Microsoft Base Smart Card Crypto Provider
  • Microsoft DH SChannel Cryptographic Provider
  • Microsoft Enhanced Cryptographic Provider v1.0
  • Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider
  • Microsoft Enhanced RSA and AES Cryptographic Provider
  • Microsoft RSA SChannel Cryptographic Provider
  • Microsoft Strong Cryptographic Provider

4.5.2 Examples

Some providers are whitelisted and all others are forbidden:

<AllowedCryptoProviders>
  <string>Microsoft Platform Crypto Provider</string>
  <string>Microsoft Software Key Storage Provider</string>
</AllowedCryptoProviders>

Some providers are blacklisted and all others are allowed:

<DisallowedCryptoProviders>
  <string>Microsoft Platform Crypto Provider</string>
</DisallowedCryptoProviders>

4.6 Configuring rules to restrict processes creating a CSR

Applies to online and offline certificate templates.

Certificate requests can contain information about which process was used to create the key pair. This information can be used to apply a policy which processes are permitted to get a certificate issued and which are not (e.g. you want to allow only Autoenrollment but not manually requesting a certificate).

Please be aware that only certficate requests that have been made with the Microsoft API (e.g. Autoenrollment, MMC, certreq, PSCertificateEnrollment (https://www.powershellgallery.com/packages/PSCertificateEnrollment) and similar apps) will contain information about the process that was used to create the certificate request.

Please be also aware that the process information may be manipulated by the enrollee during the request creation process. This is therefore an enforcement on a best-effort basis.

Reading the process names from the certificate request requires parsing the inline certificate request from the certification authority database. There are rare cases where this might fail. Should this happen, the process name is treated as nonexistent, which will lead to the request being denied if a proces rule is configured for the certificate template.

A certificate request using an unapproved process was denied by TameMyCerts (the users perspective)
A certificate request using an unapproved process was denied by TameMyCerts

4.6.1 Inspecting a certificate request for the process name

A certificate request can be inspected for the required process information by dumping it with the certutil command.

certutil -dump <request-file-name>
This certificate request contains process information

4.6.2 Configuring

The AllowedProcesses directive contains a list of one or more process names that are permitted to get a certificate issued. For example, if you would like to restrict certificate enrollment for a certificate template to Autoenrollment only, you would permit “taskhostw.exe”.

The DisallowedProcesses directive contains a list of one or more process names that are disallowed to get a certificate issued. For example, if you would like to deny certificate enrollment via certreq.exe, you could enter it here.

Though both directives can be used at the same time, it is recommended to only use either AllowedProcesses or DisallowedProcesses in a policy.

Commonly used process names could be:

Process name Description
taskhostw.exe Windows Autoenrollment
mmc.exe Manual certificate enrollment with the Microsoft Management Console (MMC)
certreq.exe Manual or scripted certificate enrollment with certreq.exe
powershell.exe Manual or scripted certificate enrollment with a PowerShell module like PSCertificateEnrollment (https://www.powershellgallery.com/packages/PSCertificateEnrollment)

Configured values are processed case-insensitive.

4.6.3 Examples

This configuration ensures that a certificate can only be requested via Windows AutoEnrollment (which is triggered by the Task Scheduler process, taskhostw.exe).

<AllowedProcesses>
  <string>taskhostw.exe</string>
</AllowedProcesses>

This configuration blacklists some common processes, but allows all others:

<DisallowedProcesses>
  <string>mmc.exe</string>
  <string>powershell.exe</string>
  <string>certutil.exe</string>
</DisallowedProcesses>

4.7 Configuring rules for the Subject Distinguished Name of a CSR

Applies only to offline certificate templates.

TameMyCerts allows to take control about which certificate content can be requested via an “offline” certificate template.

You can apply the following rules:

  • Ensure that a specific field is present in the Subject DN.
  • Ensure that a specific field is present only a specified number of times (usually once).
  • Ensure that a specific field contains a value, or that the value does not exceed a specific length.
  • Allow optional fields in the Subject DN (but not enforce them).
  • Ensure that a specific field conforms to one or more regular expression.
  • Ensure that a specific field conforms to one or more Classless Inter-Domain Routing (CIDR) mask ,if the field content is an Internet Protocol (IP) address.
A certificate request not containing required fields and containing forbidden fields was denied by TameMyCerts
A certificate request triggering blacklisted words was denied by TameMyCerts
A certificate request violating syntax rules was denied by TameMyCerts

4.7.1 Configuring

Rules for Subject RDNs get specified within a SubjectRule node under Subject section.

Any Subject RDN that is not defined is considered forbidden and will result in any certificate request containing it getting denied.

A SubjectRule can/must contain the following nodes:

Parameter Mandatory Description
Field yes Specifies the type of the certificate field. See the below list for possible values. Please be aware that this parameter is interpreted case-sensitive.
Mandatory no Specifies if this field must (true) or may (false) appear in the certificate request presented. Defaults to false.
MaxOccurrences no Specifies how often this field may appear within a certificate request. Should be 1 for most Subject RDN types. Defaults to 1. Note that more than one field of same type can only be used when the ReadSubjectFromRequest directive is set to true.
MinLength no Specifies the minimum amount of characters the field must contain, to avoid empty RDNs being requested. Defaults to 1. Note that you also can define minimum lengths for parts or the entire field content via regular expressions in the Patterns directive.
MaxLength no Specifies the maximum amount of characters the field may contain. Defaults to 128. Note that there is also an upper limit set by the certification authority (https://learn.microsoft.com/en-us/windows/win32/seccrypto/name-properties). Also note that you also can define maximum lengths for parts or the entire field content via regular expressions in the Patterns directive.
Patterns yes For any field type you can define one or more Pattern directives describing expressions of which the requested field content must match at least one of to get either permitted or denied. The node is required, so if you would want to allow any content, simply configure a Pattern directive with ^.*$ as expression. For instructions on how to configure the Patterns directive, consult the Pattern section within the Technical Reference chapter of this document.

To define a policy for one or more subject Relative Distinguished Name (RDN) types, adjust the “field” to one of the following (as defined in ITU-T X.520 (https://www.itu.int/itu-t/recommendations/rec.aspx?rec=X.520) and IETF RFC 4519 (https://datatracker.ietf.org/doc/html/rfc4519#section-2)).

Each RDN type can only be defined once in a policy definition file! Though you may specify that a certificate request contains more than one RDN of the same type, you would have to specify the criteria for all of them in the same rule. It is advised to allow each RDN type only once in a certificate request.

The following RDN types are enabled/allowed by default on AD CS and are therefore useable with TameMyCerts:

  • countryName
  • commonName
  • domainComponent
  • emailAddress
  • organizationName
  • organizationalUnitName
  • localityName
  • stateOrProvinceName

The following RDNs can additionally be defined in a policy configuration but must explicitly be enabled in the certification authority configuration by modifying its SubjectTemplate registry value (https://learn.microsoft.com/en-us/windows/win32/seccrypto/name-properties):

  • givenName
  • initials
  • surname
  • streetAddress
  • title
  • unstructuredName
  • unstructuredAddress
  • serialNumber

Please be aware that the SubjectTemplate registry value of the CA uses a different syntax for field type names than AD CS does.

Under certain circumstances, it is also possible to modify the Subject Distinguished Name (DN) using values from a mapped Active Directory object or from static values.

4.7.2 Examples

Incoming requests must contain exactly one commonName which must be a DNS-Name beneath the tamemycerts.com Domain. The whole content may not be longer than 64 characters in total.

<Subject>
  <SubjectRule>
    <Field>commonName</Field>
    <Mandatory>true</Mandatory>
    <MaxLength>64</MaxLength>
    <Patterns>
      <Pattern>
        <Expression>^[-_a-zA-Z0-9]*\.tamemycerts\.com$</Expression>
      </Pattern>
    </Patterns>
  </SubjectRule>
</Subject>

Incoming requests must contain exactly one commonName which must be a DNS-Name beneath the tamemycerts.com Domain. The whole content may not be longer than 64 characters in total. It may not contain the blacklisted words “porn” or “gambling”.

<Subject>
  <SubjectRule>
    <Field>commonName</Field>
    <Mandatory>true</Mandatory>
    <MaxLength>64</MaxLength>
    <Patterns>
      <Pattern>
        <Expression>^[-_a-zA-Z0-9]*\.tamemycerts\.com$</Expression>
      </Pattern>
      <Pattern>
        <Expression>^.*(porn|gambling).*$</Expression>
        <Action>Deny</Action>
      </Pattern>
    </Patterns>
  </SubjectRule>
</Subject>

Incoming requests must contain exactly one commonName which must be a DNS-Name beneath the tamemycerts.com Domain. It also may contain exactly one countryName but if so, it must be “DE” or “US”.

<Subject>
  <SubjectRule>
    <Field>commonName</Field>
    <Mandatory>true</Mandatory>
    <MaxLength>64</MaxLength>
    <Patterns>
      <Pattern>
        <Expression>^[-_a-zA-Z0-9]*\.tamemycerts\.com$</Expression>
      </Pattern>
    </Patterns>
  </SubjectRule>
  <SubjectRule>
    <Field>countryName</Field>
    <Mandatory>false</Mandatory>
    <Patterns>
      <Pattern>
        <Expression>^(DE|US)$</Expression>
      </Pattern>
    </Patterns>
  </SubjectRule>
</Subject>

4.7.3 Optional: Working with non-Standard Relative Distinguished Names

You should use this only if there is a definitve requirement to do so. Avoid using it in any other case.

Processing certificate requests with RDNs that are not part of the default set requires enabling the CRLF_REBUILD_MODIFIED_SUBJECT_ONLY flag (https://www.gradenegger.eu/en/use-of-undefined-relative-distinguished-names-rdn-in-issued-certificates/) on the certification authority, which should be used with extreme caution.

A common use case for this feature is supporting the requirements of the eIDAS regulation (https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:32014R0910) in form of adding an organization identifier (OI) to a certificate request and thus to an issued certificate.

This mode may have trouble with malformed certificate requests.

By default, TameMyCerts will use the data from the record provided by the certification authority (“how the certificate would get issued”) to analyze the Subject Distinguished Name. This allows for best compatibility and security, but has its drawbacks. The certification authority design assumes that there is only a specific set of field types and that there is only one per type.

If you have the need to inspect Subject Relative Distinguished Names that are not part of the default set, you can instruct TameMyCerts to parse the Subject Distinguished Name from the original certificate request (“how the certificate was originally requested”) by setting the ReadSubjectFromRequest directive.

<ReadSubjectFromRequest>true<ReadSubjectFromRequest>

Now, the following additional RDNs can be used in a subject rule:

  • postalCode
  • description
  • postOfficeBox
  • telephoneNumber
  • any other “unknown” (not part of the standard set or described above) RDN can be specified in a subject rule by using its object identifier (OID). The OID must be specified with an “OID.” prefix, e.g. OID.1.2.3.4.
Using undefined RDNs with TameMyCerts

4.8 Configuring rules for Subject Alternative Names of a CSR

Applies only to offline certificate templates.

4.8.1 Configuring

Rules for the Subject Alternative Name (SAN) get specified within a SubjectRule node under SubjectAlternativeName section. The syntax and logic for the SubjectRule is the exact same as for Rules for the Subject Distinguished Name (Subject DN).

To define a policy for one or more subject alternative name (SAN) type, adjust the Field to one of the following (as defined in IETF RFC 5280 (https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.6).

  • dNSName
  • iPAddress
  • rfc822Name
  • uniformResourceIdentifier
  • userPrincipalName

Other SAN types are currently not supported. However, the ones that are supported should be sufficient for the majority of use cases.

Under certain circumstances, it is also possible to supplement DNS Names and IP Addresses from the Subject Distinguished Name into the Subject Alternative Name extension.

4.8.2 Examples

Incoming requests may contain exactly one userPrincipalName, but if present, it must be beneath the tamemycerts.com Domain.

<SubjectAlternativeName>
  <SubjectRule>
    <Field>userPrincipalName</Field>
    <!-- other directives have been left out for simplicity -->
    <Patterns>
      <Pattern>
        <Expression>^[-_a-zA-Z0-9\.]*\@tamemycerts\.com$</Expression>
      </Pattern>
    </Patterns>
  </SubjectRule>
</SubjectAlternativeName>

4.9 Supplementing DNS names and IP addresses

Applies only to offline certificate templates.

IETF RFC 2818 (https://www.rfc-editor.org/rfc/rfc2818) states that identities in certificates intended to be used with HTTP over TLS (aka HTTPS) shall get presented in form of one or more entries of type dNSName in the Subject Alternative Name. It is deprecated and discouraged to use the commonName field in the Subject Distinguished Name for this purpose. Google started to enforce the IETF RFC in 2019, so any browser that is based on Chromium (e.g. Chrome, Edge, Opera) will distrust HTTPS certificates that dont contain a Subject Alternative Name. Other recent browsers behave in a similar manner.

Sadly, some applications are still unable to generate appropriate certificate requests. The feature for supplementing DNS names allows to transfer all DNS names or IP addresses that are found in the commonName of a certificate request into a Subject Alternative Name certificate extension (either adding to an existing or creating a newly-constructed one). Therefore, non-compliant certificate requests are automatically made compliant.

Supplementing DNS names with TameMyCerts

4.9.1 Configuring

Enabling this feature will also mean you will have to make the commonName mandatory in your policy under rules for the Subject Distinguished Name of a CSR.

You enable the feature by configuring SupplementDnsNames directive.

<SupplementDnsNames>true</SupplementDnsNames>

By default, TameMyCerts will supplement both qualified (e.g. host.domain.tld) and unqualified DNS names (e.g. host). You can suppress supplementation of unqialified names by setting the SupplementUnqualifiedNames to false.

<SupplementDnsNames>true</SupplementDnsNames>
<SupplementUnqualifiedNames>false</SupplementUnqualifiedNames>

4.9.2 Examples

This configuration accepts certificate requests with a commonName and dNSName within the tamemycerts.com DNS domain. Whilst the commonName field is mandatory, the dNSName field is optional. Should the request not contain a SAN in form of a dNSName, the value within the commonName will be used to create a SAN extension containing it in form of a dNSName.

<Subject>
  <SubjectRule>
    <Field>commonName</Field>
    <Mandatory>true</Mandatory>
    <Patterns>
      <Pattern>
        <Expression>^[-_a-zA-Z0-9]*\.tamemycerts\.com$</Expression>
      </Pattern>
    </Patterns>
  </SubjectRule>
</Subject>
<SubjectAlternativeName>
  <SubjectRule>
    <Field>dNSName</Field>
    <Mandatory>false</Mandatory>
    <Patterns>
      <Pattern>
        <Expression>^[-_a-zA-Z0-9]*\.tamemycerts\.com$</Expression>
      </Pattern>
    </Patterns>
  </SubjectRule>
</SubjectAlternativeName>
<SupplementDnsNames>true</SupplementDnsNames>

4.10 Configuring a fixed expiration date for all issued certificates

Applies to online and offline certificate templates.

TameMyCerts allows to configure certificates issued for a specific certificate template to expire at an exactly configured point in time. This can be useful in scenarios where you want to ensure that e.g. certificates with weak keys get phased out until a specified point in time.

The behavior is as follows:

  • If the configured expiration date exceeds the regular certificate expiration date as configured in the certificate template (or certificate authority), no change is made to the issued certificate.
  • If the configured expiration date has not yet passed but is less than the regular expiration date as configured in the certificate template (or certifificate authority), the expiration date is set to the configured point in time.
  • If the configured expiration date has passed, certificate requests for the given certificate template get denied.
The expiration date has passed and all certificate requests get denied

4.10.1 Configuration

You configure the expiration date with the NotAfter directive in your policy configuration file.

The time gets specified as an ISO 8601 compliant string in the following syntax:

'yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffzzz'

See the original Microsoft documentation (https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings) for further explanation.

4.10.2 Examples

All certificates will expire on Dec 31, 2022 23:59:59 Europe/Berlin (UTC+1) time. After that date has passed, all certificate requests for this template get denied.

<NotAfter>2022-12-31T23:59:59.0000000+01:00</NotAfter>

4.11 Configuring directory services mapping

Applies to online and offline certificate templates.

Directory Services mapping allows you to map an identity in a certificate request back to an Active Directory object. This way, a variety of policies can be applied, containing:

A certificate request for a user not being member of any allowed group was denied by TameMyCerts
A certificate request for a non-existing user was denied by TameMyCerts
A certificate request for an account residing in the wrong OU was denied by TameMyCerts
A certificate request for a disabled account was denied by TameMyCerts

4.11.1 Configuring

When using DS mapping with an offline certificate template, Directory Services mapping setting get processed after Rules for the Subject Distinguished Name (Subject Distinguished Name) and Rules for the Subject Alternative Name (SAN), so ensure you have these configured as well.

Note that for Directory Services mapping to work properly, the certification authority server must be member of the Built-in Pre-Windows 2000 Compatible Access security group. By default, certification authorities are implicitly members of this group via their membership in the Cert Publishers security group.

Rules for Directory Mapping get specified within the DirectoryServicesMapping node.

When using an online certificate template, the object category as well as certificate and directory services attributes are determined automatically.

When using an offline certificate template, the certificate attribute that was chosen for DS mapping is mandatory to occur in the certificate request and must occur only once. Ensure this via an appropriate Subject rules or Subject Alternative Name rules.

TameMyCerts is only able to map exactly one of the requested identities to an Active Directory object. Usually a certificate request contains multiple fields that can be used as identity (e.g. commonName and userPrincipalName). Which field of the issued certificate is used by to determine the certificate holders identity depends on the verifying application. You should therefore overwrite other identites by either modifying the Subject DN or the Subject Alternative Name with values from Active Directory (e.g. map userPrincipalName and overwrite commonName from the mapped Active Directory object to ensure strict rule enforcement.

Parameter Mandatory Description
Action no Specifies what should happen with the certificate request in case a matching object was found in the directory. Can be Allow or Deny. Defaults to Allow.
CertificateAttribute no The field which is taken from the certificate request as the identity to map to a corresponding Active Directory object. May contain any identity that is listed above for either the Subject Distinguished Name, or for the Subject Alternative Name. Defaults to userPrincipalName. Automatically determined for online certificate templates.
DirectoryServicesAttribute no The attribute of the Active Directory object that must match the certificate attribute. May be cn, name, sAMAccountName, userPrincipalName or dNSHostName. Defaults to userPrincipalName. Automatically determined for online certificate templates.
ObjectCategory no The category of the Active Directory object to be searched for. May be computer or user. Defaults to user for offline certificate templates. Automatically determined for online certificate templates.
SearchRoot no The distinguished name of the LDAP path the search for the Active Directory object shall start from. Defaults to using the global catalog for the entire forest.
AllowedSecurityGroups no A list of distinguished names of security groups the account must be member of (request gets denied if it is not member of at least one of them).
DisallowedSecurityGroups no A list of distinguished names of security groups the account must not be member of (request gets denied if it is member of at least one of them).
AllowedOrganizationalUnits no A list of distinguished names of organizational units the account must be member of (request gets denied if it is not member of at least one of them).
DisallowedOrganizationalUnits no A list of distinguished names of organizational units the account must not be member of (request gets denied if it is member of at least one of them).
PermitDisabledAccounts no Permits certificates to get issued even if the Active Directory object is disabled.
SupplementServicePrincipalNames no Set to true to supplement DNS names found in the ServicePrincipalName attribute of the mapped AD object. See Supplementing Service Principal Names for more details.
DirectoryObjectRules no You can define one or more DirectoryObjectRule directives. See Configuring directory object rules for further reference.
AddSidUniformResourceIdentifier no Adds the security identifier (SID) of the mapped AD object into the Subject Alternative Name (SAN) certificate extension of the issued certificate. The entry will be in form of a uniformResourceIdentifier (tag:microsoft.com,2022-09-14:sid:<value>). This “strong” mapping method was introduced by Microsoft in April 2023 (https://techcommunity.microsoft.com/t5/ask-the-directory-services-team/preview-of-san-uri-for-certificate-strong-mapping-for-kb5014754/bc-p/3794144#M965).

The AllowedOrganizationalUnits and DisallowedOrganizationalUnits directives match also for nested organizational units. E.g. if you whitelist DC=intra,DC=tamemycerts,DC=com and the object resides in OU=Users,DC=intra,DC=tamemycerts,DC=com, this will match as well. If you configure TameMyCerts to add the SID uniform resource identifier, you should ensure that the resulting certificate will contain a Subject Alternative Name of type dNSName (for mapped computer objects) or userPrincipalName (for mapped user objects) as this will be used to map the certificate to the AD object during authentication. You can either achieve this by having the field being put into the certificate request (and governing requested certificate content), or add the Subject Alternative Name from Active Directory via Directory Services mapping.

Please be aware of the following limitations:

  • The sAMAccountName Active Directory attribute is only unique per Domain, but not on Forest level. TameMyCerts denies a certificate request if more than one account with the same identifier is found. Avoid this by either using unique directory attributes, or by specifying the SearchRoot parameter accordingly.
  • The userPrincipalName attribute may not be populated by default for user accounts.
  • You must escape LDAP-reserved characters (e.g. =, ,, \) with a backward slash (\), if present, for SearchRoot, AllowedSecurityGroups and DisallowedSecurityGroups.
  • The certification authority needs LDAP network access to all Domain Controllers that are involved in the DS mapping process. In addition, LDAP Global Catalog (GC) access is required as well when SearchRoot is not explicitly specified, or nested Group Memberships are going to be resolved. Consult the official Microsoft documentation (https://learn.microsoft.com/en-us/troubleshoot/windows-server/identity/config-firewall-for-ad-domains-and-trusts) for further information.

4.11.2 Resolving of Group Memberships

By default, TameMyCerts resolves nested Group Memberships for mapped objects.

This allows to use the primary group of a mapped Active Directory object (e.g. Domain Users, Domain Guests) for use with the AllowedSecurityGroups and DisallowedSecurityGroups directives, and group memberships from any domain can be resolved.

However, as TameMyCerts will use the msds-TokenGroupNames (https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/1d810083-9741-4b0a-999b-30d9f2bc1f95) Active Directory Attribute, which is only available on Windows Server 2016 and newer Domain Controllers, if TameMyCerts cannot retrieve the msds-TokenGroupNames attribute for a mapped object, certificate requests will get denied due to security reasons.

4.11.3 Disabling resolving of nested Group Memberships

It is possible to disable resolving nested Group Memberships by enabling the TMC_DONT_RESOLVE_NESTED_GROUP_MEMBERSHIPS global flag. TameMyCerts will then use the MemberOf (https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-ada2/cc24555b-61c7-49a2-9748-167b8ce5a512) attribute (against the mapped accounts domain) to determine Group Memberships of mapped objects.

Make sure you understand the following limitations when enabling this setting:

  • It will allow to use Domain Controllers older than Windows Server 2016.
  • It is not possible to use the primary group of a mapped Active Directory object (e.g. Domain Users, Domain Guests) for use with the AllowedSecurityGroups and DisallowedSecurityGroups directives.
  • The mapped Active Directory object must be an explicit (no nested groups) member of the configured security groups.
  • It is only possible to define groups that are in the same domain as the mapped account.

4.11.4 Examples

Enabling the mapping with default values for user objects in an offline template:

<DirectoryServicesMapping />

Enabling the mapping with default values for user and computer objects in an online template:

<DirectoryServicesMapping />

Enabling the mapping with default values for computer objects in an offline template:

<DirectoryServicesMapping>
  <CertificateAttribute>dNSName</CertificateAttribute>
  <DirectoryServicesAttribute>dNSHostName</DirectoryServicesAttribute>
  <ObjectCategory>computer</ObjectCategory>
</DirectoryServicesMapping>

Specifying an LDAP path as search root:

<DirectoryServicesMapping>
  <!-- other directives have been left out for simplicity -->
  <SearchRoot>OU=TameMyCerts Users,DC=tamemycerts,DC=local</SearchRoot>
</DirectoryServicesMapping>

Specifying an LDAP path as search root with escaping of LDAP-reserved characters:

<DirectoryServicesMapping>
  <!-- other directives have been left out for simplicity -->
  <SearchRoot>OU=Users\,Computers\,and others,DC=tamemycerts,DC=local</SearchRoot>
</DirectoryServicesMapping>

Permitting the issuance of certificates for disabled accounts:

<DirectoryServicesMapping>
  <!-- other directives have been left out for simplicity -->
  <PermitDisabledAccounts>true</PermitDisabledAccounts>
</DirectoryServicesMapping>

Filtering on security group memberships of a mapped object:

<DirectoryServicesMapping>
  <!-- other directives have been left out for simplicity -->
  <AllowedSecurityGroups>
    <string>CN=An allowed Group,DC=tamemycerts,DC=local</string>
  </AllowedSecurityGroups>
  <DisallowedSecurityGroups>
    <string>CN=A forbidden Group,DC=tamemycerts,DC=local</string>
  </DisallowedSecurityGroups>
</DirectoryServicesMapping>

Filtering on Organizational Unit placement of a mapped object:

<DirectoryServicesMapping>
  <!-- other directives have been removed for this example -->
  <AllowedOrganizationalUnits>OU=some-allowed-OU,DC=tamemycerts,DC=local</AllowedOrganizationalUnits>
  <DisallowedOrganizationalUnits>OU=some-disallowed-OU,DC=tamemycerts,DC=local</DisallowedOrganizationalUnits>
</DirectoryServicesMapping>

Adding the SID uniform resource identifier to the certificates SAN:

<DirectoryServicesMapping>
  <!-- other directives have been left out for simplicity -->
  <AddSidUniformResourceIdentifier>true</AddSidUniformResourceIdentifier>
</DirectoryServicesMapping>

This policy will deny a certificate request, should a matching object be found in the directory.

<DirectoryServicesMapping>
  <Action>Deny</Action>
  <!-- other directives have been left out for simplicity -->
</DirectoryServicesMapping>

For an example on how to add the SID certificate extension to an issued certificate, see section “Working with the SID certificate extension”.

4.12 Configuring directory object rules

Applies to online and offline certificate templates. Requires Directory Services Mapping to be enabled.

Directory services mapping can be configured to apply conditions that must match for attributes of a mapped directory object.

The configuration goes as follows:

Parameter Mandatory Description
DirectoryServicesAttribute yes The attribute of the mapped object that shall be evaluated.
Mandatory no Specified if the attribute may be omitted if it is invalid or empty. If set to “true”, requests will get denied in such a case.
Patterns yes You can define one or more “Pattern” directives describing expressions of which the sAMAccountName attribute of the mapped AD object must match at least one of to get either permitted or denied.

For a list of supported Active Directory attributes, consult the DirectoryServicesAttribute section within the Technical Reference chapter of this document.

For instructions on how to configure the Patterns directive, consult the Pattern section within the Technical Reference chapter of this document.

4.12.1 Examples

<DirectoryServicesMapping>
  <!-- other directives have been removed for this example -->
  <DirectoryObjectRules>
    <DirectoryObjectRule>
      <DirectoryServicesAttribute>description</DirectoryServicesAttribute>
      <Mandatory>true</Mandatory>
      <Patterns>
        <Pattern>
          <Expression>^Admin$</Expression>
          <TreatAs>RegEx</TreatAs>
          <Action>Deny</Action>
        </Pattern>
      </Patterns>
    </DirectoryObjectRule>
  </DirectoryObjectRules>
</DirectoryServicesMapping>

4.13 Working with the SID certificate extension

Applies only to offline certificate templates. Certificates from online certificate templates automatically get a SID certificate extension from the Windows Default policy module.

The SID certificate extension gets processed after Rules for the Subject Distinguished Name (Subject DN) and Rules for the Subject Alternative Name (SAN), so ensure you have these configured as well. If you plan to add the SID extension from an Active Directory object to an issued certificate, you must also configure Directory Services mapping.

Microsoft introduced another mapping method in form of a uniformResourceIndicator in April 2023 (https://techcommunity.microsoft.com/t5/ask-the-directory-services-team/preview-of-san-uri-for-certificate-strong-mapping-for-kb5014754/bc-p/3794144#M965), which is also supported by TameMyCerts and can be configured within Directory Services mapping.

The security identifier certificate extension was introduced by Microsoft with the May 2022 cumulative update for Windows Server (KB5014754) (https://support.microsoft.com/en-us/topic/kb5014754-certificate-based-authentication-changes-on-windows-domain-controllers-ad2c23b0-15d8-4340-a468-4d4f3b188f16). The patch causes Active Directory to require this certificate extension to process certificate-bases logons. There is a compatibility mode, which Microsoft plans to automatically disable on February 11, 2025.

As Microsoft only ensured that the extension will be present in certificates originating from online certificate templates, this probably will cause trouble when certificates originating from offline certificate templates (e.g. mobile devices managed by Intune, AirWatch/Workspace One, MobileIron and the like) are used for certificate-bases logons against Active Directory. A popular example is Wifi or VPN logons that use the Microsoft Network Policy Server.

TameMyCerts is able to process the new certificate extension in a variety of ways:

  • Deny requests containg the extension.
  • Pass the extension as-is into the issued certificate.
  • Add the extension from the properties of a mapped Active Directory object.
  • Remove the extension if it is part of the originating certificate request.
A certificate request containing a forbidden extension was denied by TameMyCerts

4.13.1 Configuring

If TameMyCerts shall process the SID certificate extension, you configure it with the SecurityIdentifierExtension directive within a policy configuration file.

You can configure four modes:

Action Description
Deny Default Action. All certificate requests that contain a security identifier certificate extension will get denied if this is set.
Allow If a certificate request contains a security identifier extension, it will get passed as-is into the issued certificate.
Add Adds the value of the objectSid (https://learn.microsoft.com/en-us/windows/win32/adschema/a-objectsid) attribute of the Active Directory object belonging to the certificate request to the issued certificate. Can therefore only be used in combination with Directory Services mapping.
Remove If a certificate request contains a security identifier extension, it will not get passed into the issued certificate.

If you configure TameMyCerts to add the SID certificate extension, you should ensure that the resulting certificate will contain a Subject Alternative Name of type dNSName (for mapped computer objects) or userPrincipalName (for mapped user objects) as this will be used to map the certificate to the AD object during authentication. You can either achieve this by having the field being put into the certificate request (and governing requested certificate content), or add the Subject Alternative Name from Active Directory via Directory Services mapping.

4.13.2 Examples

All certificate requests that contain a security identifier certificate extension will get denied.

<SecurityIdentifierExtension>Deny</SecurityIdentifierExtension>

All certificate requests that contain a security identifier certificate extension will get allowed and the resulting certificate will contain the requested SID extension.

<SecurityIdentifierExtension>Allow</SecurityIdentifierExtension>

All certificate requests that contain a security identifier certificate extension will get allowed and the resulting certificate will not contain the requested SID extension

<SecurityIdentifierExtension>Remove</SecurityIdentifierExtension>

All certificate requests get the SID extension built from a mapped Active directory object (requires Directory Services mapping to be configured).

<SecurityIdentifierExtension>Add</SecurityIdentifierExtension>

4.14 Adding custom certificate extensions

TameMyCerts allows to add custom certificate extensions with static values.

Custom certificate extensions are not marked as mandatory.

Field Mandatory Description
Oid yes The Object Identifier of the extension.
Value yes The BASE64-encoded value of the extension.

Examples for this might be:

Extension Object Identifier Value
OCSP must-staple 1.3.6.1.5.5.7.1.24 MAMCAQU=
OCSP NoCheck 1.3.6.1.5.5.7.48.1.5 no value
Microsoft Hyper-V / SCVMM Virtual Machine Connection 1.3.6.1.4.1.311.62.1.1.1 AgEE

4.14.1 Examples

Adding the OCSP must-staple certificate extension to an issued certificate.

<CustomCertificateExtensions>
    <CustomCertificateExtension>
        <Oid>1.3.6.1.5.5.7.1.24</Oid>
        <Value>MAMCAQU=</Value>
    </CustomCertificateExtension>
</CustomCertificateExtensions>

Adding the OCSP NoCheck certificate extension to an issued certificate.

<CustomCertificateExtensions>
    <CustomCertificateExtension>
        <Oid>1.3.6.1.5.5.7.48.1.5</Oid>
    </CustomCertificateExtension>
</CustomCertificateExtensions>

Adding the Hyper-V / SCVMM Virtual Machine Connection certificate extension to an issued certificate.

<CustomCertificateExtensions>
    <CustomCertificateExtension>
        <Oid>1.3.6.1.4.1.311.62.1.1.1</Oid>
        <Value>AgEE</Value>
    </CustomCertificateExtension>
</CustomCertificateExtensions>

4.15 Modifying the Subject Distinguished Name of issued certificates

Applies to online and offline certificate templates.

TamyMyCerts allows modifying the Subject Distinguished Name (Subject DN) of a certificate before it gets issued. It is capable of retrieving properties from a mapped Active Directory object and put these values into the Subject Distinguished Name of a certificate. The resulting value can be either an attribute of a mapped Active Directory object, a field of the originating certificate request, a static value, or a combination of all.

Populating the Subject Distinguished Name based on advanced rules with TameMyCerts

This is useful in the following scenarios:

  • Certificates issued via Autoenrollment shall have another value as the cn Attribute for the commonName field (which would be the only combination with the original Microsoft policy module).
  • Issued certificates shall contain additional Relative Distinguished Names that have not been requested by the enrollee.
  • Issued certificates shall contain identities in form of a specific syntax which goes beyond built-in capabilities.
  • A value from one certificate field shall be transferred to another one before issuing the certificate.

4.15.1 Configuring

You define a OutboundSubject directive containing one or more OutboundSubjectRule rules.

The OutboundSubjectRule directive can be configured as follows:

Parameter Mandatory Description
Field yes The Relative Distinguished Name that shall be populated.
Value yes The value that shall be put into the configured certificate field. Can contain variables.
Mandatory no Specified if the configured value may be omitted if one of the variables is invalid or empty. If set to “true”, requests will get denied in such a case. Defaults to false.
Force no Specifies how to act when the originating certificate request already contains a field of the specified type. If set to true and a field of same type is present, it gets overwritten with the configured value. If set to false, no action is made. Defaults to false.

You may specify the following Relative Distinguished Names (RDN) for the “Field” directive:

RDN Maximum length Typical AD attributes Remarks
emailAddress 128 mail
commonName 64 name, sAMAccountName, displayName, userPrincipalName
organizationName 64 company
organizationalUnitName 64 department
localityName 128 l
stateOrProvinceName 128 st
countryName 2 c
title 64 title not enabled by default
givenName 16 givenName not enabled by default
initials 5 initials not enabled by default
surname 40 sn not enabled by default
streetAddress 30 streetAddress not enabled by default
unstructuredName 1024 n/a
unstructuredAddress 1024 n/a
serialNumber 1024 n/a

The field names are processed case-sensitive.

The Value may contain a static string, or can be combined with attributes of mapped Active Directory objects, or content from the certificate request.

It is also possible to remove a requested relative distinguished name from an issued certificate by setting the Value to an empty string.

You configure variables with the following syntax: {Modifier:PropertyNameGoesHere}

The following modifiers are currently supported:

Modifier Description
ad Attributes of mapped Active Directory objects. For a list of supported Active Directory attributes, consult the DirectoryServicesAttribute section within the Technical Reference chapter of this document.
sdn Fields from the Subject Distinguished Name of the certificate request.
san Fields from the Subject Alternative Name of the certificate request.
yk Fields from YubiKey PIV Attestation of the certificate request.

Note that if you plan to insert attributes from mapped Active Directory objects, you need to configure DirectoryServicesMapping.

Note that if you plan to inser attributes from a YubiKey, you need to configure YubiKey PIV attestation.

4.15.2 Remarks

  • Configuring an invalid Field will lead to certificate requests getting denied.
  • Configuring a Value that violates length constraints for the selected Field will lead to certificate requests getting denied.
  • It is possible to remove a relative distinguished name by setting the Value to an empty string. A more advanced variant of this is to transfer a value from one requested RDN to another one and then remove the original one.

4.15.3 Examples

Issued certificates will have a commonName field which will contain the content of the userPrincipalName Active Directoy attribute of the mapped object. Furthermore, the emailAddress field will be populated with the content of the mail AD attribute. Should the userPrincipalName AD attribute not be populated in AD, the request will get denied. Should the mail AD attribute not be populated in AD, the certificate will get issued but not include an emailAddress field.

<DirectoryServicesMapping />
<OutboundSubject>
  <OutboundSubjectRule>
    <Field>commonName</Field>
    <Value>{ad:userPrincipalName}</Value>
    <Mandatory>true</Mandatory>
    <Force>true</Force>
  </OutboundSubjectRule>
  <OutboundSubjectRule>
    <Field>emailAddress</Field>
    <Value>{ad:mail}</Value>
  </OutboundSubjectRule>
</OutboundSubject>

The commonName will be built out of the two Active Directory attributes sn (surname) and givenName. Assuming the given name is “John” and the surname is “Doe”, the commonName in the issued certificate will be “Doe, John”.

<DirectoryServicesMapping />
<OutboundSubject>
  <OutboundSubjectRule>
    <Field>commonName</Field>
    <Value>{ad:sn}, {ad:givenName}</Value>
    <Mandatory>true</Mandatory>
    <Force>true</Force>
  </OutboundSubjectRule>
</OutboundSubject>

The commonName will be built out of the name Active Directory attribute and a static string. Assuming the name attribute contains “John Doe”, the commonName in the issued certificate will be “John Doe is an awesome fellow!”.

<DirectoryServicesMapping />
<OutboundSubject>
  <OutboundSubjectRule>
    <Field>commonName</Field>
    <Value>{ad:name} is an awesome fellow!</Value>
    <Mandatory>true</Mandatory>
    <Force>true</Force>
  </OutboundSubjectRule>
</OutboundSubject>

The commonName will be built out of the displayName Active Directory attribute. The organizationName will be set to “TameMyCerts”, regardless if the originating certificate request did contain this field or not.

<OutboundSubject>
  <OutboundSubjectRule>
    <Field>commonName</Field>
    <Value>{ad:displayName}</Value>
    <Mandatory>true</Mandatory>
    <Force>true</Force>
  </OutboundSubjectRule>
  <OutboundSubjectRule>
    <Field>organizationName</Field>
    <Value>TameMyCerts</Value>
    <Force>true</Force>
  </OutboundSubjectRule>
</OutboundSubject>

Transfering the first dNSName of the Subject Alternative Name into the commonName field of the issued certificate.

<!-- does not require DirectoryServicesMapping -->
<OutboundSubject>
  <OutboundSubjectRule>
    <Field>commonName</Field>
    <Value>{san:dNSName}</Value>
    <Mandatory>true</Mandatory>
    <Force>true</Force>
  </OutboundSubjectRule>
</OutboundSubject>

The content of the stateOrProvinceName field will be removed from the issueed certificate, if present in the certificate request.

<DirectoryServicesMapping />
<OutboundSubject>
  <OutboundSubjectRule>
    <Field>stateOrProvinceName</Field>
    <Value></Value>
    <Mandatory>true</Mandatory>
    <Force>true</Force>
  </OutboundSubjectRule>
</OutboundSubject>

The content of the stateOrProvinceName field will be transferred from the certificate request into the serialNumber field of the issued certificate, and the stateOrProvinceName field will be removed from the issued certificate.

<DirectoryServicesMapping />
<OutboundSubject>
  <OutboundSubjectRule>
    <Field>stateOrProvinceName</Field>
    <Value></Value>
    <Mandatory>true</Mandatory>
    <Force>true</Force>
  </OutboundSubjectRule>
  <OutboundSubjectRule>
    <Field>serialNumber</Field>
    <Value>{sdn:stateOrProvinceName}</Value>
    <Mandatory>true</Mandatory>
    <Force>true</Force>
  </OutboundSubjectRule>
</OutboundSubject>

4.16 Modifying the Subject Alternative Name of issued certificates

Applies to online and offline certificate templates.

TamyMyCerts allows modifying the Subject Alternative Name (SAN) of a certificate before it gets issued. It is capable of retrieving properties from a mapped Active Directory object and put these values into the SAN of a certificate. The resulting value can be either an attribute of a mapped AD object, a field of the originating certificate request, a static value, or a combination of all.

4.16.1 Configuring

You define a OutboundSubjectAlternativeName directive containing OutboundSubjectRule rules.

The OutboundSubjectRule directive can be configured as follows:

Parameter Mandatory Description
Field yes The Relative Distinguished Name that shall be populated.
Value yes The value that shall be put into the configured certificate field. Can contain variables.
Mandatory no Specified if the configured value may be omitted if one of the variables is invalid or empty. If set to “true”, requests will get denied in such a case. Defaults to false.
Force no Specifies how to act when the originating certificate request already contains a field of the specified type. If set to true and a field of same type is present, an additional entry with the configured value gets added to the SAN. If set to false, no action is performed. Defaults to false.

You may specify the following Subject Alternative Name types for the “Field” directive:

  • dnsName
  • rfc822Name
  • uniformResourceIdentifier
  • userPrincipalName
  • ipAddress

The field names are processed case-sensitive.

The Value may contain a static string, or can be combined with attributes of mapped Active Directory objects, or content from the certificate request.

You configure variables with the following syntax: {Modifier:PropertyNameGoesHere}

The following modifiers are currently supported:

Modifier Description
ad Attributes of mapped Active Directory objects. For a list of supported Active Directory attributes, consult the DirectoryServicesAttribute section within the Technical Reference chapter of this document.
sdn Fields from the Subject Distinguished Name of the certificate request.
san Fields from the Subject Alternative Name of the certificate request.

Note that if you plan to insert attributes from mapped Active Directory objects, you need to configure DirectoryServicesMapping.

4.16.2 Examples

The SAN gets supplemented with a dNSName containing the name attribute of a computer object (so that the unqualified DNS name is part of the SAN) .

<DirectoryServicesMapping />
<OutboundSubjectAlternativeName>
  <OutboundSubjectRule>
    <Field>dNSName</Field>
    <Value>{ad:name}</Value>
    <Mandatory>true</Mandatory>
  </OutboundSubjectRule>
</OutboundSubjectAlternativeName>

The commonName from the Subject DN is transferred to the Subject Alternative Name (SAN) in form of a dNSName.

<!-- does not require DirectoryServicesMapping -->
<OutboundSubjectAlternativeName>
  <OutboundSubjectRule>
    <Field>dNSName</Field>
    <Value>{sdn:commonName}</Value>
    <Mandatory>true</Mandatory>
  </OutboundSubjectRule>
</OutboundSubjectAlternativeName>

4.17 Supplementing Service Principal Names from mapped Active Directory objects

Applies to online and offline certificate templates. Requires Directory Services Mapping to be enabled.

TameMyCerts can add DNS names found in the Service Principal Names (https://learn.microsoft.com/en-us/windows/win32/ad/service-principal-names) (SPNs) of mapped AD objects to the Subject Alternative Name (SAN) extension of issued certificates.

This allows to automatically add aliases and custom names required for Kerberos authentication to issued certificates.

Supplementing Service Principal Names with TameMyCerts

This feature might be dangerous in cases there are no strict controls about how SPNs are registered for your AD accounts. Please use the feature carefully!

As the Service Principal Names (SPNs) usually also contain the non-qualified hostname of a machine, this identity gets added to the SAN as well.

4.17.1 Configuring

You enable the feature by configuring SupplementServicePrincipalNames directive.

<DirectoryServicesMapping>
  <!-- other directives have been left out for simplicity -->
  <SupplementServicePrincipalNames>true</SupplementServicePrincipalNames>
</DirectoryServicesMapping>

By default, TameMyCerts will supplement both qualified (e.g. host.domain.tld) and unqualified DNS names (e.g. host). You can suppress supplementation of unqialified names by setting the SupplementUnqualifiedNames to false.

<DirectoryServicesMapping>
  <!-- other directives have been left out for simplicity -->
  <SupplementServicePrincipalNames>true</SupplementServicePrincipalNames>
</DirectoryServicesMapping>
<SupplementUnqualifiedNames>false</SupplementUnqualifiedNames>

4.18 Configuring per-template CDP, AIA or OCSP URIs

Applies to online and offline certificate templates.

TameMyCerts allows to create custom certificate extensions for Certificate Revocation List Distribution Points (CDP), Authority Information Access (AIA) and Online Certificate Status Protocol (OCSP) on a per-template basis.

The directives are:

  • CrlDistributionPoints
  • AuthorityInformationAccess
  • OnlineCertificateStatusProtocol

Each of those can contain one or more uniform resource identifiers (URIs). TameMyCerts supports the same token variables as the original Microsoft product (https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2003/cc737264(v=ws.10)), namely:

Microsoft Token name Description Variable
ServerDNSName The DNS name of the CA server %1
ServerShortName The NetBIOS name of the CA server %2
CaName The name of the CA %3
Cert_Suffix The renewal extension of the CA %4
ConfigurationContainer The location of the configuration container in Active Directory %6
CATruncatedName The “sanitized” name of the CA, 32 characters with a hash on the end %7
CRLNameSuffix The renewal extension for the CRL %8
CDPObjectClass %10
CAObjectClass %11

Online Certificate Status Protocol (OCSP) URIs should only be configured in combination with Authority Information Access (AIA) URIs as they get written into the same certificate extension.

4.18.1 Examples

Issuing CRL Distribution Point (CDP) URIs on a per-template basis:

<CrlDistributionPoints>
  <string>http://%1/CertData/%3%8%9.crl</string>
  <string>ldap:///CN=%7%8,CN=%3,CN=cdp,CN=Public Key Services,CN=Services,%6%10</string>
</CrlDistributionPoints>

Issuing Authority Information Access (AIA) URIs on a per-template basis:

<AuthorityInformationAccess>
  <string>http://%1/CertData/%3%4.crt</string>
  <string>ldap:///CN=%7,CN=AIA,CN=Public Key Services,CN=Services,%6%11</string>
</AuthorityInformationAccess>

Issuing Online Certificate Status Protocol (OCSP) URIs on a per-template basis:

<OnlineCertificateStatusProtocol>
  <string>http://ocsp.tamemycerts.com/ocsp</string>
</OnlineCertificateStatusProtocol>

4.19 Issuing Certificates with an exactly defined validity period

Applies to online and offline certificate templates. Does not support Audit only mode. This feature is independent from certificate templates. It can only be enabled used globally on a certification authority level.

The Windows Default policy module allows to specify the exact expiration date (https://learn.microsoft.com/en-us/troubleshoot/windows-server/identity/change-certificates-expiration-date) (NotAfter) for a certificate by specifying an ExpirationDate attribute whilst submitting the certificate request. TameMyCerts adds support for a StartDate attribute which does the exact same for the begin of the certificates validity period (the “NotBefore” certificate property).

4.19.1 Configuring

To enable the feature, you must enable the EDITF_ATTRIBUTEENDDATE flag for the policy module of the certification authority and restart the certification authority service afterwards.

certutil -setreg Policy\Editflags +EDITF_ATTRIBUTEENDDATE
net stop certsvc
net start certsvc

Now you can specify both StartDate and ExpirationDate request attribute in IETF RFC 2616 (https://datatracker.ietf.org/doc/html/rfc2616) compliant form whilst submitting the certificate request.

A syntax example for a compliant date form could be:

Tue, 1 Mar 2022 08:00:00 GMT

When an invalid date is being requested, the certificate request will get denied with error code ERROR_INVALID_TIME.

TameMyCerts currently only supports specifying StartDate whilst submitting the certificate request but not as custom attributes within the certificate request itself. The alternative method of specifying ValidityPeriod and ValidityPeriodUnits for the expiration date can currently not be used in combination with the StartDate attribute as it gets applied afterwards and thus won’t deliver the expected result.

4.19.2 Examples

Requesting a certificate that shall be valid from Mar 1, 2022 08:00 until Mar 1, 2022 16:00:

certreq.exe -config "caserver.tamemycerts.local\TameMyCerts CA" -attrib "CertificateTemplate:TameMyCertsWebServer\nStartDate:Tue, 1 Mar 2022 08:00:00 GMT\nExpirationDate:Tue, 1 Mar 2022 16:00:00 GMT" -submit "MyCertificateRequest.req"

4.20 Permitting empty identities

Applies to online and offline certificate templates.

For any certificate template that has a policy configuration defined, TameMyCerts will ensure that the resulting certificate will contain an identity, either in the Subject Distinguished Name or the Subject Alternative Name. If the resulting certificate would not contain an identity, the certificate request will get denied and an event will be logged.

Should you have the requirement to issue such certificates regardless of not containing an identity, you may change the behavior with the PermitEmptyIdentites directive:

<PermitEmptyIdentites>true</PermitEmptyIdentites>

4.21 Denying certificate requests for insecure combinations

Applies to online and offline certificate templates.

TameMyCerts will automatically deny certificate requests when they contain a “san” request attribute and the certification authority has the insecure EDITF_ATTRIBUTESUBJECTALTNAME2 (https://www.gradenegger.eu/en/take-over-the-active-directory-overall-structure-with-the-flag-editf_attributesubjectaltname2/) flag set. This combination can allow an attacker to request certificates with arbitrary identities, resulting in a complete takeover of your Active Directory.

This behavior can be altered by configuring Global settings for the policy module. However, it is stongly advised not to do so.

Instead of using the “san” request attribute in combination with EDITF_ATTRIBUTESUBJECTALTNAME2, you should ensure that certificate request already contain a Subject Alternative Name (SAN) extension. In case where this is not possible, the Supplementing DNS Names and IP Addresses feature can be used.

Note that TameMyCerts will log the presence of the “san” request attribute whether the flag is enabled or not.

4.22 YubiKey PIV attestation

Applies to online and offline certificate templates.

TameMyCerts YubiKey PIV attestation is the first utlizing Event Tracing for Windows (ETW) for logging. YubiKey validation will log which policy was matched in the Operations log, the entry will also include information about the YubiKey.

TameMyCerts can ensure that a key pair has been created and is secured with a YubiKey (https://www.yubico.com/products/yubikey-5-overview/).

This feature is called Personal Identity Verification (PIV) attestation (https://developers.yubico.com/PIV/Introduction/PIV_attestation.html). It can be combined with any other TameMyCerts feature.

It is possible to include the attestation certificates in the Certificate Signing Request by using any of the following means:

4.22.1 Preparing the certification authority for YubiKey PIV attestation

For the attestation certificate chain to be properly built, you must create a YKROOT certificate store under the LocalMachine certificate store on the certification authority server.

Set-Location -Path Cert:\LocalMachine
New-Item -Name YKROOT
New-Item -Name YKCA

Any YubiKey attestation Root CA certificates must be imported into the YKROOT certificate store.

The import could be scripted like the following:

Get-ChildItem -Path *.cer | ForEach-Object -Process { certutil -addstore YKROOT $_.FullName }
YKROOT Windows Certificate Store

Any YubiKey intermediate CA certificates must be imported into the YKCA certificate store (only applies to YubiKeys with Firmware 5.7.4 or newer).

The import could be scripted like the following:

Get-ChildItem -Path *.cer | ForEach-Object -Process { certutil -addstore YKCA $_.FullName }
YKCA Windows Certificate Store

Note that it is required to restart the certification authority service to reflect any changes that are made to the YKROOT and YKCA certificate stores.

Note that these might need to get updated during the lifetime of the certification authority, as the vendor might introduce devices signed with newer CA certificates.

4.22.2 Configuring

You define a YubiKeyPolicies directive containing one or more YubiKeyPolicy rules.

Parameter Mandatory Description
Action yes Specifies if this rule shall cause the certificate request to be allowed or denied, should it’s conditions match. Can be Allow or Deny.
PinPolicy no Specifies which PIN policy must be configured on the YubiKey for the rule to match. Can be one or more of the following: Once, Never, Always, MatchOnlye, MatchAlways.
TouchPolicy no Specifies which Touch policy must be configured on the YubiKey for the rule to match. Can be one or more of the following: Always, Never, Cached.
FormFactor no Specifies of which form factor the YubiKey must be for the rule to match. Can be one or more of the following: UsbAKeychain, UsbCKeychain, UsbANano, UsbCNano, UsbCLightning, UsbABiometricKeychain, UsbCBiometricKeychain.
MaximumFirmwareVersion no Specifies the maximum Firmware version the YubiKey must have for the rule to match.
MinimumFirmwareVersion no Specifies the minimum Firmware version the YubiKey must have for the rule to match.
Edition no Specifies of which edition the YubiKey must be for the rule to match. Can be one or more of the following: FIPS, Normal, CSPN.
Slot no Specifies the Slot under which the certificate request must be stored under for the rule to match. Can be one or more of the following: 9a, 9c, 9d, 9e.
KeyAlgorithm no Specifies the Key Algorithm of which the certificate request must be for the rule to match. Can be one or more of the following: RSA, ECC.

The YubiKeyPolicies are read one by one.

  • If there is any policy with Allow action, the default behavior if no rule matched is to deny the certificate request.
  • If all policies are of Deny action, the default behavior if no rule matched is to allow the certificate request.
  • Alternating Deny and Allow policies is allowed. In this case, for a certificate request to get allowed, at least one of the policy with Allow action must match, whereas none of the policies with Deny action must match.

4.22.3 Creating certificate requests

This is only an example. Refer to the vendor’s documentation (https://developers.yubico.com/yubico-piv-tool/) for more information on how to use the tool.

Certificate requests can be created in various ways. Here is an example using the YubiKey PIV Tool.

First, a key pair has to be created. This will save the public key into a file named pubkey.key.

yubico-piv-tool --slot=9a --action=generate --pin-policy=once --touch-policy=cached --algorithm=ECCP384 --output=pubkey.key

Afterwards, a Certificate Signing Request can be created using the public key. It will be saved into a file called request.csr.

yubico-piv-tool --slot=9a --subject="/CN=this-is-a-test/" --input=pubkey.key --attestation --output=request.csr --action=verify-pin --action=request

4.22.4 Transferring PIV attestation data into issued certificates

Attestation Information can be written into the Subject Distinguished Name of the issued certificates using the following tokens:

  • yk:FormFactor
  • yk:FirmwareVersion
  • yk:PinPolicy
  • yk:TouchPolicy
  • yk:Slot
  • yk:SerialNumber

4.22.5 Attesting the PIV attestation in issued certificates

TameMyCerts will transfer the following certificate extensions from the YubiKey attestation certificate into the issued certificate (if present in the attestation certificate):

Extension OID Description
1.3.6.1.4.1.41482.3.3 Firmware version, encoded as 3 bytes, like: 040300 for version 4.3.0.
1.3.6.1.4.1.41482.3.7 Serial number of the YubiKey, encoded as an integer.
1.3.6.1.4.1.41482.3.8 Two bytes, the first encoding pin policy (01 - never, 02 - once per session, 03 - always) and the second touch policy (01 - never, 02 - always, 03 - cached for 15 seconds)
1.3.6.1.4.1.41482.3.9 Formfactor, encoded as one byte: USB-A Keychain: 01 and 81 for FIPS Devices, USB-A Nano: 02 and 82 for FIPS Devices, USB-C Keychain: 03 and 83 for FIPS Devices, USB-C Nano: 04 and 84 for FIPS Devices, Lightning and USB-C: 05 and 85 for FIPS Devices
1.3.6.1.4.1.41482.3.10 FIPS Certified YubiKey
1.3.6.1.4.1.41482.3.11 CSPN Certified YubiKey

It was originally intended to provide an option to include the original attestation data in issued certificates, but as YubiKeys have a size limit of 3052 bytes for issued certificates (see https://docs.yubico.com/yesdk/users-manual/application-piv/attestation.html for more details), this is not feasible.

If you intend to add a proof of attestation into issued certificates, do this by adding an Issuance Policy to issued certificates.

4.22.6 Adding additional content to issued certificates

Not all tools that may be used to create certificate requests with PIV attestation support adding a Subject Alternative Name or, for example, do not support the Microsoft-proprietary userPrincipalName SAN type. TameMyCerts can add this information by Modifying the Subject Alternative Name of issued certificates. See the below section for examples.

4.22.7 Examples

A simple policy that just ensures the key pair is protected with a YubiKey, without any additional requirements.

<YubiKeyPolicies>
  <YubiKeyPolicy />
</YubiKeyPolicies>

Denying certificate requests for ECC keys with a YubiKey with firmware version prior to 5.7.0 (these have a vulnerability, see https://www.yubico.com/support/security-advisories/ysa-2024-03/ for more details).

<YubiKeyPolicies>
  <YubiKeyPolicy>
      <MaximumFirmwareVersion>5.6.9</MaximumFirmwareVersion>
      <KeyAlgorithm>
        <string>ECC</string>
      </KeyAlgorithm>
      <Action>Deny</Action>
  </YubiKeyPolicy>
</YubiKeyPolicies>

Transferring the Slot and Serial Number of the YubiKey into the commonName of the issued certificate (in combination with the cn attribute from a mapped Active Directory object).

Note that the commonName is subject to a length constraint determined by Microsoft AD CS.

<YubiKeyPolicies>
  <!-- other directives have been left out for simplicity -->
</YubiKeyPolicies>
<OutboundSubject>
  <OutboundSubjectRule>
    <Field>commonName</Field>
    <Value>{ad:cn} [{yk:Slot} {yk:SerialNumber}]</Value>
    <Mandatory>true</Mandatory>
    <Force>true</Force>
  </OutboundSubjectRule>
</OutboundSubject>

Transferring the Serial Number of the YubiKey into the serialNumber of the issued certificate.

<YubiKeyPolicies>
  <!-- other directives have been left out for simplicity -->
</YubiKeyPolicies>
<OutboundSubject>
  <OutboundSubjectRule>
    <Field>serialNumber</Field>
    <Value>{yk:SerialNumber}]</Value>
    <Mandatory>true</Mandatory>
    <Force>true</Force>
  </OutboundSubjectRule>
</OutboundSubject>

A policy containing all possible combinations.

<YubiKeyPolicies>
  <YubiKeyPolicy>
    <Action>Allow</Action>
    <PinPolicy>
      <string>Once</string>
      <string>Never</string>
      <string>Always</string>
      <string>MatchOnce</string>
      <string>MatchAlways</string>
    </PinPolicy>
    <TouchPolicy>
      <string>Always</string>
      <string>Never</string>
      <string>Cached</string>
    </TouchPolicy>
    <FormFactor>
      <string>UsbAKeychain</string>
      <string>UsbCKeychain</string>
      <string>UsbANano</string>
      <string>UsbCNano</string>
      <string>UsbCLightning</string>
      <string>UsbABiometricKeychain</string>
      <string>UsbCBiometricKeychain</string>
    </FormFactor>
    <MaximumFirmwareVersion>9.9.9</MaximumFirmwareVersion>
    <MinimumFirmwareVersion>0.0.0</MinimumFirmwareVersion>
    <Edition>
      <string>FIPS</string>
      <string>Normal</string>
      <string>CSPN</string>
    </Edition>
    <Slot>
      <string>9a</string>
      <string>9c</string>
      <string>9d</string>
      <string>9e</string>
    </Slot>
    <KeyAlgorithm>
      <string>RSA</string>
      <string>ECC</string>
    </KeyAlgorithm>
  </YubiKeyPolicy>
</YubiKeyPolicies>

Mapping the User’s Active Directory identity from the commmonName of the certificate to the sAMAccountName of the AD object and adding the user’s userPrincipalName to the Subject Alternative Name of the issued certificate, after verifying PIV attestation.

<Subject>
  <SubjectRule>
    <Field>commonName</Field>
    <Mandatory>true</Mandatory>
    <Patterns>
      <Pattern>
        <Expression>^[a-zA-Z0-9]*$</Expression>
      </Pattern>
    </Patterns>
  </SubjectRule>
</Subject>
<DirectoryServicesMapping>
  <CertificateAttribute>commonName</CertificateAttribute>
  <DirectoryServicesAttribute>sAMAccountName</DirectoryServicesAttribute>
</DirectoryServicesMapping>
<YubiKeyPolicies>
  <!-- other directives have been left out for simplicity -->
</YubiKeyPolicies>
<OutboundSubjectAlternativeName>
  <OutboundSubjectRule>
    <Field>userPrincipalName</Field>
    <Value>{ad:userPrincipalName}</Value>
    <Mandatory>true</Mandatory>
  </OutboundSubjectRule>
</OutboundSubjectAlternativeName>

5 Monitoring and Troubleshooting

Please be aware that if no policy file exists for a given certificate template, the request gets accepted as this would be the original behavior of the Windows Default policy module. This behavior can however be changed by configuring a global setting for TameMyCerts.

If a certificate request violates the defined policy, the certification authority will deny it with one of the below error codes and messages. The CA will log Event with ID 53 (https://www.gradenegger.eu/en/details-of-the-event-with-id-53-of-the-source-microsoft-windows-certificationauthority/). The error code/message will also be handed over to the requesting client over the DCOM protocol as answer to the certificate request.

TameMyCerts will also write its own Logs which contain detailled information about why a certificate request was denied, amongst others.

5.1 Error Codes

The following error codes can be thrown by the policy module back to the requestor when a request was denied:

Message Symbol Description
The permissions on the certificate template do not allow the current user to enroll for this type of certificate. CERTSRV_E_TEMPLATE_DENIED Occurs if the process used to create the certificate request is unknown, not allowed or explicitly disallowed. Also occurs when Directory Services mapping encounters an error.
The certificate has an invalid name. The name is not included in the permitted list or is explicitly excluded. CERT_E_INVALID_NAME Occurs if the requests Subject Distinguished Name or Subject Alternative Name violates the defined rules.
The public key does not meet the minimum size required by the specified certificate template. CERTSRV_E_KEY_LENGTH Occurs if the requests public key violates the defined rules for key algorithm or maximum key length.
An internal error occurred. ERROR_INVALID_DATA Occurs if the policy module is unable to interpret the given policy file.
The specified time is invalid. ERROR_INVALID_TIME Occurs if an invalid date was requested for the “StartDate” certificate request attribute.

5.2 Caches involved

TameMyCerts features the following caches:

5.2.1 Certificate Template Cache

Certificate template configuration is read by TameMyCerts from the CA servers registry every 5 minutes to reduce CPU load.

Note that updates made to a certificate template in Active Directory are not instantly replicated to the CA servers registry, as this part of the registry is only updated every 8 hours.

5.2.2 Certificate Request Policy Cache

Certificate Request policy files are loaded on first use and are then served from memory as long as they do not change. This reduces CPU and storage load. When the file gets modified and therefore the modification date of the file gets updated, it will get re-loaded on next use.

Should you, for example, copy a previous version of a policy configuration file back to the configured directory, it will not get read because it would have an older modification date. You would have to save it again so that it has a newer timestamp. Alternatively, you could re-start the certification authority service, as this will invalidate the cache.

5.3 Known limitations, common issues and frequently asked questions

5.3.1 Unsupported Subject Alternative Name (SAN) types

TameMyCerts currently does only support the following Subject Alternative Name types:

  • dnsName
  • rfc822Name
  • uniformResourceIdentifier
  • userPrincipalName
  • ipAddress

If a certificate request contains an unsupported SAN type, the behavior is as follows:

  • If the certificate template is an online template, this limitation doesn’t matter.
  • If the certificate template is an offline template,
    • If no policy configuration file exists, the SAN extension gets issued as requested.
    • If you don’t modify the SAN of a requested certificate through a policy configuration, the SAN extension gets issued as requested.
    • If you modify the SAN of a requested certificate through a policy configuration, all unsupported SAN types get stripped from the issued certificates SAN extension.

5.3.2 Interpreting the error message that a policy configuration file could not be parsed

When an error parsing the policy configuration file is thrown, remember that the actual line may be above or below the one noted in the log entry.

5.3.3 A recently created certificate template is not recognized by TameMyCerts and an Error with ID 10 is logged

This is expected as there is a chaching involved. The cache is read from the local certificate template cache of the CA server and updated every five minutes. Therefore, you can do one of the following to solve this:

  1. Wait until the local certificate template gets updated automatically. This can take up to eight hours.

  2. Update the local certificate template cache on your own. To do this, run the following command as an administrator:

     certutil -pulse

    You’ll then still have to wait up to 5 minutes or restart the CA service afterwards for the certificate template to get recognized.

5.3.4 Relative distinguished with empty values are treated as non-existent

Certificate requests that contain relative distinguished with empty values (e.g. CN=““) are treated as if the RDN was missing when a subject rule is applied. This is because TameMyCerts doesn’t inspect the actual certificate request but how the certification authority would issue the certificate. Microsoft AD CS does remove relative distinguished names containing empty values.

5.3.5 No support for standalone certification authorities

As TameMyCerts follows the original Microsoft concept of certificate templates, it does not support standalone certification authorities (as these do not use certificate templates).

5.3.6 No support for coexistence with other custom policy modules

At the moment, TameMyCerts can not be combined with other policy modules except the Windows Default policy module that is shipped with Active Directory Certificate Services. A common example for an incompatible module would be the policy modules shipped with Microsoft Identity Manager Certificate Management (MIM CM).

6 Logs generated by the TameMyCerts policy module

In addition to the certification authorities regular log entries, the policy module will also write a detailed log entry if a certificate request was denied due to a policy violation or failure. Find the logs under the Application event log with the TameMyCerts Event Source.

Event viewer filtering on the TameMyCerts source

Logging for the policy module follows the LogLevel (https://www.gradenegger.eu/en/configure-log-level-log-level-for-the-certification-authority-event-log/) concept of the certification authority. Increasing the value for the certification authority also affects the logging amount of TameMyCerts.

certutil -setreg CA\Loglevel {LogLevel}
net stop certsvc
net start certsvc
Log Level Description
0 CERTLOG_MINIMAL
1 CERTLOG_TERSE
2 CERTLOG_ERROR
3 CERTLOG_WARNING (Default Setting)
4 CERTLOG_VERBOSE
5 CERTLOG_EXHAUSTIVE

6.1 Event ID 1

  • Event Log: Application
  • Event Source: TameMyCerts
  • Event Type: Information
  • Required certification authority LogLevel: 4 (CERTLOG_VERBOSE)

6.1.1 Event Sample

{0} policy module version {1} is ready to process incoming certificate requests.
  • Placeholder {0} will contain the policy module name.
  • Placeholder {0} will contain the policy module version.

6.1.2 Event Description

Occurs if the Windows Default policy was successfully loaded and TameMyCerts is ready to process incoming requests.

Sample event of TameMyCerts

6.2 Event ID 2

  • Event Log: Application
  • Event Source: TameMyCerts
  • Event Type: Error
  • Required certification authority LogLevel: 2 (CERTLOG_ERROR)

6.2.1 Event Sample

Error initializing Windows Default policy module:
{0}
  • Placeholder {0} will contain the error message.

6.2.2 Event Description

Occurs if the Windows Default policy was not successfully loaded during CA service startup. Will cause the CA service to not start.

6.3 Event ID 4

  • Event Log: Application
  • Event Source: TameMyCerts
  • Event Type: Error
  • Required certification authority LogLevel: 2 (CERTLOG_ERROR)

6.3.1 Event Sample

Shutting down Windows Default policy module failed:
{0}
  • Placeholder {0} will contain the error message.

6.3.2 Event Description

Occurs if the Windows Default policy was not successfully unloaded during CA service shutdown.

6.4 Event ID 5

  • Event Log: Application
  • Event Source: TameMyCerts
  • Event Type: Warning
  • Required certification authority LogLevel: 0 (CERTLOG_MINIMAL)

6.4.1 Event Sample

Audit mode is enabled for {1}. Request {0} would get denied because:
{2}
  • Placeholder {0} will contain the Request ID number.
  • Placeholder {1} will contain the certificate template name.
  • Placeholder {2} will contain one or more reasons why the certificate request would get denied.

6.4.2 Event Description

Occurs if Audit only mode is enabled for a certificate template and a certificate request would get denied because of a policy violation. Contains a detailed information which kind of policy violation caused the request to get denied.

6.5 Event ID 6

  • Event Log: Application
  • Event Source: TameMyCerts
  • Event Type: Warning
  • Required certification authority LogLevel: 3 (CERTLOG_WARNING)

6.5.1 Event Sample

Request {0} for {1} was denied because:
{2}
  • Placeholder {0} will contain the Request ID number.
  • Placeholder {1} will contain the certificate template name.
  • Placeholder {2} will contain one or more reasons why the certificate request was denied.
Preventing the ESC6 attack with TameMyCerts

6.5.2 Event Description

Occurs if a certificate request was denied because of a policy violation. The event description contains detailed information which kind of policy violation caused the request to get denied.

Note that TameMyCerts can also detect abuse of insecure flags set on the certification authority, which can help prevent compromise of the Active Directory environment. Occurrences are logged under this event ID.

6.6 Event ID 7

  • Event Log: Application
  • Event Source: TameMyCerts
  • Event Type: Warning
  • Required certification authority LogLevel: 4 (CERTLOG_VERBOSE)

6.6.1 Event Sample

Unable to find policy file for {0}. Request {1} will get issued.
  • Placeholder {0} will contain the certificate template name.
  • Placeholder {1} will contain the Request ID number.

6.6.2 Event Description

Occurs if there is no policy configuration file defined for the certificate template used certificate request. The certificate request gets allowed in this case.

6.7 Event ID 8

  • Event Log: Application
  • Event Source: TameMyCerts
  • Event Type: Warning
  • Required certification authority LogLevel: 3 (CERTLOG_WARNING)

6.7.1 Event Sample

Unable to find policy file for {0}. Request {1} will get denied.
  • Placeholder {0} will contain the certificate template name.
  • Placeholder {1} will contain the Request ID number.

6.7.2 Event Description

Occurs if there is no policy configuration file defined for the certificate template used certificate request, and TameMyCerts global flags are configured to deny certificate requests when there is no policy defined. The certificate request gets denied in this case.

6.8 Event ID 9

  • Event Log: Application
  • Event Source: TameMyCerts
  • Event Type: Error
  • Required certification authority LogLevel: 2 (CERTLOG_ERROR)

6.8.1 Event Sample

The {0} policy module currently does not support standalone certification authorities.
  • Placeholder {0} will contain the policy module name.

6.8.2 Event Description

Occurs it the TameMyCerts policy module is loaded on a standalone certification authority, which is unsupported at the moment. Will cause the CA service to not start.

6.9 Event ID 10

  • Event Log: Application
  • Event Source: TameMyCerts
  • Event Type: Error
  • Required certification authority LogLevel: 2 (CERTLOG_ERROR)

6.9.1 Event Sample

Request {0} will get denied. Unable to interpret policy for {1} because:
{2}
No certificate template information for request {0} could be retrieved from the certification authority service. The request will get denied.
No certificate template information for request {0} could be retrieved from the local certificate template cache. The request will get denied.
  • Placeholder {0} will contain the Request ID number.
  • Placeholder {1} will contain the certificate template name.
  • Placeholder {2} will contain any additional error messages.

6.9.2 Event Description

Occurs if a certificate request was denied because because the policy file for the certificate template could not be interpreted.

6.10 Event ID 11

  • Event Log: Application
  • Event Source: TameMyCerts
  • Event Type: Information
  • Required certification authority LogLevel: 4 (CERTLOG_VERBOSE)

6.10.1 Event Sample

Request {0} was denied by the Windows Default policy module.
  • Placeholder {0} will contain the Request ID number.

6.10.2 Event Description

Occurs if the Windows Default policy module denied a certificate request, thus the additional logic of TameMyCerts was not triggered at all for the given request. As this is a normal occurrence during PKI operations, this event is just informational.

6.11 Event ID 12

  • Event Log: Application
  • Event Source: TameMyCerts
  • Event Type: Information
  • Required certification authority LogLevel: 4 (CERTLOG_VERBOSE)

6.11.1 Event Sample

Request {0} for {1} will get issued.
  • Placeholder {0} will contain the Request ID number.
  • Placeholder {1} will contain the certificate template name.

6.11.2 Event Description

This is an informational event containing the request ID and the certificate template name in case TameMyCerts decides that the certificate request shall get issued.

6.12 Event ID 13

  • Event Log: Application
  • Event Source: TameMyCerts
  • Event Type: Information
  • Required certification authority LogLevel: 4 (CERTLOG_VERBOSE)

6.12.1 Event Sample

Request {0} for {1} will be put into pending state.
  • Placeholder {0} will contain the Request ID number.
  • Placeholder {1} will contain the certificate template name.

6.12.2 Event Description

This is an informational event containing the request ID and the certificate template name in case TameMyCerts decides that the certificate request shall be put into pending state.

6.13 Event ID 14

  • Event Log: Application
  • Event Source: TameMyCerts
  • Event Type: Warning
  • Required certification authority LogLevel: 3 (CERTLOG_WARNING)

6.13.1 Event Sample

The following warnings have been logged during the processing of request {0} for {1}:
{2}
  • Placeholder {0} will contain the Request ID number.
  • Placeholder {1} will contain the certificate template name.
  • Placeholder {2} will contain one or more warnings that have been logged during the processing of the certificate request.

6.13.2 Event Description

This event gets logged if warnings occurred during the processing of the certificate request. This event will get logged regardless if the certificate gets issued or not.

Warnings might indicate an abnormal condition. It is therefore recommended to collect these events and trigger an alert in your monitoring solution, if present.

Currently, TameMyCerts logs warnings in the following cases:

7 Technical Reference

7.1 Description of the “Pattern” directive

The Pattern parameter is defined as follows:

Parameter Mandatory Description
Expression yes Specifies the expression the field gets matched against.
TreatAs no Specifies how the expression is to be interpreted by TameMyCerts. Defaults to RegEx.
Action no Specifies if a match for the pattern will Allow the certificate to get issued (the default) or Deny the certificate request.

The TreatAs directive can be configured to one of the following values:

Value Description
RegEx Treat the value to be analyzed as a case sensitive regular expression (the default).
RegExIgnoreCase Treat the value to be analyzed as a case insensitive regular expression.
Cidr Treat the value to be analyzed as an IP address that must be within an IPv4 or IPv6 subnet in CIDR notation, e.g. 192.168.0.0/16.
ExactMatch The value to be analyzed must exactly match the configured expression (case sensitive).
ExactMatchIgnoreCase The value to be analyzed must exactly match the configured expression (case insensitive).

7.2 Description of the “DirectoryServicesAttribute” directive

The following Active Directory attributes are supported as “DirectoryServicesAttribute”:

Attribute In Global Catalog Remarks
c yes
co no
company no
department no
departmentNumber no
description yes
displayName yes
division no
dNSHostName yes Computer objects only
employeeID no
employeeNumber no
employeeType no
extensionAttribute1 no only available when Microsoft Exchange is used in the environment
extensionAttribute2 no only available when Microsoft Exchange is used in the environment
extensionAttribute3 no only available when Microsoft Exchange is used in the environment
extensionAttribute4 no only available when Microsoft Exchange is used in the environment
extensionAttribute5 no only available when Microsoft Exchange is used in the environment
extensionAttribute6 no only available when Microsoft Exchange is used in the environment
extensionAttribute7 no only available when Microsoft Exchange is used in the environment
extensionAttribute8 no only available when Microsoft Exchange is used in the environment
extensionAttribute9 no only available when Microsoft Exchange is used in the environment
extensionAttribute12 no only available when Microsoft Exchange is used in the environment
extensionAttribute10 no only available when Microsoft Exchange is used in the environment
extensionAttribute12 no only available when Microsoft Exchange is used in the environment
extensionAttribute11 no only available when Microsoft Exchange is used in the environment
extensionAttribute12 no only available when Microsoft Exchange is used in the environment
extensionAttribute13 no only available when Microsoft Exchange is used in the environment
extensionAttribute14 no only available when Microsoft Exchange is used in the environment
extensionAttribute15 no only available when Microsoft Exchange is used in the environment
facsimileTelephoneNumber no
gecos no
givenName yes
homePhone yes
homePostalAddress no
info no
initials no
l yes
location yes Computer objects only
mail yes
mailNickname no
middleName no
mobile no
name yes
otherMailbox no
otherMobile no
otherPager no
otherTelephone no
pager no
personalPager no
personalTitle no
postalAddress no
postalCode no
postOfficeBox no
sAMAccountName yes
sn yes
st yes
street yes
streetAddress no
telephoneNumber no
title no
userPrincipalName yes

7.3 Upgrade instructions

7.3.1 Upgrading TameMyCerts to version 1.7

Beginning with Version 1.7, TameMyCerts uses .NET 8.0 instead of the previously used .NET Framewotk 4.7.2. Therefore, you must install the .NET 8.0 Desktop runtime prior to installing the module.

Policy configuration files are now strictly processed, means that there will be errors raised when they contain invalid nodes. This may especially affect the following:

  • If policy configuration files still contain KeyAlgorithm nodes (which were removed with version 1.6), these must be removed from the configuration files.
  • The Action directives as well as the TreatAs directives for Pattern directives as processed case-sensitive, means that they must be specified exactly as documentated.

7.3.2 Upgrading TameMyCerts to version 1.6

If you are upgrading from a TameMyCerts version older than 1.6, you must adjust some elements in your policy configuration files.

  • Modifications of the Subject Distinguished Name has been moved out of the DirectoryServicesMapping. The directives have been renamed and the syntax has changed to enable advanced modifications of both Subject Distinguished Name (Subject DN) and Subject Alternative Name (SAN).

TameMyCerts version 1.5 and lower used the following syntax:

<DirectoryServicesMapping>
  <!-- other directives have been left out for simplicity -->
  <SubjectDistinguishedName>
    <RelativeDistinguishedName>
      <Field>emailAddress</Field>
      <DirectoryServicesAttribute>mail</DirectoryServicesAttribute>
      <Mandatory>true</Mandatory>
    </RelativeDistinguishedName>
  </SubjectDistinguishedName>
</DirectoryServicesMapping>

TameMyCerts version 1.6 and newer now uses the following syntax:

<DirectoryServicesMapping>
  <!-- other directives have been left out for simplicity -->
</DirectoryServicesMapping>
<OutboundSubject>
  <OutboundSubjectRule>
    <Field>emailAddress</Field>
    <Value>{ad:mail}</Value>
    <Mandatory>true</Mandatory>
    <Force>true</Force>
  </OutboundSubjectRule>
</OutboundSubject>

7.3.3 Upgrading TameMyCerts to version to 1.2 or newer

If you are upgrading from a TameMyCerts version older than 1.2, you must adjust some elements in your policy configuration files.

  • organizationalUnit under SubjectRule must be changed to organizationalUnitName.

TameMyCerts version 1.1 and lower used the following syntax:

<SubjectRule>
  <Field>organizationalUnit</Field>
  <!-- other directives have been left out for simplicity -->
</SubjectRule>

TameMyCerts version 1.2 now uses the following syntax:

<SubjectRule>
  <Field>organizationalUnitName</Field>
  <!-- other directives have been left out for simplicity -->
</SubjectRule>

7.3.4 Upgrading TameMyCerts to version to 1.1 or newer

If you are upgrading from a TameMyCerts version older than 1.1, you must adjust some elements in your policy configuration files.

  • AllowedPattern under SubjectRule must be changed to Pattern with differing syntax.
  • DisallowedPattern under SubjectRule must be changed to Pattern with differing syntax.

TameMyCerts version 1.0 used the following syntax:

<SubjectRule>
  <Field>commonName</Field>
  <AllowedPatterns>
    <string>^[-_a-zA-Z0-9]*\.tamemycerts\.com$</string>
  </AllowedPatterns>
  <DisallowedPatterns>
    <string>^.*(porn|gambling).*$</string>
  </DisallowedPatterns>
</SubjectRule>

TameMyCerts version 1.1 now uses the following syntax:

<SubjectRule>
  <Field>commonName</Field>
  <Patterns>
    <Pattern>
      <Expression>^[-_a-zA-Z0-9]*\.tamemycerts\.com$</Expression>
    </Pattern>
    <Pattern>
      <Expression>^.*(porn|gambling).*$</Expression>
      <Action>Deny</Action>
    </Pattern>
  </Patterns>
</SubjectRule>

8 Appendix

8.1 Typical use cases for the TameMyCerts policy module

8.1.1 How TameMyCerts can secure mobile device deployments with Microsoft Intune and similar MDM systems

Enterprise use Mobile Device Management (MDM) products to provision and manage their mobile devices like smartphones, tablet computers or even entire desktop computers, over-the-air (OTA).

Common MDM products include:

  • Microsoft Intune
  • VMware Workspace One (previously known as AirWatch)
  • Ivanti MobileIron UEM
  • Jamf Pro
  • Baramundi Enterprise Mobility Management
  • BlackBerry Enterprise Mobility Suite
  • Sophos Mobile Control
  • SOTI MobiControl

All these systems follow a similar concept: They act as an intermediary between the managed device, the coprorate directory service, and the certification authority. All of them provide some kind connector to submit certificate requests to a Microsoft AD CS certification authority.

Microsoft Intune uses the Network Device Enrollment Service (NDES) (https://learn.microsoft.com/en-us/windows-server/identity/ad-cs/network-device-enrollment-service-overview) role as a connector between Intune and the certification authority. NDES, like the certificaton authority, allows for custom-developed policy modules. Microsoft provides a policy module for NDES in combination with Intune, therefore it is not possible to add another policy module to an Intune-enabled NDES instance. However, TameMyCerts, as it resides on the CA, can coexist perfectly well with an Intune-enabled NDES instance, including the Intune policy module there.

All MDM systems require the certificate template to be configured as an offline certificate template. This means that the certification authority must accept any identity contained in a certificate request. Furthermore, all certificate requests are submitted to the certification authority using a single service account. If this account is compromised or otherwise abused, if the MDM system is misconfigured or has a software flaw, the certification authority will issue virtually any possible identity, including those of the CEO or highly privileged system accounts and administrators, which can lead to a variety of security disasters.

The default deployment with a Microsoft Certification Authority using Active Directory Certificate Services makes the whole setup vulnerable to the Swiss Cheese Model (see https://en.wikipedia.org/wiki/Swiss_cheese_model for futrher information), in which all participating layers having a small flaw, which in combinations allow disasters to happen.

Swiss Cheese Model. Original image Source: Wikipedia by Davidmack, licensed under CC BY-SA 3.0.

TameMyCerts can restrict the requested certificate content to precisely-defined certificate fields as well as apply syntax rules to these. In addition, TameMyCerts is able to map requested identities back to their underlying Active Directory objects and can decide whether a certificate shall be issued based on enablement status, group memberships and other criteria.

Denying certificate requests for members of forbidden groups with TameMyCerts

8.1.2 How TameMyCerts can help establish digital signature processes in the enterprise

Many enterprises nowadays want to establish paperless processes to ease and speed up internal approval and signature processes. This has become even more important in the times of employees predominantly working remotely. Whilst Microsoft AD CS is capable of automating certificate issuance processes, its possibilities to influence the certificate content are limited.

TameMyCerts allows to define advanced rules to build the Subject Distinguished names or Subject Alternative Names with either statically defined values, or by pulling the necessary data from Active Directory. This drastically extends the possibilities of certificate Autoenrollment in the Windows ecosystem.

The digital signature as shown in Adobe Reader contains the users display name instead of its logon name

For example, you could populate a certificates Common Name with the displayName Active Directory attribute and set a static value for the organizationName field as well.

Populating the Subject Distinguished Name with values from ActiveDirectory as well as static values with TameMyCerts

8.1.3 How TameMyCerts can repair incoming certificate requests to make them RFC-compliant

Beginning with Version 58, Google decided to remove the support for certificates containing only a Subject Distinguished Name (Subject DN) (https://developer.chrome.com/blog/chrome-58-deprecations/#remove-support-for-commonname-matching-in-certificates). From thereon, certificates not containing a Subject Alternate Name in form of a DNS name were treated as invalid by Google Chrome. Soon, other major browser vendors adopted this approach.

This behavior is in compliance to the IETF RFC 2818 (https://tools.ietf.org/html/rfc2818) dating back to the year 2000. Certificates for web servers must therefore use the Subject Alternative Name (SAN) for their identity. Sadly, there are still a lot of products in use that are not capable of creating a Certificate Signing Request containing a SAN in form of a DNS name.

Sadly, many HowTos on the web instruct CA administrators to enable the EDITF_ATTRIBUTESUBJECTALTNAME2 flag on their CAs in the belief this would enable them the issuance of SANs for certificate requests not containine one. However, doing so opens a large security hole, as this setting allows anyone to request any identity for any certificate template published on the certification authority.

Luckily, there are better ways to reach the intended goal.

With TameMyCerts, there is a secure, yet automatic method available to fix those certificates without the need of enabling insecure flags on the CA. TameMyCerts can be instructed to transfer the content of the Subject Distinguished Name into a Subject Alternative Name (SAN) extension prior to issuing the certificate. Furthermore, TameMyCerts ensures that attempts to abuse the certification authority are detected and such requests wil get denied, should an insecure flag still be enabled.

Supplementing DNS Names with TameMyCerts

8.1.4 How TameMyCerts can reduce severity of attacks against the ESC1 attack vector

Attacks on Microsoft certification authorities include the abuse of permissions on certificate templates. In many cases, certificate templates must be configured to allow the enrollee request any kind of identity, which can lead to account impersonation and elevation of privileges. These kinds of attacks are known as ESC1 (https://posts.specterops.io/certified-pre-owned-d95910965cd2) in the security scene.

ESC1 abuses a certificate template that is configured with the “Enrollee supplies subject” setting enabled (also called an “offline” certificate template, because the identity is provided by the enrollee, as opposed to an “online” certificate template where the certificate identity is built from Active Directory based on the enrollee’s logon information). The adversary would have to submit a certificate request containing a “malicious” Subject Alternative Name certificate extension.

A certificate template that allows the enrollee to supply the identity of the issued certificate in the certificate request

TameMyCerts can contain the damage done in such a case, and in even prevent the attack in many cases:

  • TameMyCerts can enforce identity types and thus ensure that only defined certificate fields are allowed to get issued.
  • TameMyCerts can apply syntax rules to certificate requests and thus ensure that certificates only get issued if the certificate content matched defined naming conventions.
  • TameMyCerts can map requested identities back to the according object in Active Directory and apply rules bases on accont status, security group or organizational unit membership.

Rule violations are being logged and thus allow alerting on policy violations.

A certificate request not containing required fields and containing forbidden fields was denied by TameMyCerts
A certificate request triggering blacklisted words was denied by TameMyCerts
A certificate request violating syntax rules was denied by TameMyCerts
A certificate request for a user not being member of any allowed group was denied by TameMyCerts
A certificate request for a non-existing user was denied by TameMyCerts
A certificate request for an account residing in the wrong OU was denied by TameMyCerts
A certificate request for a disabled account was denied by TameMyCerts
A certificate request containing a forbidden extension was denied by TameMyCerts

8.1.5 How TameMyCerts can detect and stop attacks against the ESC6 and ESC7 attack vector

Many HowTos on the web instruct CA administrators to enable the EDITF_ATTRIBUTESUBJECTALTNAME2 flag on their CAs. However, this opens a large security hole, as this setting allows anyone to request any identity for any certificate template. These kinds of attack against Microsoft Active Directory Certificate Services have widely become known as ESC6 and ESC7 (https://posts.specterops.io/certified-pre-owned-d95910965cd2) in the security scene.

ESC6 abuses a certification authority that has the EDITF_ATTRIBUTESUBJECTALTNAME2 flag globally enabled. When this flag is enabled in the certification authoritys configuration - either by lack of knowledge or by accident - an attacker can send a malicious request attribute to the certification authority (https://www.gradenegger.eu/en/take-over-the-active-directory-overall-structure-with-the-flag-editf_attributesubjectaltname2/) whilst submitting a legitimate certificate request, instructing the certification authoritry to add the specified content to the Subject Alternative Name (SAN) extension of the issued certificate, regardless of certificate template security settings.

TameMyCerts ensures that such attempts to abuse the certification authority are detected and requests are denied, should the insecure flag be enabled. The denied certificate request is getting logged, so that an alert can be triggered.

This mechanism was adopted as a core part of the Certiception (https://github.com/srlabs/Certiception) honeypot toolkit for Active Directory Certificate Services and allows spotting adversaries trying to abuse a certification authority.

Preventing the ESC6 attack with TameMyCerts

Administrators sometimes enable the setting to be able to add SANs to certificate requests not containing them (e.g. because the host on which the original certificate request was made is not capable of requesting SANs). In the most common use case of Web Server certificates, certificates without a SAN (in form of a DNS Name) will get rejected by applications (any modern web browser like Mozilla Firefox, Google Chrome, Microsoft Edge, and so on). TameMyCerts provides a secure alternative to this approach in that it is able to detect DNS Names and IP addresses found in the Common Name of a certificate request and automatically transfer them to a newly-built SAN certificate extension.

8.2 Changelog for the TameMyCerts policy module

TameMyCerts has evolved into a reliable, secure and stable enterprise product. Many organizations around the world are relying on it to improve their security and their PKI workflows. Professional development, testing and documentation consumes a considerable amount of time and resources. Whilst still being fully committed on keeping source code available for the community, digitally signed binaries, a print-optimized documentation and priority support are benefits only available for customers with an active maintenance contract.

8.2.1 Version 1.7.1609.1089

This version was released on May 29, 2025.

  • The code base has been upgraded from .NET Framework 4.7.2 to .NET 8.0. Files are no longer installed into the System32 folder but under the Program Files directory. Also, the .NET 8.0 Desktop Runtime must be installed.
  • Policy configuration files are now strictly processed, means that there will be errors raised when they contain invalid nodes. This may especially affect the following:
    • If policy configuration files still contain KeyAlgorithm nodes (which were removed with version 1.6), these must be removed from the configuration files.
    • The Action directives as well as the TreatAs directives for Pattern directives as processed case-sensitive, means that they must be specified exactly as documentated.
  • Directory Services Mapping is now able to honor nested group memberships and resolve primary Groups (#38).
    • This is enabled by default and requires all Domain Controllers targeted by TameMyCerts to run on Windows Server 2016 or newer. It can be disabled via global flag.
  • Directory Services Mapping now supports restricting certificate issuance based on remaining password validity time (#34).
  • Introducing a new Validator enabling to verify Yubikey PIV attestation with a Microsoft certification authority (thanks to the contribution of Oscar Virot).
  • Introducing (verbose) Event IDs 12 and 13 that indicate certificate requests getting issued or put into pending state.
  • Introduding Event 14 which will contain warnings that occurred during the processing of a certificate request.
    • Currently, the detection of the san request attribute will get logged regardless if the dangerous EDITF_ATTRIBUTESUBJECTALTNAME2 flag is enabled or not.
    • This new behavior allows to silently detect attack attempts on the certification authority without raising suspicion.
  • Introducing a SupplementUnqualifiedNames switch to use in combination with supplementing of DNS names (both SupplementDnsNames and SupplementServicePrincipalNames). To keep compatibility with the previous behavior, this setting defaults to true. If set to false, supplementation logic will not include DNS names that are not fully qualified.
  • Directory Services mapping can now be configured to deny a certificate request in the case a matching object was found in the directory.
  • Introducing global settings for TameMyCerts which allows to define behavior that applies globally, regardless of the defined certificate templates (the default behavior stays as before):
    • Allow to set the default behavior to globally deny a certificate request when no policy configuration file is found for the requested certificate template.
    • Allow to certificate requests containing insecure request attribute and certification authority flag combinations to get issued (Only for testing purposes. Use at your own risk!).
    • Disable the resolving of nested Group Memberships.
  • Introducing support for adding custom certificate extensions with static values to issued certificates (e.g. OCSP Must-staple or Microsoft Hyper-V/SCVMM Virtual Machine Connection).
  • Fix the module denying certificate requests with error 0x80131500 when the certificate request contains a Subject Alternative Name extension with empty content (#20).
  • Fix the installer script not removing the event source on uninstall (#22).
  • Since Windows Server 2012 R2 is now out of support by Microsoft, support by TameMyCerts has been dropped as well.
  • Improved documentation, especially description of event logs and use cases.

8.2.2 Version 1.6.1045.1129

This version was released on Nov 12, 2023.

This is a major release containing lots of bug fixes for edge-cases as well as many new exciting features, whilst (mostly) staying backwards-compatible to existing configuration files.

  • TameMyCerts now supports modifying the Subject Distinguished Name and Subject Alternative Name of issued certificates with attributes of mapped Active Directory objects, values from certificate request fields, static strings, or a combination of all these. Note that this breaks existing policy files. These must be adjusted when upgrading.
  • TameMyCerts now implements caching for policy configuration files. Instead of loading them over and over again for any incoming request, this is now only done if the file has changed..
  • TameMyCerts now supports configuring per-Template CRL Distribution Point, Authority Information Access, and Online Certificate Status Protocol URIs. Configure them with the CrlDistributionPoints, AuthorityInformationAccess and OnlineCertificateStatusProtocol directives.
  • TameMyCerts now automatically determines the desired key algorithm from the certificate template. The KeyAlgorithm parameter has therefore been removed. Existing configurations will continue to work but without using the configured KeyAlgorithm.
  • TameMyCerts now reads all available request properties directly from the certification authority instead of parsing the inline request. The inline certificate request will now only be parsed when AllowedProcesses or DisallowedProcesses directives are configured, as this information cannot be obtained from the CA directly. There are rare cases where it may not be possible to parse the inline certificate request. In this case, the requested properties will be treated as non-existent.
  • TameMyCerts now supports the DSA key algorithm for incoming certificate requests.
  • TameMyCerts now detects if a resulting certificate wouldn’t contain any identity, and will deny such a request by default. This allows to make both commonName and Subject Alternative Name fields optional at the same time in a policy, whilst ensuring a certitificate request has one of them set. The behavior can be disabled with the PermitEmptyIdentities parameter.
  • Directory Services mapping now supports the SupplementServicePrincipalNames directive. This mode allows to automatically add all DNS names found in the Service Principal Names (SPNs) of mapped AD objects to the SAN extension of issued certificates.
  • Directory Services mapping now allows to specify Pattern directives like in Subject or SAN rules that can get applied all of the attributes that can be used for building the Subject Distingushed Name.
  • Directory Services mapping now allows to filter based on organizational unit memberships of mapped AD objects with the AllowedOrganizationalUnits and DisallowedOrganizationalUnits parameters.
  • Directory Services mapping now allows adding the SID of a mapped AD object into the Subject Alternative Name (SAN) extension of an issued certificate as introduced by Microsoft in April 2023. The directive is called AddSidIUniformResourceIdentifier.
  • Pattern directives now support the new RegExIgnoreCase kind for the TreatAs attribute, which allows a regular expression to be treated case-insensitive.
  • Pattern directives now support the new ExactMatch and ExactMatchIgnoreCase kinds for the TreatAs attribute, which allow simple value comparisons, either case sensitive or case-insensitive.
  • Pattern directives now support matching IPv6 addresses against CIDR masks when TreatAs is set to Cidr.
  • Supplementing DNS names from the Subject DN can now append missing entries to an existing SAN certificate extension (instead of only building a new one as it was before). Same goes for all other cases that potentially build or modify the SAN extension.
  • The new mode to interpret the Subject Distinguished Name introduced with version 1.5 now correctly handles multiple RDNs of same type.
  • When TameMyCerts is unable to interpret a policy configuration file, the error message now contains more detailed information about the possible cause.
  • Fix a bug causing to allow blacklisted patterns when an invalid kind for the TreatAs attribute was specified for a Pattern in a Subject or SAN rule.
  • Fix a bug potentially allowing LDAP injections via requested certificate content.
  • Fix a bug causing requests getting denied when a template name contains invalid file name characters.
  • Fix a bug in the installer script preventing to run it without arguments.

8.2.3 Version 1.5.760.827

This version was released on Jan 31, 2023.

This is a quality improvement only release. TameMyCerts now uses the interfaces provided by the certification authority to determine Subject and Subject Alternative Name information.

  • Fix a security vulnerability causing nested certificate requests to bypass subject alternative name rule processing. All users of previous versions are urged to upgrade!
  • Subject RDN inspection is now done against the properties constructed by the certification authority (how the CA would issue the certificate. Previously it was done against the original inline PKCS#10 certificate request). This should enhance compatibility with malformed certificate requests but does not work with undefined relative distinguished names. Behavior can be changed back to previous logic by setting ReadSubjectFromRequest to true in request policy.
  • Enhance logging for directory service query failures.
  • Refactor the code for building the security identifier certificate extension.

8.2.4 Version 1.4.728.502

This version was released on Dec 30, 2022.

This is a quality improvement only release. TameMyCerts is now covered by automated integration tests which allow testing parts of the code base otherwise not testable with unit tests.

  • Fix a bug causing directory mapping not finding all of mapped object’s attributes when using global catalog (no SearchRoot configured in policy) to find an object.
  • Fix a bug causing to not display the correct error message in case no connection to Active Directory is possible during directory validation.
  • Fix a bug causing certificate modifications made by TameMyCerts are not applied when a template is configured to put requests in pending state.
  • Fix a bug causing to falsely log that a certificate request would get denied even if there is no reason to when policy is configured in audit mode.
  • Fix a bug causing the StartDate request attribute not getting applied if no policy is configured for the given certificate template.
  • Fix a bug causing request attributes to get processed case-sensitive which would allow circumventing security measures.
  • Fix a bug causing directory mapping to fail when the userPrincipalName attribute is not populated for an account (even if is was not used for mapping). Due to this, mapped accounts are now identified and logged with their distinguishedName attribute instead oder userPrincipalName.
  • Fix a bug causing an exception with directory mapping when the telexNumber directory attribute is populated for an object, as the property is not of string data type. Support for the telexNumber directory attribute has therefore been dropped.
  • Fix a bug causing requests using a valid process name to get denied when only DisallowedProcesses is configured.
  • Fix a bug causing requests using a valid cryptographic provider to get denied when only DisallowedCryptoProviders is configured.
  • Attributes used for modification of a certificate’s subject distinguished name are now only retrieved from AD if the feature is enabled for a certificate template.

8.2.5 Version 1.3.683.747

This version was released on Nov 15, 2022.

  • Implement support for (over)writing the subject relative distinguished name (RDN) of issued certificates with configurable attributes from a mapped Active Directory object.
  • Implement support for supplementing missing DNS names and IP addresses from commonName field in subject distringushed name into the subject alternative name of the issued certificate. This is to automatically make issued certificates compliant to IETF RFC 2818.
  • Add option to issue certificates for mapped acounts that are disabled (e.g. to prestage certificates in combination with the StartDate attribute functionality).
  • Add option to remove Security Identifier (szOID_NTDS_CA_SECURITY_EXT) certificate extension when provided in a certificate request instead of denying it entirely (Remove keyword for the SecurityIdentifierExtension directive).
  • Key rules can now also be applied to requests for online certificate templates.
  • Fix string substitution for the serialNumber, unstructuredName and unstructuredAddress relative distinguished name types.
  • Fix a bug preventing the use of the “any” IPv4 CIDR mask (0.0.0.0/0) in a subject rule.
  • Fix a bug in installer script not updating policy directory.

8.2.6 Version 1.2.587.662

This version was released on Aug 11, 2022.

  • Implement support for looking up identities that are requested in offline templates against Active Directory (called “directory mapping”). It may be specified if a certificate request shall get denied if a matching user or computer account does not exist, is disabled, if it is member of a forbidden group, or not member of any permitted group.
  • Implement support for adding the new Security Identifier (szOID_NTDS_CA_SECURITY_EXT with object id 1.3.6.1.4.1.311.25.2) certificate extension that was introduced with KB5014754 to certificates issued for offline certificate requests (requires directory mapping). This should enable users to prevent authentication to fail when strong certificate mapping will be enforced on February 11, 2025.
  • Implement protection against forgery of the szOID_NTDS_CA_SECURITY_EXT certificate extension by the enrollee. Policy can be configured to deny or allow offline requests containing this extension (default is to deny).
  • Implement support for specifying a fixed expiration date on a per-template basis.
  • Implement proper logging for processing of the StartDate request attribute and align behavior with Windows Default policy module.
  • Fix a bug causing the module to return the validation result too early. This had no effect on security but not all violations against the ruleset would get logged, making troubleshooting somewhat more difficult.
  • Fix a bug causing the module to throw an exception in the case a SAN extension could not be parsed.
  • Fix the organizationalUnitName RDN to align with X.520 specifications (it was wrongly called organizationalUnit in earlier versions). Note that this breaks existing policy files. These must be adjusted when upgrading.
  • Remove code for denying certificate requests containing the Subject Directory Atttributes (2.5.29.9) request extension, as this is disabled for issuance on AD CS by default anyway.
  • Remove excessive calling of garbage collection which should improve processing performance.

8.2.7 Version 1.1.432.1215

This version was released on Mar 10, 2022.

  • Change logic for allowed and disallowed patterns on SubjectRule directives. Now, for each defined “field” it is possible to specify how the expression will get treated (regular expression or CIDR notation), which allows for IP addresses to get verified if they are present in fields other that the iPAddress alternative name field. Note that this breaks existing policy files. These must be adjusted when upgrading.
  • Implement support for applying rules on process names used to create certificate requests for both online and offline certificate templates.
  • Implement support for applying rules on cryptographic providers used to create certificate requests’ private keys for both online and offline certificate templates.
  • Implement support for custom NotBefore date on a certificate with the StartDate request attribute, in analogy to the ExpirationDate request attribute supported by the Windows Default policy module.
  • Implement basic protection against abuse of having the EDITF_ATTRIBUTESUBJECTALTNAME2 flag enabled. Requests with a san attribute get denied if the flag is enabled.
  • Fix a bug causing the module to log an exception for requests with invalid ExpirationDate attribute.
  • SubjectRule Field definition is now processed case insensitive.
  • Change required .NET Framework 4.7.2 due to end of life of previously used version 4.6.
  • General code optimization that should slightly increase processing performance and overall maintainability of the code.
  • install.ps1 is now also digitally signed.

8.2.8 Version 1.0.410.1186

This version was released on Feb 15, 2022.

This is the initial release of TameMyCerts made publicly available.

8.3 Abbreviations

Abbreviation Description
ACME Automatic Certificate Management Environment
AD CS Active Directory Certificate Services
AD DS Active Directory Domain Services
AIA Authority Information Access
CA Certification Authority
CDP CRL Distribution Point
CN Common Name
CRL Certificate Revocation List
CSR Certificate Signing Request
CRLDP CRL Distribution Point
DN Distinguished Name
DNS Domain Name System
ETW Event Tracing for Windows
GC Global Catalog
HTTP HyperText Transfer Protocol
HTTPS HyperText Transfer Protocol, Secure
IETF Internet Engineering Task Force
IP Internet Protocol
IPv4 Internet Protocol Version 4
IPv6 Internet Protocol Version 6
ITU-T International Telecommunication Union Telecommunication Standardization Sector
LDAP Lightweigt Directory Access Protocol
MDM Mobile Device Management
MMC Microsoft Management Console
NAC Network Access Control
NDES Network Device Enrollment Service
OCSP Online Certificate Status Protocol
PIV Personal Identity Verification
PKI Public Key Infrastructure
RA Registration Authority
RDN Relative Distinguished Name
REST Representational State Transfer
RFC Request for comment
SAN Subject Alternative Name
SCEP Simple Certificate Enrollment Protocol
SID Security Identifier
URI Uniform Resource Identifier
URL Uniform Resource Locator
VA Validation Authority
XML eXtended Markup Language