Updates

PSSO Technical Deep Dive

What is Platform Single Sign-On?

Platform Single Sign-On (PSSO) is a component of macOS for obtaining Single Sign-On (SSO) tokens at the macOS login window and in a user session. These SSO tokens can then be used by an SSO extension to authenticate to resources without prompting the user for authentication. The SSO tokens are stored in the keychain backed by the secure enclave and tokens are only accessible by single sign-on extensions. PSSO can also configure local group membership and authorization rights based on MDM configuration and Identity Provider (IdP) users.

PSSO uses the native macOS login window for username/password and SmartCard authentication and does not use JavaScript or a web view for multi-factor authentication. Instead, device trust is established at initial device registration and all authentication messages are cryptographically signed and/or encrypted using asymmetric keys on both the device and the IdP service. This binds the user to the specific device for login to the Mac system. Additionally, PSSO handles user password changes and updating passwords for unlocking FileVault and the user’s keychain.

On successful authentication, the IdP returns an identity token and a refresh token to PSSO. The refresh token format is determined by the IdP and will be passed to a configured Single Sign-On extension (SSOE) in the user session. The SSOE can use this refresh token to obtain tokens from the IdP to access other network resources. Neither the format of the refresh token nor the token format are defined by PSSO; it is up to the identity provider to implement the token exchange protocol. For example, Microsoft Entra uses a Primary Refresh Token (PRT) to exchange for resource-specific tokens. The PRT is obtained on initial login and passed to the SSOE. The SSOE then exchanges the PRT for resources in a user session.

PSSO has 3 different setups for obtaining SSO tokens:

1. User Login: The user logs in with a username and password and returns a refresh token.

2. Secure Enclave: After authenticating to their local account, a derived key is created by the secure enclave specific to this user. The derived key is shared with the IdP and is used by PSSO to obtain a refresh token from the IdP in the user session without further prompting the user for credentials.

3. Smart Card: The user authenticates with a smart card and a refresh token is returned. The smart card is used to log in at the login window and unlock the keychain (and FileVault).

Scope

This document does not cover every feature of PSSO. It does not cover WS-Trust for federated authentication with ADFS (or other WS-Trust federated providers) and does not go in-depth on smart card authentication. It also only covers PSSO version 2.0. Version 1.0 did not have device registration and had user-specific keys. Platform SSO also has a credential flow mainly for Kerberos and is not covered in this document. 

How PSSO Works

PSSO can request tokens in different ways depending on configuration, but the overall purpose of PSSO is to authenticate to the IdP with credentials specific to the user, and receive back a refresh token and an identity token to be used for Single Sign-On in the user session. The authentication request must come from a specific Mac system and PSSO uses device binding with asymmetric keys to achieve this. The device binding occurs during initial device registration. After the device registration, all requests and responses are tokens that are signed or encrypted with these asymmetric keys. This allows the IdP to verify the authentication came from a specific Mac system, and allows PSSO to verify the tokens were sent from the IdP. How the tokens are signed and/or encrypted are described later in this document.

PSSO requires an authentication provider extension (typically called a Single Sign-On Extension, or SSOE) inside a container app installed on the Mac system. A configuration profile must also be installed to the Mac system from a Mobile Device Management (MDM) service to configure PSSO. Once both of these components are installed on the Mac system, any logged in user will be prompted for device registration, then user registration. Any existing local users who have not registered will be requested to register on the next login.

Device Registration

Device registration is requested in a user session and the device cannot be registered silently. If the device is unregistered, any logged in users will be prompted to register the Mac system. They will be prompted for a local admin username and password. On successful authentication to the local Mac system, two keys will be created:

Device Encryption Key: An Elliptical Curve Asymmetric key for decrypting data from the IdP to the Mac system
Device Signing Key: An Elliptical Curve Asymmetric key for signing data sent to the IdP from the Mac system.

Once the keys are created on the Mac system in the keychain backed by the secure enclave, the public keys are sent to the IdP with identifiers along with a device identifier. The device and key identifiers are used to look up keys and devices when requested in subsequent operations. Once the device is registered, a random symmetric key is returned for use for key exchange.

