Skip to content

Support computer and managed service accounts in Windows AD auth - #1807

Open
schnyders wants to merge 1 commit into
Badgerati:developfrom
schnyders:develop
Open

schnyders wants to merge 1 commit into
Badgerati:developfrom
schnyders:develop

Conversation

@schnyders

@schnyders schnyders commented Oct 9, 2026 •

Copy link
Copy Markdown

Description of the Change

Windows AD authentication only worked for user accounts, because the LDAP query was hardcoded to objectCategory=person. Computer accounts and managed service accounts (sMSA, gMSA, dMSA) could not authenticate.

  • Get-PodeAuthADQuery now matches on sAMAccountType (user 805306368, machine 805306369), so any account that can authenticate is found.
  • The User object now has an AccountType property: the most specific AD object class of the account (user, computer, msDS-GroupManagedServiceAccount, ...). It is populated by the Directory Services, OpenLDAP, ActiveDirectory module and IIS providers.
  • The ActiveDirectory module provider now uses Get-ADObject instead of Get-ADUser, since Get-ADUser does not return computer or service accounts.
  • Get-PodeAuthADGroupDirect reuses Get-PodeAuthADQuery instead of a duplicated filter.
  • The username is now escaped (RFC 4515) before it is placed in the LDAP filter, which prevents LDAP filter injection through the username.
  • The OpenLDAP and ActiveDirectory module lookups return $null when no entry is found.
  • Docs updated (WindowsAD.md, IIS.md) and unit tests added for Get-PodeAuthADQuery.

Examples

New-PodeAuthScheme -Basic | Add-PodeAuthWindowsAd -Name 'Login' -Fqdn 'domain.local'

Add-PodeRoute -Method Get -Path '/info' -Authentication 'Login' -ScriptBlock {
    # AccountType is 'user', 'computer', 'msDS-GroupManagedServiceAccount', ...
    Write-PodeJsonResponse -Value @{
        Username    = $WebEvent.Auth.User.Username
        AccountType = $WebEvent.Auth.User.AccountType
    }
}

Computer and managed service accounts are supplied with their trailing $, e.g. DOMAIN\WEB01$.

Additional Context

  • Behaviour change: user accounts are still matched, but the query is now broader (machine accounts also match). Existing user logins are unaffected.
  • The passwords of managed service accounts are generated and rotated by AD, so Basic/Form auth requires the caller to retrieve the managed password first. For these accounts, Kerberos via Add-PodeAuthWindowsAdIIS is usually the better choice (noted in the docs).
  • Tests: new Pester unit tests cover the query, trailing $ and special-character escaping. Not yet tested against a live domain with gMSA/computer accounts.

The AD LDAP query was hardcoded to objectCategory=person, so computer
accounts and sMSA/gMSA/dMSA could not authenticate. Match on
sAMAccountType (user 805306368, machine 805306369) instead, so any
account that can authenticate is found.

- Add AccountType to the returned User object (most specific AD
  objectClass: user, computer, msDS-GroupManagedServiceAccount, ...),
  across the Directory Services, OpenLDAP, ActiveDirectory module and
  IIS providers
- Use Get-ADObject instead of Get-ADUser for the ActiveDirectory module
  provider, since Get-ADUser doesn't return computer/service accounts
- Reuse Get-PodeAuthADQuery in Get-PodeAuthADGroupDirect rather than
  duplicating the filter
- Escape RFC 4515 special characters in the username before it is put
  into the LDAP filter (fixes LDAP filter injection via the username)
- Return $null from the OpenLDAP/ADModule lookups when no entry is found
- Document AccountType and the supported account types, including the
  note about retrieving managed passwords for Basic/Form auth
- Add unit tests for Get-PodeAuthADQuery

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant