Windows · Active Directory

Kerberos Delegation Types

Unconstrained, constrained, and resource-based delegation all let one service reuse a user’s identity to call a second service, but each draws the trust boundary in a very different place.

Quick idea: Kerberos delegation lets a front-end service reuse a user’s authenticated identity to call a back-end service on their behalf. Unconstrained delegation trusts the front-end service with that identity everywhere; constrained and resource-based delegation each narrow the trust to a specific, enforced list of targets.
Unconstrained

The front-end server can impersonate any authenticated user against any service in the forest. Legacy, and the highest-risk option.

Constrained (KCD)

The KDC enforces a fixed list of back-end services a front-end account may delegate to, set on the front-end account itself.

Resource-Based (RBCD)

The back-end resource owner decides which front-end accounts may delegate to it. Works across domains and forests.

What Is Kerberos Delegation?

Delegation exists to solve the double-hop problem. A user authenticates to a front-end service, and that service then needs to act as the same user against a second, back-end service — without ever holding the user’s password. A web application querying a SQL Server database as the logged-in user, rather than as its own generic service account, is the textbook case.

Think of delegation as a power of attorney: it lets one service temporarily act on a user’s behalf when it reaches a second service, without the user needing to be present to authenticate again. What differs between the three delegation types is how tightly that power of attorney is scoped, and who gets to write the scope.

The mechanism is a set of extensions to the Kerberos protocol defined in [MS-SFU]: Service for User to Self (S4U2Self), which lets a service obtain a ticket to itself on behalf of a user who didn’t authenticate to it with Kerberos directly, and Service for User to Proxy (S4U2Proxy), which lets that service present the resulting ticket to the KDC to obtain a service ticket to a back-end service, still in the user’s name.

Important: All three delegation types use the same underlying S4U extensions. What changes is which account controls the delegation list, whether that list exists at all, and whether the front-end and back-end services have to share a domain.

Unconstrained Delegation

Unconstrained delegation is the original, and now discouraged, form. When an account is trusted for delegation, the KDC includes a copy of a client’s ticket-granting ticket (TGT) inside the service ticket that client presents to it. The service can then use that cached TGT to request a ticket to any service in the forest, on the client’s behalf, with no list of allowed targets at all.

That is also the risk. If an attacker compromises a server trusted for unconstrained delegation, and a privileged account ever authenticates to it, the attacker can extract that account’s cached TGT from memory and impersonate it anywhere in the forest — not just against the service the server was meant to run.

Production note: Domain controller computer accounts are trusted for delegation by design; that’s expected and covered by their own Tier-0 protections. The risk this section describes is unconstrained delegation left enabled on ordinary member servers and service accounts, which should be audited and removed wherever the workload doesn’t genuinely require it.

Two built-in controls limit unconstrained delegation without touching the account itself. Members of the Protected Users group cannot be delegated with any delegation type, constrained or unconstrained — Kerberos simply stops issuing the cached long-term credentials delegation depends on. Separately, on a system with Credential Guard enabled (Windows 10, Windows Server 2016, and later), unconstrained delegation is blocked outright; only constrained delegation is available.

Constrained Delegation (KCD)

Constrained delegation replaces “delegate to anything” with an explicit list. The front-end account’s msDS-AllowedToDelegateTo attribute holds the service principal names (SPNs) of the back-end services it’s allowed to reach, and the KDC enforces that list at ticket-request time via S4U2Proxy — the front-end account can no longer act as the user against a service that isn’t named.

There’s a second decision alongside the allow-list: whether the front-end service can use protocol transition. If the front-end account is only trusted for delegation to specified services using Kerberos, the user must already have authenticated to it with Kerberos. If it’s also trusted to authenticate for delegation using any protocol — the TRUSTED_TO_AUTH_FOR_DELEGATION flag — the front-end service can use S4U2Self to obtain a ticket for the user even when the user authenticated some other way, such as forms-based authentication, and then delegate that ticket onward. This is what lets a web front end delegate to a back end even though the browser never did Kerberos with it directly.

Key rule: Classic constrained delegation requires the front-end and back-end accounts to live in the same domain. If they’re in different domains or forests, constrained delegation as described here doesn’t apply — resource-based constrained delegation is the supported path instead.

Resource-Based Constrained Delegation (RBCD)

Resource-based constrained delegation, introduced with Windows Server 2012, inverts who owns the delegation list. Instead of the front-end account declaring what it may delegate to, the back-end resource account declares which front-end accounts are allowed to delegate to it, using its own msDS-AllowedToActOnBehalfOfOtherIdentity attribute. Control moves from the domain admin managing the front-end account to the administrator who actually owns the back-end resource.

That change in ownership is also what makes RBCD work across domain and forest boundaries, since the resource owner doesn’t need any authority over the front-end account’s domain to grant it access — only over their own object. It’s the delegation model recommended for new deployments, including Microsoft Entra Domain Services, where administrators don’t have domain-admin rights to configure the classic account-based form at all.

RBCD always allows protocol transition; there’s no separate flag to set, because control already sits entirely with the resource owner. Two well-known SIDs — AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY and SERVICE_ASSERTED_IDENTITY — let a back-end service tell, via standard ACL checks, whether a caller’s identity was asserted directly by the KDC or asserted by an intermediate service through protocol transition.

Why the Distinction Matters

Every delegation type ultimately grants the same capability: acting as another user without their password. What differs is the blast radius when the delegating account is compromised. Unconstrained delegation has none — any cached TGT from any user who touched that server is exposed. Constrained delegation limits the blast radius to a named, finite list of services. Resource-based delegation goes further by putting that list under the control of the party with the most to lose if it’s wrong.

