SDProp Silently Reverts Direct Group ACL Edits
A helpdesk delegation added directly to the Domain Admins security descriptor disappears without warning inside an hour, while a stray ACE placed on AdminSDHolder itself propagates unchanged to every protected account domain-wide. Active Directory's SDProp cycle overwrites rather than merges ACLs, so standard change logs point at the wrong actor and break-glass access fails exactly when it's needed.
Operational summary
At a glance
- Symptom
- SDProp's next scheduled run replaces the protected object's ACL wholesale from AdminSDHolder, deleting the direct edit without an attributable removal event.
- Likely cause
- Custom ACEs applied directly to protected group objects instead of to CN=AdminSDHolder, relying on the default 3600-second SDProp cycle to leave them untouched.
- Impact
- Delegated Tier-0 recovery access vanishes silently, or a mistaken AdminSDHolder edit propagates domain-wide to every adminCount=1 account on the next cycle.
- Verification signal
- Re-run the detection test and a controlled negative-path test.
- Safe correction
- Write all protected-group delegation to AdminSDHolder via dsacls, force propagation with the RootDSE fixupInheritance modify, and diff the ACL against an approved baseline on schedule.
- Rollback or recovery
- Restore the exported configuration if the new control blocks required production traffic, then narrow the policy before redeployment.
The Trap
Direct ACE modification on protected group objects – Domain Admins, Enterprise Admins, Schema Admins, Backup Operators – instead of on the AdminSDHolder template object they inherit from. An engineer opens the Security tab in ADUC (or runs a scripted Set-Acl against the group’s distinguishedName), adds an ACE granting a Tier-1 helpdesk group Reset Password or Write Member rights, and confirms the change applied. It looks permanent because nothing challenges it immediately.
The Default State
SDProp runs on the PDC emulator on a fixed interval controlled by AdminSDProtectFrequency under HKLMSYSTEMCurrentControlSetServicesNTDSParameters, defaulting to 3600 seconds. Any object flagged adminCount=1 has its discretionary ACL replaced wholesale – not merged – with a verbatim copy of the ACL on CN=AdminSDHolder,CN=System,DC=<domain>. The vendor ships AdminSDHolder’s own ACL untouched from install, so any legitimate delegation must be written there, but every administrative tool makes it just as easy to write to the protected object directly, which is where most engineers instinctively look.
The Blast Radius
Because SDProp overwrites rather than merges, the custom ACE disappears with no deletion event tied to the person who added it. Directory Service Changes auditing (event 5136) attributes the change to the SDProp process context, not the operator, so incident response chases the wrong actor while the real cause – a scheduled propagation cycle – goes unreviewed. The operational failure surfaces at the worst time: a Tier-1 group’s delegated right to reset a locked-out Domain Admin account vanishes silently sometime in the preceding hour, breaking the break-glass procedure during an actual outage. The inverse failure is worse: if someone edits AdminSDHolder directly by mistake – adding a broad Authenticated Users ACE meant for one group – that ACE propagates unchanged to every adminCount=1 object domain-wide on the next cycle, instantly granting the error to Domain Admins, Enterprise Admins, Schema Admins and every historically protected account at once.
The Lead Mechanic Fix
Treat CN=AdminSDHolder,CN=System,DC=corp,DC=local as the only legitimate write target for protected-group delegation. Add rights there directly: dsacls “CN=AdminSDHolder,CN=System,DC=corp,DC=local” /G “CORPTier0-Helpdesk:CA;Reset Password;user” – never touch the group object’s own Security tab. After any AdminSDHolder change, force immediate propagation rather than waiting for the default 3600-second cycle: bind to RootDSE with ldp.exe and issue a Modify operation setting attribute fixupInheritance to 1 (Replace), which triggers SDProp synchronously so the change is validated in the same maintenance window it was made. Gate every AdminSDHolder write behind change control, and run a scheduled dsacls export compared against the last approved baseline, alerting on any delta submitted outside a ticket – this catches accidental edits to protected group objects and unauthorised AdminSDHolder tampering before the next SDProp cycle turns either one into a domain-wide grant.
Apply the safer control
Before you change production
Confirm the affected scope, export the current configuration, and test the replacement control in a non-production environment first.
Write all protected-group delegation to AdminSDHolder via dsacls, force propagation with the RootDSE fixupInheritance modify, and diff the ACL against an approved baseline on schedule.
Validate the vendor-specific syntax in official documentation before applying it.
Verify, roll back or escalate
Verify
Re-run the detection test and a controlled negative-path test. Confirm the unsafe behaviour is blocked while approved traffic still succeeds.
Rollback
Restore the exported configuration if the new control blocks required production traffic, then narrow the policy before redeployment.
Escalate
Escalate when the blast radius is uncertain, the control cannot be tested safely, or remediation requires an outage or security exception.