Create AD CS certificate template objects over LDAP, for authorized penetration-testing labs and AD CS research.
templify is a command-line tool that builds a complete
pKICertificateTemplate object (the LDAP representation of an Active
Directory Certificate Services template) and writes it directly into the
Certificate Templates container of a domain. It works against any reachable
domain controller over LDAP or LDAPS, needs no Windows-side tooling, and
prints an audit summary of every attribute it sets.
The tool is deliberately explicit about what it creates. It supports two
template modes, a hardened one and an intentionally vulnerable one, and in
both modes you must name the group that receives the Enroll right. Nothing
is written unless you confirm it (or pass -force).
- Resolves the configuration naming context and the Certificate Templates container automatically from the RootDSE.
- Builds the full attribute set of a v2 certificate template, including flags, key spec, key usage, validity periods, EKUs, application policies, the security descriptor, and a freshly generated template GUID and OID.
- Writes the security descriptor so that exactly one group holds the Certificate-Enrollment extended right, Authenticated Users can read the template, and Domain Admins keep full control for later management.
- Optionally publishes the new template to a CA by appending its name to
the CA's
certificateTemplatesattribute. - Checks the DC's schema first and skips attributes the forest does not
define (for example
msPKI-Certificate-Templateon older AD), with a clear warning about what was skipped and why. - Supports simple bind, NTLM password, pass-the-hash, and Kerberos (ccache or password-acquired TGT), over LDAPS with automatic fallback to plain LDAP.
- It does not restart the CA service. After creating and publishing a template, AD CS may need a restart (or its periodic template refresh) to serve enrollment requests for the new template.
- It does not issue certificates. To enroll against a template you created,
use an enrollment client such as Certipy's
reqor the Windows Certificate Management UI. - It cannot delete or modify templates. Only creation is implemented.
- Python 3.9 or newer.
- A reachable domain controller (LDAP ports 389/636, Kerberos port 88 for
-k). - An account with permission to create objects in
CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration(typically Domain Admins or Enterprise Admins). - The
gssapipackage for Kerberos binds (install thekerberosextra, see below).
Installs templify in its own isolated environment and puts the templify
command on your PATH:
pipx install 'https://github.com/jimmexploit/templify.git[kerberos]'
templify create ...Omit the [kerberos] extra if you do not need Kerberos binds.
git clone https://github.com/jimmexploit/templify.git
cd templify
python3 -m venv .venv && source .venv/bin/activate
pip install .
templify create ... # installed console script
python3 -m templify create ... # or just run from the repo root, no installFor Kerberos binds add the extra to the install: pip install '.[kerberos]'.
templify create -u DOMAIN\user -p PASSWORD -dc-ip <dc-ip> \
-name 'Template Name' -mode legit -enroll-group 'DOMAIN\Group'
All examples below assume a lab domain with a DC at 192.168.37.10.
templify create -u 'corp\operator' -p 'P@ssw0rd123!' -dc-ip 192.168.37.10 \
-name 'Lab Client Auth' -mode legit -enroll-group 'corp\Lab Enrollers'The legit mode builds a conservative v2 template: subject derived from
the enrollee's AD object, a single explicit EKU (Client Authentication by
default, never Any Purpose), CA manager approval enabled, non-exportable
keys on renewal, and enrollment restricted to the named group.
templify create -u 'corp\operator' -p 'P@ssw0rd123!' -dc-ip 192.168.37.10 \
-name 'Lab ESC1' -mode esc1 -enroll-group 'corp\Domain Users'The esc1 mode reproduces the ESC1 pattern from the SpecterOps "Certified
Pre-Owned" research: the enrollee supplies the subject name, manager
approval is off, no authorized signatures are required, and the key is
exportable. The tool prints a prominent warning before anything is written.
Use this mode only in an authorized penetration-testing lab or training
forest. Enrolling with arbitrary SANs or UPNs through such a template can
lead to full domain compromise.
templify create -u 'corp\operator' -p 'P@ssw0rd123!' -dc-ip 192.168.37.10 \
-name 'Lab ESC1' -mode esc1 -enroll-group 'corp\Domain Users' -dry-runThe dry run prints the full LDAP ADD, every attribute value with a plain English explanation, the security descriptor detail, and anything that will be skipped because the DC's schema does not define it.
templify create -u 'corp\operator' -p 'P@ssw0rd123!' -dc-ip 192.168.37.10 \
-name 'Lab Client Auth' -mode legit -enroll-group 'corp\Lab Enrollers' \
-enable-on-ca 'CORP-DC01-CA'After the template is created, its cn is appended to the
certificateTemplates attribute of the CA's pKIEnrollmentService object,
which enables it in the CA's UI. The CA service must be restarted (or its
template refresh interval must elapse) before it will serve requests for
the new template.
templify create -u 'corp\operator' -p 'P@ssw0rd123!' -dc-ip 192.168.37.10 \
-name 'Lab User Clone' -mode legit -clone-from 'User' \
-enroll-group 'corp\Lab Enrollers'Attributes are copied from the named template, excluding structural values
such as cn, distinguishedName, objectGUID, the security descriptor,
and the template GUID and OID. The selected mode's overrides are applied on
top of the clone.
| Option | Description |
|---|---|
-u corp\operator -p P@ssw0rd123! |
Simple bind with a password |
-u corp\operator -hashes :<nthash> |
NTLM pass-the-hash |
-u user@corp.local -k -p P@ssw0rd123! |
Kerberos, TGT acquired from the password |
-k -ccache /path/ticket.ccache |
Kerberos with an existing ccache |
-ntlm |
Force NTLM when using a bare -u user |
Kerberos requires the DC's clock to be within the default 5 minute skew tolerance of your machine. If it is not, templify warns you before the bind and explains how to fix it.
| Flag | Meaning |
|---|---|
-name |
Template cn; required |
-mode |
legit or esc1; required |
-enroll-group |
Group or SID granted the Enroll right; required in both modes |
-eku |
Explicit EKU OID or name; defaults to Client Authentication |
-enable-on-ca |
Publish the template to the named CA after creation |
-clone-from |
Copy non-conflicting attributes from an existing template |
-force |
Skip the confirmation prompt |
-dry-run |
Print the operations without executing them |
-debug |
Print full tracebacks on errors |
Every run prints:
- An attribute summary table, where each value is explained in plain English (for example which flag bits mean what, and which EKU is used).
- A security descriptor detail showing the owner, the Enroll grant, the read grant, and the protection state of the DACL.
- A warning listing any attributes that were skipped because the DC's schema does not define them.
- The blast radius is always explicit: the Enroll right goes to exactly the group you name, and no other Enroll grants are created.
- The EKU never defaults to Any Purpose.
- The
esc1mode prints a loud warning before doing anything. - Nothing is written without confirmation unless you pass
-force.
MIT. See the LICENSE file.