Skip to content
03 · DelegationPart 1 of 4Foundation

Active Directory delegation: finding and fixing risky trusts

Audit unconstrained, constrained, and resource-based constrained delegation in Active Directory, and lock down privileged accounts against abuse.

Florian Amette6 min read

Kerberos delegation lets a front-end service act on behalf of a user against a back-end service — the classic case is a web application querying a SQL Server as the logged-in user rather than as itself. It's a legitimate and sometimes necessary feature, but each of its three implementations creates a trust relationship that, if placed on the wrong server or account, gives an attacker who compromises that one machine a path to impersonate other users, often including administrators.

This guide covers how the three delegation types differ, how to inventory every delegation relationship in your domain, and how to lock down the accounts that should never be delegable at all.

The three delegation types

TypeConfigured onControlling attributeScope
UnconstrainedFront-end computer/service accountuserAccountControl flag TRUSTED_FOR_DELEGATIONCan impersonate any authenticated user to any service in the domain
ConstrainedFront-end computer/service accountmsDS-AllowedToDelegateToCan impersonate users only to the specific services listed
Resource-based constrained (RBCD)Back-end resource (target computer)msDS-AllowedToActOnBehalfOfOtherIdentityBack-end decides which front-ends may delegate to it; works across domains/forests

Unconstrained delegation

When a user authenticates via Kerberos to a server trusted for unconstrained delegation, the client sends a forwarded copy of the user's TGT along with the service ticket, and the server caches it in memory. That server can now replay the TGT to request tickets to any service, as that user, indefinitely (until the TGT expires). If a Domain Admin ever authenticates to that box — even just to browse a file share — their TGT is sitting in memory for the taking.

By default, all domain controllers are trusted for unconstrained delegation (required for their normal function). The critical rule: no server other than a domain controller should have this flag set. It was a common legacy default on print servers, older IIS boxes, and misconfigured application servers, and it remains one of the highest-value footholds an attacker can find.

Constrained delegation

Introduced in Windows Server 2003, constrained delegation restricts the front-end to impersonating users only toward an explicit list of back-end SPNs, set via msDS-AllowedToDelegateTo on the front-end account. It also supports "protocol transition" (TRUSTED_TO_AUTH_FOR_DELEGATION), letting the front-end obtain a ticket on a user's behalf even without a prior Kerberos hop — useful for web apps authenticating users via forms/other means but still needing to delegate to a back-end. This is safer than unconstrained but still risky: whoever controls the front-end account can impersonate any user (including admins) to every service in that allow-list.

Resource-based constrained delegation (RBCD)

