en-US/about_PSWSManAuthentication.help.txt

# PowerShell WSMan Authentication
## about_PSWSManAuthentication

# SHORT DESCRIPTION
There are many different ways to authenticate with a Windows host over WSMan each with their own advantages and disadvantages.
It is complicated further that some authentication methods might be available on some hosts but not available on others.
This help page will go through the various authentication options available to `PSWSMan` and how they can be used.

# LONG DESCRIPTION
There are 6 different types of authentication methods supported by WSMan:

+ `Basic` - Simple HTTP basic authentication

+ `Certificate` - HTTPS client certificate authentication

+ `NTLM` - NTLM authentication

+ `Kerberos` - Kerberos authentication for domain accounts

+ `Negotiate` - Kerberos but with a fallback of NTLM authentication

+ `CredSSP` - Negotiate authentication with the ability to delegate credentials

The `Negotiate` authentication package is an authentication method that will attempt to use `Kerberos` before falling back to `NTLM` if that is unavailable.
It is also the default method used when no method is specified.

Here is a simple matrix of each options and some of the features they support:

|Method|Local Account|Domain Account|Implicit Credential|HTTP Encryption|Delegation|
|-|-|-|-|-|-|
|Basic|Y|N|N|N|N|
|Certificate|Y|N|N|N/A¹|N|
|NTLM|Y|Y|Y²|Y³|N|
|Kerberos|N|Y|Y|Y|Y|
|Negotiate|Y|Y|Y⁴|Y|Y⁵|
|CredSSP|Y|Y|N|Y|Y|

¹ Certificate auth only available over HTTPS
² Only on Windows with the System auth provider
³ NTLM HTTP Encryption is based on a weak RC4 cipher and should not be used
⁴ On Windows with the System auth provider or on other OS', implicit credentials will only work with Kerberos through Negotiate
⁵ Only available if Kerberos was negotiated

Exchange Online also offers Modern Auth (OAuth) but this just uses the Basic authentication headers to smuggle the OAuth token.

# BASIC AUTH
Basic authentication is sending the username nad password as a base64 encoded value in the HTTP headers.
This is the simplest authentication option available but also the weakest.
It only works for local accounts and should only be used over a HTTPS connection.
When specifying a credential for Basic authentication only the username should be used.
Do not specify the hostname portion of the username, e.g. use `username` and not `HOST\username`.

Using it over a HTTP connection is dangerous as the credentials are simply encoded not encrypted and there is no encryption of the data exchanged between the client and server.
If Basic authentication over HTTP is truly desired then `New-WinRMSessionOption -NoEncryption` must be set and the server must allow unencrypted access.

By default Basic authentication is disabled on the server, to enable it run:

```powershell
Set-Item -Path WSMan:\localhost\Service\Auth\Basic -Value True
```

# CERTIFICATE AUTH
Certificate authentication is when the client offers an X.509 certificate to the server for authentication.
The server will check that this certificate was issued by a Certificate Authority (CA) that it trusts and whether the certificate maps to a local account mapping defined on the server itself.
It can only be used over a HTTPS connection as it's a feature done through the TLS connection itself.

The certificate must have the `ClientAuthentication` extended key usage and a Subject Alternative Name (SAN) that identifies the local user it maps to.
On the server side a HTTPS listener must exist, the certificate must be trusted and installed in the `TrustedPeople` store, mapped to the local account, and the WSMan service must have certificate authentication enabled.
The [winrm-cert-auth](https://github.com/jborean93/winrm-cert-auth) repository covers these requirements in greater detail and includes scripts that generate the certificate and configure the server.

Once the server is configured, connect over HTTPS with `-UseSSL`, or a `https` `-ConnectionUri`, and give the client certificate in one of two ways:

+ By thumbprint with the `-CertificateThumbprint` parameter, for a certificate with its private key in the `Cert:\CurrentUser\My` or `Cert:\LocalMachine\My` store. The parameter is on the builtin remoting cmdlets, like `New-PSSession` and `Invoke-Command`, as well as `New-WinRMSession` and the WinRS cmdlets, and cannot be combined with `-Credential` or `-Authentication`.

+ As a certificate object with `-ClientCertificate` on `New-WinRMSessionOption`, for a certificate that is not in a store, like one loaded from a PFX file.

```powershell
# A certificate in the personal store, referenced by thumbprint
Invoke-Command -ComputerName host -UseSSL -CertificateThumbprint 2C8D1BE6A3F2E1F8C9D0B1A2F3E4D5C6B7A89012 -ScriptBlock { ... }

# A certificate loaded from a file
$cert = Get-PfxCertificate -FilePath ~/client_auth.pfx
$pso = New-WinRMSessionOption -ClientCertificate $cert
Invoke-Command -ComputerName host -UseSSL -SessionOption $pso -ScriptBlock { ... }
```

On Linux and macOS the stores are the ones .NET provides, `Cert:\LocalMachine\My` is not available on Linux and PowerShell has no `Cert:` drive outside Windows.
Import a certificate into the current user store with `[System.Security.Cryptography.X509Certificates.X509Store]` or use `-ClientCertificate` instead.
If `-TlsOption` is used, the `ClientCertificates` property of the `SslClientAuthenticationOptions` object must contain the certificate instead, `-CertificateThumbprint` and `-ClientCertificate` are ignored.

# NTLM AUTH
NTLM authentication is a legacy authentication protocol offered by Microsoft.
It supports both local and domain accounts making it usable in more circumstances but due to its age it is quite weak when used by itself.
NTLM authentication should only be used with WSMan when the connection is being used over HTTPS.
The reason for this is that HTTPS offers both server authentication through certificates, and strong message encryption through TLS.
Without server authentication, the client cannot know for sure the server it is talking to is who it thinks it is.
Without TLS message encryption, the data sent by NTLM is encrypted with a weak RC4 key.
The NTLM token send in the HTTP headers is also susceptible to cracking if a weak password was used.
Ultimately NTLM should be avoided unless HTTPS is being used.

Availability of NTLM depends on the OS and authentication provider used.
On Windows NTLM will work out of the box and supports using the current user's credentials.
On macOS NTLM will also work out of the box but can only be used when explicit credentials are passed with `-Credential` when creating the session.
On Linux NTLM is only available if both GSSAPI is installed and the [gss-ntlmssp](https://github.com/gssapi/gss-ntlmssp) package is installed and configured.

The `Devolutions` authentication provider also supports NTLM authentication out of the box.
It only supports explicit credentials but is a good option to use that is consistent across all platforms.
To specify the `Devolutions` authentication provider to be used pass in the session options `New-WinRMSessionOption -AuthProvider Devolutions`.
Alternatively, the `Devolutions` authentication package can be set globally as the default with `Set-PSWSManAuth -AuthProvider Devolutions`.
See `#DEVOLUTIONS SSPI` for more details.

By default Windows will allow NTLM authentication through the `Negotiate` auth package.
If this package has been disabled then NTLM will not work.

# KERBEROS AUTH
Kerberos authentication is a domain authentication method that supports AES encryption over HTTP and server authentication.
It is the first protocol that is attempted with the Negotiate method.

Kerberos authentication can also be used to delegate the ticket to remote host.
This delegation enables the remote session to be able to connect to another downstream server like a UNC path.
To request a delegated ticket the session option `New-WinRMSessionOption -RequestKerberosDelegate` must be specified.
See `#CREDENTIAL DELEGATION` for more details.

Part of the Kerberos authentication process is to lookup the target server using an service principal name (SPN).
The SPN is constructed using the `-ComputerName` value that is being connected to form the SPN `host/$ComputerName`.
To change the service portion `host` to something else use `New-WinRMSessionOption -SPNService host`.
To override the hostname portion to something else use `New-WinRMSessionOption -SPNHostName other`.
For example `New-WinRMSessionOption -SPNService http -SPNHostName test` will use the SPN `http/test`.

Availability of Kerberos depends on the OS and authentication provider used.
On Windows Kerberos will work out of the box and supports using the current user's credentials.
While it is easier for the host to be domain joined it is possible for Windows to use Kerberos if the host has been configured to map the realm to a KDC.
On macOS Kerberos will also work out of the box and credentials can be retrieved using `kinit` or with an explicit credential.
On Linux Kerberos is only available if GSSAPI is installed and like macOS credentials can be retrieved through `kinit` or with an explicit credential.
Both macOS and Linux GSSAPI can be configured through an `/etc/krb5.conf` file.
It can also use DNS SRV records to lookup domain realms.

The `Devolutions` authentication provider also supports Kerberos authentication out of the box.
It only support explicit credentials but as it requires no system packages it provides a consistent experience across all platforms.
DevolutionsSspi can retrieve domain configuration through many means, like the `/etc/krb5.config`.
To specify the `Devolutions` authentication provider to be used pass in the session options `New-WinRMSessionOption -AuthProvider Devolutions`.
Alternatively, the `Devolutions` authentication package can be set globally as the default with `Set-PSWSManAuth -AuthProvider Devolutions`.
See `#DEVOLUTIONS SSPI` for more details.

Kerberos can either be used through the Negotiate method but can also be explicitly used as the Kerberos method.

# NEGOTIATE AUTH
Negotiate authentication is a psuedo method that combines both Kerberos with a fallback for NTLM authentication.
It is enabled by default on the WSMan server.
It is the default authentication method tried by PSWSMan when no authentication method is chosen.

The same Kerberos options `-RequestKerberosDelegate`, `-SPNService`, and `-SPNHostName` also apply to Negotiate authentication if it negotiates Kerberos authentication.

# CREDSSP AUTH
CredSSP is a more complex authentication method that works for both local and domain accounts.
It will delegate the user's credentials to the remote host allowing it to access further downstream servers with its credentials.
Internally CredSSP uses the Negotiate protocol to authenticate the user but because it needs the users credentials to delegate it only works with credentials supplied by `-Credential`.

CredSSP creates a temporary TLS context that wraps the authentication exchange and subsequent messages.
This is unrelated to the actual HTTP transport, i.e. CredSSP works just fine over a HTTP connection.
The following options can be specified with `New-WinRMSessionOption` to control the CredSSP authentication behaviour

+ `CredSSPAuthMethod` - By default CredSSP will use `Negotiate` but this can be set to `Kerberos` or `NTLM` to restrict CredSSP from only using one or the other

+ `CredSSPTlsOption` - Controls the TLS wrapper of the CredSSP session

As well as this the `-SPNService` and `-SPNHostName` will be used on the inner Negotiate stage of CredSSP if Kerberos is used.
The TLS option can be used to finely control the TLS context that CredSSP sets up.
For example the default TLS context for CredSSP will not validate the CredSSP certificate as it's typically an ephemeral self-signed certificate.
By specifying a custom TLS option for CredSSP it can be setup so the remote certificate is verified or that only specific TLS protocols or cipher suites are used.
Be careful not to restrict the TLS protocols available to just TLS 1.3, Windows does not support CredSSP with TLS 1.3 as of yet (the WSMan connection can still be TLS 1.3 though).

CredSSP is not enabled by default on the remote server as the unconstrained delegation can be dangerous if the remote host is not trusted.
To enable CredSSP on the WSMan server run the following:

```powershell
Enable-WSManCredSSP -Role Server
```

# SPECIFY AUTHENTICATION METHOD
There are two main ways an authentication method is set:

+ On the `-Authentication` parameter of cmdlets that create a connection, e.g. `New-PSSession`, `Invoke-Command`, `Enter-PSSession`, `New-WinRMSession`, `Invoke-WinRSCommand`

+ On the `-AuthMethod` parameter of the `New-WinRMSessionOption`

The `-Authentication` parameter of the builtin cmdlets is limited to just `Basic`, `Kerberos`, `Negotiate`, or `CredSSP` while the `-AuthMethod` parameter, and `-Authentication` on the PSWSMan cmdlets, also include `NTLM` as an option.
The `-Authentication` parameter takes priority over `-AuthMethod` when it is set to anything other than `Default`, so `-AuthMethod` is the default for the connections made with those options.
The default authentication method chosen is `Negotiate` which typically offers the best out of box experience.
It uses the system SSPI/GSSAPI library unless the Devolutions provider is requested for the session or has been set as the default with `Set-PSWSManAuth`.
On Linux, if no GSSAPI library is installed and Devolutions has not been selected, the connection fails with an error saying no SSPI/GSSAPI library could be found.

# CREDENTIAL DELEGATION
A common problem that is encountered with remote PSSessions is the lack of credential delegation on the default authentication methods.
This problem is also known as the [double hop problem](https://learn.microsoft.com/en-us/powershell/scripting/learn/remoting/ps-remoting-second-hop?view=powershell-7.3) and is essentially a failure to authenticate the remote session with a futher downstream server.
For example accessing a network path on the remote session will fail with access is denied even if the connection user typically has access to that server.

```powershell
Invoke-Command -ComputerName Server1 -ScriptBlock {
    # This will fail to access Server2
    Get-Content -Path "\\Server2\share\file.txt"
}
```

There are 2 main ways they can be solved in the connection method:

+ Use CredSSP, or

+ Use Kerberos (or Kerberos through Negotiate) with `-RequestKerberosDelegation`

Using `CredSSP` is straight forward as the credentials are provided as part of the authentication process and the remote session can delegate them.
This is considered unconstrained delegation and can be dangerous if the remote host is compromised as it now has access to your credentials to do as it wishes.

Using `-RequestKerberosDelegation` with Kerberos auth is also a form on unconstrained delegation so it has the same security concerns as CredSSP.
When this switch is set, the authentication process will request a delegated ticket from the KDC and use that as part of authenticating with the remote host.
This ticket is special in that the remote host can then use that authentication ticket to request subsequent tickets for any downstream servers as requested.
For a target server to get a delegated Kerberos ticket it must be marked in Active Directory with `Trust this computer for delegation to any service (Kerberos only)` in the Delegation tab.
Without the target server being trusted Windows will not give you a delegated ticket even if `-RequestKerberosDelegation` is set.

Linux and macOS are slightly different in that it ignores the delegation setting in AD unless `enforce_ok_as_delegate` is set in the `krb5.conf` file.
Linux and macOS can also only delegate if:

+ Using implicit creds, they are marked as forwardable (`kinit -f username@READLM.COM`)

+ Using explicit creds, the `forwardable = true` flag is set in the `krb5.conf`

To verify if the cred retrieved from `kinit` is forwardable, run `klist -f` and the flags should have `F`.

To verify if the remote PSSession has a forwardable ticket that it can use for delegation, the `klist.exe` command will display the `forwarded` flag.

# DEVOLUTIONS SSPI
By default the PSWSMan authentication process will use the system provided library, SSPI and GSSPI.
The module also ships with a copy of [sspi-rs](https://github.com/Devolutions/sspi-rs) from Devolutions.
The `sspi-rs` library is a cross platform implementation of the SSPI API that is completely independent from any system dependencies.
This means it can use both NTLM and Kerberos authentication without relying on either SSPI or GSSAPI to be installed and configured.
It also means that any behaviour on one platform is the same on any other.

Devolutions SSPI is never chosen automatically, it is only used when it is set as the default authentication provider for the runspace or requested on a specific session.
The code `Set-PSWSManAuth -AuthProvider Devolutions` sets the default for the current runspace to use Devolutions SSPI.
The default is scoped to the runspace, so a new runspace such as a `ForEach-Object -Parallel` or `Start-ThreadJob` job starts from the `System` provider again.
Otherwise `New-WinRMSessionOption -AuthProvider Devolutions` can be used on a specific session setup to use Devolutions for that connection.
The `New-WinRMSessionOption -AuthProvider ...` takes precedence over the runspace default.

Support for Devolutions is limited and while things should work it is an experimental feature and mileage may vary.