Token and key security
The Ping SDKs handle and store keys and tokens based on the security best practices of each platform.
Token storage
Depending on the authentication use case, the SDKs will potentially have to store and be able to retrieve the session cookie, ID tokens, access tokens, and refresh tokens.
Each token is serving a different use case, and as such how the SDKs handle them can be different.
The following sections cover how the SDKs handle different types of tokens.
Session tokens and cookies
-
On Android and iOS, the session tokens are stored in either the Android keystore or iOS keychain after authentication completes. The tokens are encrypted using a hardware-backed security key when possible and can be retrieved by the SDK on request.
-
When using the Ping SDK for JavaScript, cookies are stored in the browser’s cookie storage. The cookie name matches the one provided by PingAM (such as
iPlanetDirectoryPro
) and its value is the actual session token. When making requests to PingAM, the value is passed as an authentication cookie. This cookie is configured with theHTTPOnly
andSecure
attributes, which provide additional layers of security.
ID, access, and refresh tokens
-
On Android and iOS when authorization is completed any OAuth 2.0-related tokens are stored securely locally, encrypted using a hardware-backed security key when possible and can be retrieved by the SDK on request. Tokens are not configured as cloud sharable by default.
-
When using the Ping SDK for JavaScript, the OAuth 2.0 Tokens are stored by using one of the web storage APIs provided by the browser. By default, this uses the browser’s
localStorage
, but the SDK also supportssessionStorage
.If required, app developers can provide a custom storage mechanism that can be passed to the SDK.
We recommend that JavaScript single-page applications do not use refresh tokens or any other long-running authorization elements due to the potentially unsecure nature of the storage mechanisms provided by browsers.
Token lifecycle
The session and OAuth 2.0-related tokens the SDKs handle all have associated expiry times. When a token reaches its expiry time it becomes unusable.
A feature of the SDKs is that they manage the refresh of OAuth 2.0 tokens. The timing of the refresh is based on a threshold value to improve the end-user experience. The SDKs refresh tokens automatically when the token is requested from storage to be used in your application and its expiry is within the threshold.
In the case of access tokens, if a refresh token is present, then the Android and iOS SDKs will use it to obtain a new access token. If the refresh token cannot be used, is not present, or if it has expired, then the SDKs fall back to using the session token to start a new OAuth 2.0 flow.
The SDKs do not handle the refresh of session tokens. If a session token has expired, the app needs to re-authenticate the user. |
When an OAuth 2.0 or session token expires, the SDK removes any respective tokens from the secure storage and performs a cleanup. The Android and iOS SDKs also check if the current session token is the same one used to obtain the OAuth 2.0 tokens. In case of a mismatch, then these orphaned tokens are cleaned.
When using SDK logout methods to perform a Logout
event, the SDKs revoke existing OAuth 2.0 tokens, revoke the session, and perform a local cleanup. If the SDKs are unable to revoke the session at the server—for example the network is unavailable—then the SDKs remove the tokens from local storage.
When using the Ping SDK for JavaScript, if an access token expires within the threshold limit or returns an HTTP 401 Unauthorized
error, the SDK attempts to renew it using the same session cookie that was performing the authorization code flows.
The Ping SDK for JavaScript calls the endSession
and session?action=logout
endpoints during logout, as well as calling revoke
whenever you use FRUser.logout
. This ensures that the server invalidates the session cookie.
The Ping SDK for JavaScript has no direct control over the session cookie; it can only make requests to the browser that may or may not be acted upon. Instead, it must rely on the server to manage the cookie removal. |
Encryption key storage
On supported platforms and devices, the Ping SDKs generate Hardware-Backed encryption keys, and uses them to encrypt and store tokens. This provides an extra level of security against attacks.
-
The Ping SDK for iOS uses the
kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM
encryption algorithm. The key is stored in the Secure Enclave.On unsupported devices, the SDK cannot not enforce hardware-backed encryption and will save the tokens in the iOS keychain.
-
The Ping SDK for Android uses a number of different algorithms, depending on the OS version and device functionality. It supports the following encryptors:
-
AndroidLEncryptor
: RSA -
AndroidMEncryptor
: AES -
AndroidNEncryptor
: Similar to M, with the addition of settingsetInvalidatedByBiometricEnrollment
totrue
-
AndroidPEncryptor
: Similar to N, with the addition of using Android Strongbox
-
Hardware-backed key storage and encryption
Both the Android and iOS SDKs use platform-provided methods to create hardware-backed encryption keys.
-
On iOS the SDK creates keys within the
SecuredKey.swift
class. IfSecuredKey
generation fails, theKeychainManager
generates theKeychainService
with noSecuredKey
. The values in this case will be added to the iOS keychain askSecClassGenericPassword
types.If
SecuredKey
creation is successful then the value is encrypted before being stored. TheSecuredKey.swift
class provides anisAvailable()
public method that validates whether creation of theSecuredKey
using Secure Enclave is available on the device or not.The SDKs also support devices that do not have Secure Enclave or other hardware-backed encryption functionality. -
On Android, the SDK uses
DefaultTokenManager
andDefaultSingleSignOnManager
for storing tokens, in addition toSecuredSharedPreferences.java
on supported devices.Depending on the Android version, the SDK can use more specific encryptors. For more information, see
getEncryptor
. For information about the different encryptor classes, see theauth
folder in GitHub.