🏢Active DirectoryIdentityGroupsPermissions

AD foreign security principals: classify SIDs before cleanup

Classify FSP SIDs, inspect consuming groups and verify trust context before removing any Active Directory placeholder or membership.

Younes AZABARBy Younes AZABAR10 min read
AD foreign security principals: classify SIDs before cleanup

What AD foreign security principals represent

AD foreign security principals are placeholder objects that let a domain represent security identities it does not store as ordinary local users or groups. Their presence is an inventory fact. It does not establish an attack, a dangerous permission, or a broken trust. Review each object's SID and consuming groups before deciding whether anything should change.

Microsoft's MS-ADTS Foreign Security Principals container specification explains the AD DS case: the domain naming context contains a container of foreignSecurityPrincipal objects representing principals from trusted domains outside the forest, allowing those principals to join groups in the domain. This article covers AD DS, rather than the separate AD LDS container rules.

There is also a normal well-known-SID case. Microsoft's historical FSP explanation, last updated May 24, 2016, describes why adding a well-known identity to a group's member attribute can create a placeholder: the membership reference needs an existing distinguished name. The archive recommends inspecting memberOf before removing an FSP. It documents group membership; it does not establish that every ACL reference creates an FSP.

Technical sources and collector behavior were reviewed on October 4, 2026. The commands below are documentation-based examples for an authorized administrator; they were not executed against a customer domain.

How to classify the SID and its dependencies

Start with three outcomes: well-known identity, resolved external identity, and indeterminate. These are review decisions, not severities inferred from a number of objects. Keep the SID in the record even when a tool displays a friendly name. Names are useful for contacting owners; the SID is the identity being referenced.

Microsoft's current security identifier reference lists the following well-known identities:

SIDIdentityConsequence for this review
S-1-5-11Authenticated UsersClassify as well-known; review why the consuming group includes it
S-1-5-4InteractiveClassify as well-known; confirm the intended membership with the group owner
S-1-5-7Anonymous LogonClassify as well-known; assess the actual consumer rather than calling it a foreign account
S-1-1-0World / EveryoneClassify as well-known; assess the intended breadth of the consuming group

This is an example set, not a complete lookup table. Match any other SID to the Microsoft reference before assigning a label. Well-known means a recognized identity, not automatically appropriate access. A broad membership can still deserve review, but deleting its placeholder is not a substitute for reviewing the membership decision.

For a domain-account SID, identify the issuing domain and ask the responsible domain administrator to confirm the exact principal. Record the source domain, current identity, business owner and the purpose of its membership. A successful name lookup alone does not prove that the group is still needed. A failed lookup alone does not prove that the principal was deleted.

Keep uncertainty explicit. The review record should answer four questions: did collection complete, which groups consume the object, can the relevant trust partner be contacted, and who can approve the business decision? An unanswered question keeps the object in the indeterminate category.

Detection: inventory SID, memberOf and trust context

Step 1: collect objects independently of the count

Use an authorized Windows administration host with the ActiveDirectory PowerShell module. Select a domain controller deliberately and record the host, domain, collection time and any errors. Microsoft's Get-ADRootDSE documentation exposes defaultNamingContext; use it to construct the domain-specific container DN instead of copying another domain's path.

The following inventory adapts the documented Get-ADObject LDAP query parameters. The filter is fixed, additional attributes are explicit, and $null for ResultSetSize avoids an intentional result-count cap.

