Active Directory FundamentalsActive Directory PoliciesRecent PostsTop Read Articles

SID filtering in complex AD layouts: the one-bit boundary that decides what crosses your forest

Complex AD layouts

Quick definition: SID filtering is a trust-side control that removes foreign SIDs—including values in SIDHistory—from a user’s authorization data as it traverses a trust. It prevents privilege escalation by honoring only the SIDs the trusting side expects.

Answer box (at a glance)

  • External/domain trusts: Quarantine=Yes by default → accept only SIDs from the directly trusted domain.
  • Forest trusts: EnableSidHistory=No by default → SIDHistory is not honored across the boundary unless you temporarily enable it for migrations.
  • Filtering occurs on the trusting DC that issues the service ticket; the resource server sees the already-filtered token.
Kerberos PACNetdom trustToken bloatSelective authentication

Why this matters now

Few enterprises run a single, tidy forest. You likely juggle account/resource forests, B2B external trusts, mergers, and carve-outs. In these layouts, a single flag on the trust—Quarantine or EnableSidHistory—decides whether a risky SID sneaks across or a migration proceeds without breaking access.

Misconfigured filtering invites SID-history injection and unexpected delegation paths. Over-zealous filtering blocks legitimate day-1 access during migrations. The craft is using filtering deliberately—tight for steady-state, relaxed only within strict guardrails during moves.

Newer Windows builds also introduce trust scanners and stronger defaults for cross-boundary auth. If you don’t plan for these, you’ll either punch holes unintentionally or trip hard failures during cutover.

Fundamentals (and what gets overlooked)

Most guidance says: “SID filtering strips foreign SIDs; turn it off for migration; re-enable afterward.” True—but incomplete. Three gotchas matter:

  1. Two knobs exist depending on trust type:
    • External/domain trust: /Quarantine:{Yes|No}.
    • Forest trust: /EnableSidHistory:{Yes|No} governs whether SIDHistory is honored across forests.
  2. Not every SID is filterable. Certain “NeverFilter” categories (e.g., Enterprise DC) are by spec not removed.
  3. Filtering interacts with modern trust hardening. Trust scanners and selective authentication change outcomes if they can’t read what they need.

Key terms at a glance

SIDSIDHistory
PACQuarantine
EnableSidHistorySelectiveAuth

What’s in the core?

Kerberos tickets contain a PAC (Privilege Attribute Certificate) with the user SID, all group SIDs, and any SIDHistory. When a user from Forest B requests access in Forest A, a DC in Forest A evaluates the PAC and filters SIDs that don’t conform to the trust’s rules. The DC then issues the service ticket containing the already-filtered authorization data. The resource server simply enforces what the DC decided.

Trust type Primary control Default Implication
External / domain /Quarantine Yes (on) Only SIDs from the directly trusted domain survive.
Forest /EnableSidHistory No (off) SIDHistory is not honored across the forest boundary unless you enable it.

What counts as “foreign”? It’s not guesswork—DCs match SIDs against trusted namespaces in the TDO (Trusted Domain Object). SIDs with a domain component outside the directly trusted namespace are filtered (unless covered by forest-aware rules or “NeverFilter”).

Testing tip: To see the effect, purge tickets (klist purge), then authenticate across the trust and run whoami /all on the trusting side. Don’t rely on the client’s pre-existing token.

Token-size side effects are real. Extra SIDs—nested groups and SIDHistory—inflate the PAC. During co-existence, tokens can exceed MaxTokenSize, causing odd logon issues and HTTP 401s. Plan to shed SIDHistory quickly and trim memberships.

Runbook: Migrate safely, then harden

This is the part you’ll reuse. It assumes a two-forest migration where you need temporary access continuity via SIDHistory.

Step A — Inventory & classify your trusts

# PowerShell (run from a management workstation with RSAT)
Import-Module ActiveDirectory
Get-ADTrust -Filter * |
  Select-Object Name, Direction, TrustType, ForestTransitive,
    SIDFilteringQuarantined, SIDFilteringForestAware, SelectiveAuthentication

Interpretation:

  • SIDFilteringQuarantined → quarantine state (external/domain trusts).
  • SIDFilteringForestAware → forest-aware SID handling (ties to EnableSidHistory).
  • SelectiveAuthentication → explicit allow lists required on resources.

:: Validate from the trusting side (per direction)
netdom trust TrustingDomain /domain:TrustedDomain /quarantine
netdom trust TrustingForestRoot /domain:OtherForestRoot /enablesidhistory

Step B — Prepare a safe allowance for SIDHistory (forest trust only)

  • Pre-checks: confirm mutual admin approvals; open LDAP/RPC for trust scanners; if Selective Auth is on, grant Allowed to authenticate to the other forest’s PDC for scanner reads.
  • Enable SIDHistory across the forest boundary (temporarily):

:: Run on the trusting forest root (outbound to the other forest)
netdom trust  /domain: /EnableSidHistory:Yes ^
  /UD:<OtherForestRoot\Administrator> /PD:* /UO:<TrustingForestRoot\Administrator> /PO:*

Re-read with Get-ADTrust to confirm state. Document the exit date for this exception.

Step C — Migrate with SIDHistory and validate

  • Use ADMT or a vendor tool that calls DsAddSidHistory under the hood and meets prerequisites.
  • Spot-check migrated objects:

Get-ADUser -Identity  -Properties SIDHistory |
  Select-Object SamAccountName, SID, SIDHistory

Then validate the effective token from the trusting side:

klist purge
whoami /all

Step D — Cutover hardening: remove allowances and reduce blast radius

  1. Disable cross-forest SIDHistory:

netdom trust  /domain: /EnableSidHistory:No
  1. Ensure quarantine on external/domain trusts:

netdom trust  /domain: /Quarantine:Yes
  1. Clean SIDHistory quickly:

# Find accounts still carrying SIDHistory
Get-ADUser -Filter * -Properties SIDHistory | Where-Object SIDHistory

# Remove after ACLs are updated
Set-ADObject -Identity "" -Clear SIDHistory
  1. Review delegation & target validation: eliminate unconstrained delegation across incoming trusts; prefer constrained & resource-based constrained delegation.
  2. Instrument & monitor: export trust flags weekly and diff; alert on drift.

Troubleshooting quick hits

  • “Access denied” toggling trust flags: run netdom on a DC using admin creds on both sides with /UD and /UO; verify time sync and RPC/LDAP reachability.
  • Token bloat after enabling SIDHistory: trim group memberships; expedite SIDHistory cleanup; temporarily raise MaxTokenSize for critical apps while you remediate.
  • “Filtering is on, but I still see SID X”: confirm whether X is in a “NeverFilter” category or Enterprise DC—by spec, it can traverse.

Inherent tendencies you can’t code around

  • Security ↔ continuity is a spectrum. Relaxation (EnableSidHistory:Yes / Quarantine:No) smooths migrations but softens boundaries.
  • Token growth is inevitable during co-existence. Plan for it, observe it, then reduce it.
  • Modern Windows prefers to fail closed. Trust scanners and target validation break risky paths rather than silently allow them.

Some mental models for you

  • Boundary contract: a trust is a contract about which SIDs are recognized. If there’s no clause, the SID doesn’t pass.
  • PAC budget: every group and SIDHistory entry spends bytes. Spend them only while you must.
  • Directional asymmetry: every trust has two directions—decide settings for each.
  • Temporary exception with exit: any relaxation must have a calendar end and a cleanup plan.

Misunderstandings, risks & corrective actions

Myth: “Forest trusts are fine with EnableSidHistory=Yes forever.”
Reality: you soften the boundary and expand blast radius. Keep it temporary.
Myth: “Quarantine breaks everything; avoid it.”
Reality: external trusts should be quarantined by default; grant access with direct domain groups instead of universal groups crossing the boundary.

Expert essentials checklist

  • External trusts steady-state: Quarantine=Yes.
  • Forest trusts: EnableSidHistory only during the migration window; revert to No after cutover.
  • Document per-direction settings; never assume symmetry.
  • Monitor for Unsecure SIDHistory and remove it quickly.
  • Prefer constrained delegation; enable modern target validation features.
  • Budget PAC size; trim memberships; remove SIDHistory promptly.

Applications, decisions & what’s next

  • Resource/account forest designs: keep EnableSidHistory=No steady-state. Use shadow principals or scoped roles for admin needs.
  • M&A and carve-outs: time-box EnableSidHistory=Yes with a tracked ACL-refactor burn-down. Target zero references to source groups before turning it off.
  • B2B external access: keep quarantine on; where exception is necessary, use Selective Authentication with Allowed to authenticate on specific resources.
Want the full kit?Get our SID Filtering Migration & Hardening Kit: pre-checks, step templates, PowerShell snippets, validation & rollback checklists. Subscribe on the site to receive it.

FAQ

Is SID filtering enabled by default?

For external/domain trusts, quarantine is on by default. For forest trusts, SIDHistory is blocked unless you explicitly enable it.

How do I check if filtering is on?

Use netdom trust … /quarantine or /enablesidhistory, and confirm with Get-ADTrust.

Can I quarantine inside a forest?

Not recommended—doing so breaks assumptions for universal groups and often causes outages.

Why did a specific SID still pass with filtering on?

Some SID categories are “NeverFilter” by specification (e.g., Enterprise DC); those may traverse by design.

Some more references

  1. Microsoft Learn — netdom trust (parameters incl. /Quarantine, /EnableSidHistory)
  2. Microsoft Open Specs — MS-PAC overview (PAC composition)
  3. Microsoft Open Specs — SID filtering & “NeverFilter” categories
  4. Microsoft — Kerberos token size, MaxTokenSize guidance
  5. Microsoft — DsAddSidHistory requirements
  6. ADSecurity — Security considerations for trusts (SID filtering & selective auth)
  7. ADSecurity — SID History persistence & risks
  8. MITRE ATT&CK — T1134.005 SID-History Injection
  9. Dirk-Jan Mollema — How does SID filtering work? (deep dive)
  10. SpecterOps (2025) — New trust attack paths & filtering notes
  11. MS Q&A — Selective Authentication & “Allowed to authenticate” rights
  12. MS KB 938118 — Managing MaxTokenSize via GPO

Keep in mind: Always verify exact behavior on your OS build and patch level. Feature defaults evolve.



Related posts
Active Directory FundamentalsActive Directory ObjectsRecent Posts

Managing AD metadata cleanup post-DC decommission: A Playbook

Active Directory FundamentalsActive Directory Policies

AD high-availability: RODCs and cross-site redundancy

Active Directory FundamentalsActive Directory PoliciesRecent Posts

Transitioning AD schema versions safely: runbook & pitfalls

Active Directory FundamentalsActive Directory PoliciesRecent AD NewsTop Read Articles

DNS delegation architectures for multi-forest environments

×

There are over 8,500 people who are getting towards perfection in Active Directory, IT Management & Cyber security through our insights from Identitude.

Wanna be a part of our bimonthly curation of IAM knowledge?

  • -Select-
  • By clicking 'Become an insider', you agree to processing of personal data according to the Privacy Policy.