Introduced in Windows Server 2012, RBCD flips where the trust is configured: instead of the front-end declaring where it may delegate, the back-end resource declares which front-end accounts are allowed to act on its behalf, via msDS-AllowedToActOnBehalfOfOtherIdentity. This is more flexible (works across domain/forest boundaries, doesn't require Domain Admin rights to configure — just write access to the target computer object) but that flexibility is also the risk: anyone with GenericWrite/WriteProperty on a computer object can grant themselves RBCD rights to impersonate users against it, including via machine account creation privileges that many users hold by default (ms-DS-MachineAccountQuota).

Finding delegation in your domain

Run a full inventory before deciding what to fix. This should be a recurring audit, not a one-time exercise.

PowerShell
# Unconstrained delegation — computers and users (should be empty except DCs)
Get-ADComputer -Filter 'TrustedForDelegation -eq $true' -Properties TrustedForDelegation, servicePrincipalName |
    Select-Object Name, DistinguishedName

Get-ADUser -Filter 'TrustedForDelegation -eq $true' -Properties TrustedForDelegation |
    Select-Object Name, DistinguishedName

# Constrained delegation — accounts with msDS-AllowedToDelegateTo populated
Get-ADComputer -Filter * -Properties msDS-AllowedToDelegateTo, TrustedToAuthForDelegation |
    Where-Object { $_."msDS-AllowedToDelegateTo" } |
    Select-Object Name, msDS-AllowedToDelegateTo, TrustedToAuthForDelegation

Get-ADUser -Filter * -Properties msDS-AllowedToDelegateTo, TrustedToAuthForDelegation |
    Where-Object { $_."msDS-AllowedToDelegateTo" } |
    Select-Object Name, msDS-AllowedToDelegateTo, TrustedToAuthForDelegation

# Resource-based constrained delegation — PrincipalsAllowedToDelegateToAccount is the
# ActiveDirectory module's decoded view of the msDS-AllowedToActOnBehalfOfOtherIdentity descriptor
Get-ADComputer -LDAPFilter '(msDS-AllowedToActOnBehalfOfOtherIdentity=*)' `
    -Properties PrincipalsAllowedToDelegateToAccount |
    Select-Object @{n='Computer';e={$_.Name}},
        @{n='DelegatedFrom';e={$_.PrincipalsAllowedToDelegateToAccount -join '; '}}

For every unconstrained hit outside the Domain Controllers OU, treat it as a critical finding requiring immediate remediation. For constrained and RBCD hits, verify each one against a change record — delegation should be documented, deliberate, and reviewed, not an artifact of a forgotten proof-of-concept.

Removing unwanted delegation

PowerShell
# Remove unconstrained delegation from a non-DC computer account
Set-ADComputer -Identity "APP01" -TrustedForDelegation $false

# Remove constrained delegation entries
Set-ADComputer -Identity "APP02" -Clear msDS-AllowedToDelegateTo

# Clear RBCD on a resource
Set-ADComputer -Identity "SQL01" -Clear msDS-AllowedToActOnBehalfOfOtherIdentity

Protecting privileged accounts: "sensitive and cannot be delegated"

Regardless of what delegation exists elsewhere in the domain, privileged accounts should be explicitly excluded from ever being delegated, using the NOT_DELEGATED flag (userAccountControl bit, exposed as "Account is sensitive and cannot be delegated" in ADUC). This prevents any service — even a legitimately configured constrained delegation — from obtaining a ticket to impersonate that account.

PowerShell
# Apply to a single privileged account
Set-ADAccountControl -Identity "adm-t0-famette" -AccountNotDelegated $true

# Apply to every member of Domain Admins and Enterprise Admins
"Domain Admins", "Enterprise Admins" | ForEach-Object {
    Get-ADGroupMember -Identity $_ -Recursive |
        Where-Object { $_.objectClass -eq 'user' } |
        ForEach-Object { Set-ADAccountControl -Identity $_.SamAccountName -AccountNotDelegated $true }
}

Verify

PowerShell
Get-ADUser -Identity "adm-t0-famette" -Properties userAccountControl |
    Select-Object Name, @{n='NotDelegated';e={
        [bool]($_.userAccountControl -band 0x100000)
    }}

Membership in Protected Users (covered in Tier 0 & Privileged Access) provides an even stronger, overlapping protection — it blocks NTLM and unconstrained/constrained delegation for the account outright, without needing the NOT_DELEGATED flag set separately, and additionally hardens the Kerberos ticket lifetime and encryption requirements.

Why unconstrained delegation on a non-DC is critical

It bears repeating on its own because it's the single highest-value delegation misconfiguration: a compromised server trusted for unconstrained delegation becomes a credential trap that harvests every administrator's TGT the moment they touch it — no exploitation of the admin's own machine required. Combined with unconstrained delegation awareness training for infrastructure teams, this should be a standing item in any AD security review, checked every time a new server is provisioned, not just during periodic audits.

What it breaks

  • Web applications using Kerberos delegation to query back-end databases as the logged-in user (common with SharePoint, SSRS, and custom intranet apps) rely on constrained delegation — removing an entry from msDS-AllowedToDelegateTo without replacing it with the correct scoped entry breaks "run as user" functionality, forcing the app to fall back to a service account context or fail outright.
  • SQL Server linked servers configured for delegated authentication (rather than stored credentials) stop working if the SQL service account's delegation entries are cleared; audit and re-scope to constrained delegation with explicit SPNs rather than removing entirely.
  • Print servers and older application proxies that were historically granted unconstrained delegation as a blanket fix often silently depended on it; removing the flag can surface as intermittent "access denied" errors for double-hop scenarios (e.g., a user browsing a share through a print server that then needs to authenticate onward) — test in a maintenance window and be ready to reconfigure as properly scoped constrained delegation.
  • RBCD used by legitimate cross-domain resource access (e.g., a migration scenario or multi-forest application) will break if cleared without first re-provisioning the relationship through documented change control.

Related reading: Kerberos hardening for the ticket-forgery techniques that delegation abuse often chains into, and Tier 0 & Privileged Access for the account tiering that keeps delegable service accounts away from Tier 0 credentials. See also DCSync for what an attacker does after obtaining a Domain Admin TGT via delegation abuse.

Frequently asked questions

Why is unconstrained delegation so dangerous on a non-DC server?

A server trusted for unconstrained delegation receives and caches a copy of every user's TGT the moment they authenticate to it. If that server is compromised, the attacker extracts those cached TGTs and can impersonate any user who connected — including Domain Admins — to any service in the domain, with no further exploitation needed.

What is the difference between constrained delegation and resource-based constrained delegation (RBCD)?

Constrained delegation (msDS-AllowedToDelegateTo) is configured on the front-end account and lists which back-end services it may impersonate users to — the front-end decides. RBCD (msDS-AllowedToActOnBehalfOfOtherIdentity) is configured on the back-end resource and lists which front-end accounts may delegate to it — the resource decides, which also means anyone with write access to that resource's computer object can grant themselves delegation rights to it.

Does marking an account 'sensitive and cannot be delegated' stop all delegation abuse?

It stops that specific account's credentials from being used in any delegation flow (constrained, unconstrained, or RBCD), which is a strong protection for privileged accounts. It does not, however, prevent delegation abuse against other, unprotected accounts in the domain — it's one control among several, not a domain-wide fix.

Active Directory delegation: finding and fixing risky trusts

Related guides