User Registration

User registration authenticates the user to the IdP by sending the username and password. On successful authentication, the Mac system is configured to support all three authentication methods defined in the next section. The Mac system is configured as follows:

1. The local user account is associated with the IdP username.

2. If the authentication method is defined as a password in the MDM profile, the local user password is changed to match the cloud password.

3. The user registration response will contain an X.509 certificate that is inserted into the Mac system as a persistent token. This persistent token is used to unlock the keychain if the user’s IdP password changes and the user attempts to log in. 

Group Membership

See the Platform_SSO_developer_documentation-v2-0 for more information

Create user during login

See the Platform_SSO_developer_documentation-v2-0 for more information

MDM Configuration

See the Platform_SSO_developer_documentation-v2-0 for more information

Authentication Methods

PSSO supports three authentication methods, each with its own set of features: Login Window, Secure Enclave, and Smart Card. The MDM profile defines the authentication method and determines how tokens are obtained from the IdP. All three authentication methods result in an identity token, and a refresh token is returned to PSSO from the IdP and made available to the SSOE in the user session. 

Password

Password authentication is used to get a refresh token when the user authenticates at the login window with a username and password.

The username and password are sent (either encrypted or plaintext over an encrypted link) to the IdP for authentication from the login window. The IdP username is associated with an existing local user account or the user account is created. Once the IdP has verified the user, identity and refresh tokens are returned. The refresh token is sent back occasionally to the IdP from the user session to keep the tokens current. 

Secure Enclave

Secure Enclave authentication is used to get a refresh token after the user has logged in using a shared secret in the secure enclave from the IdP. The shared secret is shared between the IdP and user account (stored in the secure enclave and only accessible once logged in to that user account).

The user logs in to the Mac system using a local account and they are prompted for their cloud and local credentials. A derived key is created in the secure enclave and is sent with the cloud authentication to the IdP. On successful registration, an identity token and refresh token is returned. The refresh token is sent back occasionally to the IdP from the user session to keep the tokens current. In subsequent logins, the derived key is used to acquire a refresh token in the user session.

Smart Card

Smart Card authentication is used to get a refresh token at the login window when the user logs in to the Mac system with a smart card.

When a user authenticates with a smart card that is mapped to a local user account, the authentication is signed with the smart card certificate associated with the user. If the IdP can validate the signature, a refresh token is returned. The refresh token is sent back occasionally to the IdP from the user session to keep the tokens current. 

Authentication Response

Successful authentication with PSSO results in an identity and refresh token returned by the IdP to PSSO. This response is based on an OAuth 2 response token, but without the access token.  PSSO then makes these tokens available to an associated SSOE in the user session. The response token contains this information (as well as some other related info):

ID Token: Information about the user that has authenticated
Refresh Token: Opaque data that is passed back to the IdP for SSO
Expires In: Date when the refresh token will expire

Identity Token

The identity token contains information about the user who has successfully logged in. It must contain:

iss: Issuer Identifier for the Issuer of the response. This value must match the issuer configured in the extension.
sub: Subject Identifier 
aud: Audience(s) that this ID Token is intended for. This must match the issuer sent in the request.
exp: Expiration time on or after which the ID Token must not be accepted
iat: Time the token was issued

Refresh Token

The authentication response also contains a refresh token. This is an opaque data blob that can be sent to the IdP for either another refresh token to extend the life of the refresh token, or an SSO request for a service. The IdP can use this as a unique identifier or can encrypt and sign user and device specific data that may be helpful for the Sign Sign-On extension in the user session.

IdP Endpoints

PSSO communicates with the IdP over the following endpoints:

nonceEndpoint: Returns an opaque nonce to the requestor. It is used to verify the IdP is communicating to a live client and as replay prevention. PSSO will request a nonce from the IdP and include it in requests. The IdP will then verify that the nonce has not been used before and has issued the nonce used.
tokenEndpoint: This is the main communication endpoint. It is used to post user authentication requests.
keyEndpointURL: This endpoint is used for creating and using the key to unlock the keychain and FileVault. 
jwksEndpoint: When PSSO needs to encrypt data with the public key of the IdP, the JWKSEndpoint provides the public key for the encryption.