This is also why delegation shows up constantly in attack path analysis. An account trusted for unconstrained delegation, or with a permissive msDS-AllowedToDelegateTo or msDS-AllowedToActOnBehalfOfOtherIdentity list, is a privilege-escalation target regardless of how it was originally intended to be used. Auditing what’s actually configured against what’s actually needed is worth doing on a schedule, not just once at deployment.

Configuring Delegation

For a regular user or computer account with an SPN, delegation is configured from the Delegation tab in Active Directory Users and Computers (Properties → Delegation). Group Managed Service Accounts and standalone Managed Service Accounts don’t get a Delegation tab at all — for those, the same attributes have to be set directly with PowerShell.

Delegation Type GUI Option (Delegation tab) PowerShell
Unconstrained Trust this computer/user for delegation to any service (Kerberos only) Set-ADAccountControl -Identity websvc01 -TrustedForDelegation $true
Constrained, Kerberos only Trust this user for delegation to specified services only → Use Kerberos only Set-ADUser -Identity websvc01 -Add @{'msDS-AllowedToDelegateTo'=@('HTTP/backend01.corp.example.com')}
Constrained, protocol transition Trust this user for delegation to specified services only → Use any authentication protocol Set-ADAccountControl -Identity websvc01 -TrustedToAuthForDelegation $true
Resource-based Not exposed in the Delegation tab — configured entirely from the back-end account Set-ADComputer backend01 -PrincipalsAllowedToDelegateToAccount (Get-ADComputer websvc01)

For a user or service account instead of a computer account, the resource-based command is the same shape with Set-ADUser or Set-ADServiceAccount in place of Set-ADComputer.

Practical note: To remove delegation entirely, clear the flags and the attribute rather than leaving them half-set: Set-ADAccountControl -Identity websvc01 -TrustedForDelegation $false -TrustedToAuthForDelegation $false followed by Set-ADObject websvc01 -Clear 'msDS-AllowedToDelegateTo'.

Auditing Delegation with PowerShell

Because delegation is a standing grant rather than a one-time action, it needs periodic auditing the same way stale group memberships do.

# Find every computer account trusted for unconstrained delegation
Get-ADComputer -Filter {TrustedForDelegation -eq $true} -Properties TrustedForDelegation

# Find every user account trusted for unconstrained delegation
Get-ADUser -Filter {TrustedForDelegation -eq $true} -Properties TrustedForDelegation

# List every account with a classic constrained-delegation allow-list
Get-ADObject -Filter {msDS-AllowedToDelegateTo -like '*'} -Properties msDS-AllowedToDelegateTo |
    Select-Object Name, msDS-AllowedToDelegateTo

# Show which principals are allowed to delegate to a specific resource (RBCD)
Get-ADComputer backend01 -Properties PrincipalsAllowedToDelegateToAccount |
    Select-Object -ExpandProperty PrincipalsAllowedToDelegateToAccount

# Confirm an account cannot be delegated at all (Protected Users-style hardening)
Set-ADAccountControl -Identity SQLAdmin1 -AccountNotDelegated $true

Delegation Types at a Glance

Type Who Controls the List Cross-Domain Risk if Compromised
UnconstrainedNo list — trusts everythingYes, forest-wideAny cached user TGT usable anywhere
Constrained (KCD)Front-end account’s msDS-AllowedToDelegateToNo, same domain onlyLimited to the named back-end SPNs
Resource-based (RBCD)Back-end account’s msDS-AllowedToActOnBehalfOfOtherIdentityYes, across domains/forestsLimited to whichever front-end accounts the resource owner listed

Troubleshooting Cheat Sheet

Symptom Likely Cause Fix
Delegated call fails, front-end and back-end in different domains Classic constrained delegation can’t cross a domain boundary. Switch to resource-based delegation, configured from the back-end account with PrincipalsAllowedToDelegateToAccount.
Delegation works for Kerberos clients but not for a web front end using forms auth Front-end account isn’t trusted for protocol transition. Enable it: Set-ADAccountControl -Identity websvc01 -TrustedToAuthForDelegation $true.
Delegation silently stops working for a specific account after a security hardening pass The account was added to Protected Users, which blocks all delegation regardless of configuration. Confirm group membership; if the account genuinely needs delegation, it cannot also be a Protected Users member.
Unconstrained delegation won’t work on a hardened member server Credential Guard is enabled and blocks unconstrained delegation outright. Reconfigure the service to use constrained or resource-based delegation instead of relying on unconstrained.
Managed Service Account has no Delegation tab in ADUC gMSAs and standalone MSAs don’t expose the Delegation tab. Set the flags directly: Set-ADAccountControl for the UAC flags and Set-ADServiceAccount -Add or -Clear for msDS-AllowedToDelegateTo.

Final Thoughts

Unconstrained, constrained, and resource-based delegation aren’t three unrelated features — they’re the same S4U mechanism with progressively tighter, and progressively better-owned, boundaries around it. Unconstrained delegation trusts a server with everything a user could ever authenticate to; constrained delegation names the destinations up front; resource-based delegation hands that naming decision to the administrator who actually has to live with the consequences.

For new deployments, resource-based delegation should be the default starting point, not something reached for only when a cross-domain scenario forces the issue. Unconstrained delegation is worth actively hunting for and removing wherever it isn’t a domain controller.

Key takeaway: If an account doesn’t need to reach every service in the forest, it shouldn’t be trusted for unconstrained delegation — a scoped msDS-AllowedToDelegateTo list or, better, resource-based delegation configured from the back-end account gets the same double-hop working with a fraction of the exposure.
Next in this series

The Kerberos constrained delegation troubleshooting post covers what to do when a specific delegation setup stops working; this post is the map of which model to reach for in the first place.