Import-Module ActiveDirectory
$dc = 'dc01.corp.example'
$root = Get-ADRootDSE -Server $dc -ErrorAction Stop
$base = 'CN=ForeignSecurityPrincipals,' + $root.defaultNamingContext
$fsps = @(Get-ADObject -Server $dc -SearchBase $base -SearchScope Subtree `
    -LDAPFilter '(objectClass=foreignSecurityPrincipal)' `
    -Properties objectSID,memberOf -ResultPageSize 256 `
    -ResultSetSize $null -ErrorAction Stop)
$fsps | Select-Object DistinguishedName,ObjectGUID,objectSID,memberOf

For an LDAP client, the equivalent request uses that container as the search base, subtree scope, (objectClass=foreignSecurityPrincipal) as the filter, and distinguishedName, objectGUID, objectSid and memberOf as requested attributes. Complete paging, preserve multivalued attributes and retain failures separately from empty results. Do not manufacture SID strings from display names.

Do not continue to cleanup if the query fails, is interrupted, or the account cannot read the required properties. An empty inventory from a completed read and an unavailable inventory are different outcomes. For multiple domains, repeat the collection with each domain's own context and keep those records separate.

Step 2: inspect the consuming groups

Microsoft's memberOf schema reference identifies it as the distinguished names of groups to which the object belongs. Treat the returned references as the starting list of consumers, not an effective-access report. Follow group nesting and resource dependencies separately before judging impact.

Select one FSP by its recorded DN, not by taking the first row. This example uses Get-ADGroup's documented identity and additional-property parameters to inspect each returned group:

$fspDn = Read-Host 'Exact FSP distinguished name from the inventory'
$fsp = Get-ADObject -Identity $fspDn -Server $dc `
    -Properties objectSID,memberOf -ErrorAction Stop
foreach ($groupDn in $fsp.memberOf) {
    Get-ADGroup -Identity $groupDn -Server $dc `
        -Properties member,memberOf,managedBy,description -ErrorAction Stop |
        Select-Object DistinguishedName,GroupScope,GroupCategory, `
            member,memberOf,managedBy,description
}

Check that the group's member values contain the exact FSP DN. Ask the group owner which application or resource relies on it, whether an acquisition or migration is still active, and how to test the intended access. managedBy and the description can provide contact clues; they do not replace confirmation from an accountable owner. A blank owner field is a follow-up task, not permission to delete.

Step 3: resolve without turning failures into an orphan verdict

Microsoft documents SecurityIdentifier.Translate and its IdentityNotMappedException when identity references cannot be translated. This example preserves failure as evidence:

$sid = [System.Security.Principal.SecurityIdentifier]$fsp.objectSID
try {
    $account = $sid.Translate([System.Security.Principal.NTAccount])
    [pscustomobject]@{ SID = $sid.Value; Account = $account.Value }
} catch {
    [pscustomobject]@{ SID = $sid.Value; LookupError = $_.Exception.Message }
}

The lookup uses the administration host's Windows context. It does not accept a selected partner DC and does not demonstrate trust health. Preserve the host and error, identify the expected issuing domain, check name resolution and required connectivity with its administrators, and confirm whether the exact SID still exists there. Investigate inaccessible partners and retired trusts before using the word orphan. Do not weaken trust settings to make a lookup succeed.

Microsoft's Get-ADTrust documentation gives this exact enumeration command:

Get-ADTrust -Filter *

Use the returned trusted-domain objects as context, with the queried domain recorded. Their presence is configuration evidence, not an end-to-end connectivity test or proof that a particular foreign SID resolves. Once an actual external identity has been identified, the trust SID filtering and selective authentication audit provides the separate review of trust controls.

If the question is instead whether an unresolved trustee holds a dangerous grant, use the dangerous ACE audit for unresolved and cross-domain trustees. That examines DACL permissions; this inventory classifies existing FSP objects and their consumers. Neither review replaces the other.

Remediation: remove only a reference proven unnecessary

Step 1: approve the classification and scope

Keep needed well-known and external memberships. Leave indeterminate objects unchanged while collection, connectivity or ownership questions remain open. For a candidate retired reference, retain the exact SID, FSP DN and GUID, consuming group DNs, partner confirmation, owner decision and relevant application tests. Agree on a change window and a rollback that can restore the intended membership.

Make the decision specific: which group membership is unnecessary, why, and which accesses should continue afterward? If only one consuming group has retired its dependency, remove that membership alone. Other consumers can still need the same placeholder. Do not make object deletion the first step in a membership review.

Step 2: preview one approved membership change

Microsoft's Set-ADGroup documentation supports removing a specific property value by its LDAP display name, plus WhatIf and confirmation. This adapted example targets one member DN on a writable DC:

$groupDn = Read-Host 'Exact approved consuming group distinguished name'
Get-ADGroup -Identity $groupDn -Server $dc -Properties member -ErrorAction Stop
Set-ADGroup -Identity $groupDn -Server $dc -Remove @{member=$fspDn} -WhatIf

Review the target and saved membership first. WhatIf previews the operation; it does not test the application's access or guarantee that a later write will succeed. Only after the owner has approved this exact removal, execute the individual change with confirmation and reread the group:

Set-ADGroup -Identity $groupDn -Server $dc -Remove @{member=$fspDn} `
    -Confirm:$true -ErrorAction Stop
Get-ADGroup -Identity $groupDn -Server $dc -Properties member -ErrorAction Stop

Step 3: validate access before optional object cleanup

Confirm that the approved membership changed, allow for the environment's replication and authentication context, and have the application owner verify both intended access and the retired dependency. A successful write is not an access test. Record actual results in the change record rather than declaring success from a lower inventory count.

Recollect the FSP's membership and investigate remaining dependencies. An empty memberOf does not by itself establish that a SID is unused across resource ACLs or application configuration. If the object itself is proven unnecessary, object cleanup is a separate, explicitly approved action. Microsoft's Remove-ADObject reference documents single-object removal; preview the recorded GUID only after those checks:

Remove-ADObject -Identity $fsp.ObjectGUID -Server $dc -WhatIf

This preview performs no deletion. Do not turn it into a pipeline over the container or remove the container itself. Keep the cleanup decision, restoration plan and final access verification together.

How EtcSec Detects This

EtcSec's FOREIGN_SECURITY_PRINCIPALS check reports DomainInfo.ForeignSecurityPrincipalsCount. The reviewed Detect() initializes the count to zero, copies the field when DomainInfo exists, and returns a Medium finding carrying that count. A missing DomainInfo therefore produces zero. The positive-count details add a caveat, not per-object evidence or SID classification.

The LDAP provider performs a paged subtree search under CN=ForeignSecurityPrincipals,<baseDN> using (objectClass=foreignSecurityPrincipal). It requests only distinguishedName and assigns the number of returned entries when the search succeeds. A search error leaves the field at its initial zero value. This field exposes no collection-success indicator that distinguishes that failure from a successfully empty result.

The check does not expose individual SIDs, memberOf, owners, resolved names, trust connectivity or effective permissions. Its count mixes well-known placeholders and actual external references. It cannot identify an orphan, count trusts, prove cross-forest exposure or establish that zero means a clean inventory. The independent collection and classification above supply the evidence needed for a decision. This workflow includes no automatic deletion.

The collector's explanatory text also generalizes placeholder creation to ACL references. The historical Microsoft source used here establishes the member case; that broader wording is not repeated as a verified rule. Treat the finding as a prompt to inspect the underlying objects and their dependencies, then retain or change only what the evidence supports.

Explore the identity security pages that support this topic