Request and Response with JSON Web Tokens

After device registration, all requests are handled by the configured PSSO and requests and responses are not passed to the single sign-on extension. If there is an issue with the registration, the single sign-on extension used for PSSO configuration may be called again, but the process of requesting tokens is handled by PSSO without calls to the single sign-on extension. The IdP must implement the endpoints and process the requests sent to these endpoints. All requests are sent with JSON Web Tokens (JWT) that are signed and/or encrypted, depending on the operation requested. The tokens will have a different format depending on the version of PSSO being used and the version of PSSO will be passed with the request. The JWTs are not posted directly to the endpoint, but are part of a form post that contains other information, including the version number of PSSO. This version number is used to determine the format of the JWT.

Form Request

The form data sent to the IdP is a standard HTTP form with a Content-Type of application/x-www-form-urlencoded:

POST /oauth2/token HTTP/1.1

Host: auth.example.com

Accept: application/platformsso-key-response+jwt

Content-Type: application/x-www-form-urlencoded

client-request-id: <Request ID>


platform_sso_version2.0&grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=<JWT>

JWT Signature Verification

To process the request at the endpoint, the IdP service will determine the PSSO version and process the JWT based on the PSSO version. The JWT contains a header, a body and a signature. The header contains the key ID used to sign the token. The key ID was sent during registration, and the public key of the device can be looked up based on the key ID. This public key is then used to verify the signature of the token. 

Once the signature has been verified, the body of the JWT can be processed. 

Claims

Claims are attributes asserted in the request. For example, if the JWT contains a request to authenticate a user, the JWT claim would have a username and password to be verified. 

Embedded Assertions

If the authentication requires a digital signature, like smart card authentication or secure enclave, the claims will include an embedded assertion. This assertion is signed by the smart card or secure enclave key and used to verify the authentication. If the assertion contains an encrypted password, it is decrypted using the JWKS key.

PSSO Cryptographic Token Internals

Tokens exchanged between the IdP and PSSO are signed and sometimes encrypted. Since the keys used by PSSO are generated in the secure enclave, Elliptical Curve Cryptography is used for signing and encrypting.

JWT Signed (JWS) tokens

JSON Web Tokens contain 3 parts: Header, Body, and a Signature. The Header contains information about how the body was signed. The Signature part contains the actual signature. To verify the signature, the information in the header is used to determine how to verify that the signature part is valid for the body of the JWT.

JWT Encrypted (JWE) token

If the signed JWT (JWS) needs to be encrypted, the JWS is converted to binary data (known as marshaling). To encrypt the data, a key must be derived. PSSO uses ConcatKDF. ConcatKDF is a concatenation Key Derivation Function (KDF) to derive a shared key from the result of performing Diffie-Hellman key exchange. The process for encryption is documented in the Performing Encryption Verification document at https://developer.apple.com/documentation/authenticationservices/performing-encryption-verification#4295826.

An example of encrypting a token:

alg: Algorithm (A256GCM)

apu: Info about the ephemeral key in X9.63 format

apv: Info about the receiver's key in X9.63 format

ephemeral: ephemeral ECC key created for this encryption

deviceEncryptionPublicKey: public key of the receive

sharedSecret = josecipher.DeriveECDHES(alg, apu,apv, ephemeral, deviceEncryptionPublicKey, 32)

apv and apu are X9.63 bytes that contain “APPLE” + ECC.X + ECC.Y.

This shared secret is then used to encrypt the data. The receiver will use its ECC key, the apu, apv, and ephemeral public key to generate the same shared secret and use it to decrypt the token.

TLS Encryption and Trust Certificates

Because the login process could happen on any network, all HTTP requests are sent using TLS and use the current App Transport Security settings. The requests explicitly require that the issuer of the TLS certificate is included in the system-provided root CAs. User-trusted CAs or MDM-provided CAs are not trusted for these requests. The CAs are limited to ensure the TLS tunnel to the IdP does not include any third-party products with security vulnerabilities or intentionally malicious code.

Device and User Registration

In order to use PSSO and activate device registration, a Single Sign-On Extension with PSSO methods implemented must be installed, and a configuration profile with PSSO configured must be sent from an MDM service. The configuration cannot be done locally, and the Mac system must be enrolled in the MDM service. If the SSOE is installed and configured correctly, the logged-in user will be prompted to begin registering the device with the identity provider. The extension developer is responsible for providing a login interface to authenticate the user and allow registration. This is covered later in this document when creating an SSOE with PSSO.

The extension developer is also responsible for sending the device keys to the IdP. When registration starts, a PSSO configuration method beginDeviceRegistration(loginManager:options:completion:) is called. The loginManager gives access to the public key to the signing and encrypting keys. These keys should be sent to the IdP for verifying signatures and encrypting tokens sent to the Mac system.

Once device registration is complete, beginUserRegistration(loginManager:userName:method:options:completion:)

is called and the extension developer can prompt for additional authentication and information from the user, and post to the IdP as needed.

The API for the IdP for registering the device and user is not defined by PSSO and is defined by the extension developer for posting the registration data. The posted data format is defined by the application developer as well.

Once the registration is complete, the extension is not called for PSSO operation and all communication between PSSO and the IdP is handled by the configured PSSO on the Mac system.

PSSO Messages

Authentication

In order to obtain tokens from the IdP, PSSO needs to authenticate to the IdP. Depending on how PSSO is set up to authenticate, it can do so in two general flows. The authentication can happen with a username and password entered by the user, or through a signed or encrypted assertion in the authentication token sent to the IdP to authenticate. The assertion is used for an encrypted password, Smart Card authentication, or User Secure Enclave authentication.

Password Authentication

With Password Authentication, a JWT is sent from a registered Mac by PSSO to the IdP. The JWT contains the username and password and is verified by the IdP. The IdP then returns an ID Token and a refresh token in an encrypted JWT:

1. PSSO requests a nonce from the IdP endpoint. This will be included in the authentication request to prevent message replay. 

2. The IdP returns a nonce.

3. PSSO sends a JWT signed with the device signing key. The JWT contains the username and password of the user to be authenticated, along with the nonce from step 2.

4. The IdP verifies the signature on the JWT with the device public key and then verifies the password. The IdP then returns a JWT signed with the key from the JWKS and encrypted with the public key of the device.

5. PSSO decrypts the data using the device encryption key and verifies the signature using the public key from the IdP service JWKS endpoint.

6. PSSO now has the refresh token and identity token.

Username and Encrypted Password

1. PSSO requests a nonce from the IdP endpoint. This will be included in the authentication request to prevent message replay. 

2. The IdP returns a nonce.

3. PSSO sends a JWT signed with the device signing key. The JWT contains the username of the user to be authenticated, along with the nonce from step 2. The JWT also contains an embedded assertion that is encrypted with the public key of the IdP service JWKS endpoint. The embedded assertion contains the password.

4. The IdP verifies the signature on the JWT with the device public key and then decrypts the embedded assertion to retrieve the password. The IdP then returns a JWT signed with the key from the JWKS and encrypted with the public key of the device.

5. PSSO decrypts the data using the device encryption key and verifies the signature using the public key from the IdP service JWKS endpoint.

6. PSSO now has the refresh token and identity token.

Smart Card

1. PSSO requests a nonce from the IdP endpoint. This will be included in the authentication request to prevent message replay. 

2. The IdP returns a nonce.

3. PSSO sends a JWT signed with the device signing key. The JWT contains the username of the user to be authenticated, along with the nonce from step 2. The JWT also contains an embedded assertion. The embedded assertion is signed with the smart card identity.

4. The IdP verifies the signature on the JWT with the device public key and then verifies that the JWT was signed with the smart card identity. The IdP then returns a JWT signed with the key from the JWKS and encrypted with the public key of the device.

5. PSSO decrypts the data using the device encryption key and verifies the signature using the public key from the IdP service JWKS endpoint.

