Skip to content

Instantly share code, notes, and snippets.

@mcguinness
Last active October 9, 2022 01:06
Show Gist options
  • Save mcguinness/85116690d556f8ddf280143469063a6c to your computer and use it in GitHub Desktop.
Save mcguinness/85116690d556f8ddf280143469063a6c to your computer and use it in GitHub Desktop.
Online Access Refresh Tokens

Problem Statement

The OAuth 2.0 Authorization Framework defines the authorization_code grant type and refresh token. It doesn't establish any rules for issuing refresh tokens and explicitly states in Section 1.5 that "Issuing a refresh token is optional at the discretion of the authorization server". One of the explicit goals for Rfc6749 was to enable offline access to protected resources when the end-user is not present. It does not define any request semantics for how a client can explicitly request a refresh token or whether that refresh token's lifecycle should be bound to the user's session that granted the refresh token. Authorization Servers are free to define these behaviors on a per-implementation or policy basis.

OpenID Connect being the identity layer ontop of OAuth 2.0 needed to define some new authorization server behaviors to enable end-user consent for when a client can access their identity info (UserInfo). This resulted in a new scope offline_access being defined to allow a client to access their identity info when they are not present.

offline_access
OPTIONAL. This scope value requests that an OAuth 2.0 Refresh Token be issued that can be used to obtain an Access Token that grants access to the End-User's UserInfo Endpoint even when the End-User is not present (not logged in).

OpenID Connect 1.0 does not define how the offline_access scope should constrain access to other protected resources, nor does it define the behavior of the refresh token if this scope is not requested. Authorization Servers are free to define behaviors for other protected resources and/or non-OIDC defined scopes when offline_access is requested.

The use of Refresh Tokens is not exclusive to the offline_access use case. The Authorization Server MAY grant Refresh Tokens in other contexts that are beyond the scope of this specification.

There are many large scale OAuth 2.0 deployments the have chosen to only issue refresh tokens for delegated access to their protected non-identity resources only if offline_access scope is requested. This approach often simplified Authorization Server complexity and developer documentation by linking the offline_access OIDC constrain to all protected resources.

OpenID Connect 1.0 also does not define any new behaviors for when an issued refresh tokens should be linked to the authentication session that issued the authorization code/refresh token. Logging out of the OP is an implementation-specific behavior with respect to any issued refresh tokens that were not requested with offline_access scope.

This lack of clarity hasn't historically been a significant issue as refresh tokens were restricted from being issued via the implicit grant in Section 4.2. Refresh tokens were often only used for web or native clients where offline_access was the desired behavior (raison d'etre of OAuth 2.0)

As developers shift to more browser-based applications (e.g Single Page Apps) and leverage cloud identity services, the need to resolve this undefined behavior has reached a tipping point. The OAuth 2.0 for Browser-Based Apps BCP and OAuth 2.0 Security Best Current Practice BCP deprecate the implicit grant and require all browser-based applications to use the authorization_code grant with PKCE. This change requires defining new behaviors for refresh tokens in the browser where it previously never was used. Section 8 of the BCP defines security mitigations to prevent refresh tokens from being leaked but does not define what should happen if the user logs out of the authorization server.

When browser-based apps used the implicit grant they often used patterns like making authentication requests with prompt=none to silently request new access tokens when previously issued access tokens were expired. This pattern relied on the client and the end-user being in the same browser context and having a session with the OP. Logout at OP would prevent these clients from obtaining new access tokens. This not only had security benefits but also user experience benefits especially when switching accounts at the OP.

Proposal

It is desirable to have an explicit pattern for a client to opt-in to a refresh token that is tightly coupled to the user's session at the Authorization Server. An explicit pattern enables the client to express it's intent on whether it wants to operate in a connected or disconnected mode. The Authorization Server can choose to honor this intent or not based on policy.

The recommendation was to introduce a new online_access scope that when requested, binds the issued refresh token to user's session on the Authorization Server. If the user's session is closed or revoked either directly by end-user or indirectly by the Authorization Server such as an inactivity timeout policy the refresh token and children access tokens issued with the refresh token MUST be revoked by the Authorization Server.

Revoking the issued refresh token directly via Token Revocation Endpoint or indirectly via the Authorization Server should only revoke the refresh token and children access tokens and not the user's session.

If the need arises to revoke the user's session at the Authorization Server via the backchannel with a Refresh Token, then a new extension to Logout Specifications should be defined.

The recommendation was to define the new online_access in OIDF as this is consistent with offline_access and relates to authentication concerns. Once defined in OIDF, we can reference in OAuth 2.0 for Browser-Based Apps BCP. We should maybe consider introducing a new client application_type (e.g. browser) that requires online_access scope.

Precedence

The healthcare domain has defined a similar use of online_access with the HL7 FHIR specifications.

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