6. PSSO now has the refresh token and identity token.

Secure Enclave

1. PSSO requests a nonce from the IdP endpoint. This will be included in the authentication request to prevent message replay. 

2. The IdP returns a nonce.

3. PSSO sends a JWT signed with the device signing key. The JWT contains the username of the user to be authenticated, along with the nonce from step 2. The JWT also contains an embedded assertion. The embedded assertion is signed with the user secure enclave key.

4. The IdP verifies the signature on the JWT with the device public key and then verifies that the JWT was signed with the secure enclave key. The signature is verified by using the public key of the secure enclave key that was sent to the IdP during registration. The IdP then returns a JWT signed with the key from the JWKS and encrypted with the public key of the device.

5. PSSO decrypts the data using the device encryption key and verifies the signature using the public key from the IdP service JWKS endpoint.

6. PSSO now has the refresh token and identity token.

Key Request

When PSSO is set up for password authentication, the user keychain must be unlocked during user login at the login window. If the user password changes on the IdP, the keychain cannot be unlocked with the new password. To unlock the keychain, PSSO requests a certificate that contains an ECC public key from the IdP through a key request during registration. This certificate is then inserted with CryptoTokenKit as a persistent token to unlock the keychain using a certificate-backed persistent token. 

1. After device registration, a key request token is sent to the IdP. 

2. The IdP creates a new ECC key and X.509 certificate with the public key of the new key and returns a JWT signed with the signing key from the JWKS and encrypted with the public key of the device. 

3. The IdP returns the certificate in a JWT signed with the key from the JWKS and encrypted with the public key of the device.

4. PSSO creates a new ECC key and derives a shared secret using the local ECC key and the public key in the returned certificate.

5. PSSO rekeys the keychain to use the new derived symmetric key.

Key Exchange

When PSSO is set up for password authentication and the IdP password changes, the user can log in to the Mac with the new password but the new password cannot be used to unlock the keychain. The login window and lock screen . 

1. User logs in with a new IdP password that does not match the current local user password.

2. Login window attempts to unlock the keychain using the persistent token. 

3. The login attempt triggers a request to the IdP key exchange endpoint. The request is a signed JWT containing the public key of the local ECC key.

4. The IdP uses the private key from the key created during the key request step and the sent public key to derive the shared secret.

5. The IdP then returns the shared key in a JWT signed with the key from the JWKS and encrypted with the public key of the device.

Using PSSO SSO Tokens with the SSOE

PSSO’s purpose is to obtain SSO tokens to authenticate resources on a network. The only requirement on the IdP is that a refresh token is provided as a binary opaque piece of data. The format of the data depends on how the IdP intends to use the refresh token. After the user has logged in, a refresh token is obtained, and a Single Sign-On functionality is configured, any app or web browser that attempts to access a defined URL is blocked, and the URL request is passed to the SSO extension with the beginAuthorization(with:) method. The Single Sign-On extension can present a user interface or access other network resources to complete the request. The PSSO refresh token is made available to the Single Sign-On extension, and that token can be used to authenticate to the resource, typically by presenting the refresh token to the IdP in exchange for a token or header that can be inserted into the request that is being blocked. Once this operation is complete, the blocked URL can be redirected back to the requested resource.

Comparison with Browser SSO

When authenticating with a browser to network resources and using single sign-on, it is common to be redirected from the network resource to the IdP. The browser will have session cookies from a prior IdP login and the IdP will redirect back to the network resource with the required information to complete the authentication without user intervention.

With PSSO, there are no web cookies since the initial authentication is not done in a web browser. The result is an opaque refresh token. The IdP must be set up to accept this refresh token to give tokens or headers to access the network resource. It may be possible to exchange the refresh token for session cookies in the SSO extension and redirect the request to set those cookies and complete the request, but how the refresh token is used is determined by the IdP and the network resources. Since PSSO authentication is based on the opaque refresh token, the token could contain information to bind that token to that specific machine (such as including a device identifier and signed by the IdP) to prevent use after exfiltration.