Access policy for API grant types
Access policy can be applied to API-driven usage of OpenID Connect and OAuth 2.0. This
API usage is most commonly known as the Resource Owner Password credentials grant type (ROPC), but
also includes the JWT assertion-based grant type. These grant types unlike the authorization code
and implicit grant types, have a fundamental difference in how they operate. No browser user-agent
exists, and no requests are made to the /authorize
endpoint. Because this browser
endpoint is not used, the access policy for an application must be assessed differently.
When an access policy is applied, these fundamental business requirements are addressed:
- Has the user authenticated sufficiently to access this application?
- Is the authenticated user allowed to access this application?
- Is the device or client context that is being used to access this application allowed?
In traditional browser flows these requirements are applied. If they are not met, the browser prompts for MFA, or it returns an error page to the user that halts the access. In an API grant type, these faculties are not all available. So the following issues must be addressed.
- Receiving context from a client device.
- Returning an MFA challenge, including,
- The APIs that are needed to fulfill the MFA.
- How to access the APIs.
The policyauth grant type
To effectively apply an access policy to an API only OAuth 2.0 flow, a new grant type is introduced. This grant type allows a client to present some context to the access policy before any authentication. This ability makes it possible to implement an enhanced user experience. For example, when a user presses a login button, before they're prompted to enter any credentials, they are evaluated according to the associated policy. If they do not satisfy the policy requirements, the user receives an error message that indicates that they're unable to authenticate or access the resource because of the policy requirements.
policyauth
grant type is used, one of these responses is returned.- A deny
- An error that indicates that access cannot be granted because of the policy.
- A challenge
- A token that can be used to access authentication APIs is returned, with a list of acceptable authentication factors.
MFA challenge responses from /token
When an access policy is applied to an API OAuth 2.0 flow, a challenge for MFA must become part
of the API contract. The traditional methods of the OP performing the MFA steps as part of the
request to /authorize
are not possible.
When an MFA challenge is returned by /token
,
- The scope is
mfa_challenge
and no other scopes are returned. - An access token is issued.
- The access token is entitled to access the necessary authentication APIs. It's important that this access token is used, and not a regular API client access token. This token is used to track already performed authentication factors and past actions across the grant.
- The access token returns
active: true
from requests to/introspect
. Any APIs that protect a resource server must, when MFA challenges are being used, implement a check that thescope
returned from/introspect
does not equalmfa_challenge
.
- Optionally, an array of factors that can be performed to satisfy this challenge
allowedFactors
is listed.
Presenting context to /token
The API client that performs a request to /token
can present well-defined and
arbitrary context information to /token
to use in access policy evaluation.
Three mandatory pieces of context information must be included.
sessionId
- An arbitrary session identifier that is issued and maintained by the OAuth client.ipAddress
- Because the OAuth client is responsible for the interactions with the user-agent, the user IP address must be explicitly provided.userAgent
- Similarly to IP address, the user-agent of the user must be explicitly provided.
More parameters can be included and context attribute conditions can be authored on these values.
context
parameter is not included in a request to
/token
, the access policy is not invoked.Context is provided to /token
in the form of base64 encoded JSON. An example
JSON payload for context is:
{
"sessionId":"MDNjZmQ3NDM2NjFmMDc5NzVmYTJmMT",
"ipAddress":"129.42.38.10",
"userAgent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36"
}
Context information is considered trusted, as it is presented by an API client that was issued a secure set of client credentials. That API client must ensure it doesn't allow context to be arbitrarily presented by the consuming user-agent, which can then be used to circumvent business controls.
Context must be presented whenever an access policy is invoked across all the API grant types,
policyAuth
, JWT Bearer
, ROPC
and refresh
token
.
Satisfying mfa_challenge
To satisfy an MFA challenge that is returned by the /token
endpoint, the
authentication factors APIs can be used. These APIs are used to satisfy both first and second factor
requirements. The access token that is returned in the mfa_challenge
response is
used to request the appropriate factor. After a successful factor completion, a JWT is returned.
This JWT contains a few key pieces of information.
- The
grant_id
that is derived from the access token that was used to request the factor API. This ID maintains correlation across the different requests to/token
. - The
factor
that was performed and any factors that were performed previously.
This JWT is presented to /token
as part of a jwtBearer
grant
type flow. The access policy is reassessed and a fully entitled token or another challenge is
issued.
returnJwt=true
must be included.- The following first-factor authentication APIs support this flag:
- The following MFA APIs support this flag:
- https://securitypoc.ice.ibmcloud.com/developer/explorer/#!/Email_One-time_Password_2.0/attemptEmailotpVerification_2_0
The transient verification API also supports this flag. However, to use the JWT that is issued by it, the mapping of the subject claim must be configured.
- https://securitypoc.ice.ibmcloud.com/developer/explorer/#!/SMS_One-time_Password_2.0/attemptSmsotpVerification_2_0
The transient verification API also supports this flag. However, to use the JWT that is issued by it, the mapping of the subject claim must be configured.
- https://securitypoc.ice.ibmcloud.com/developer/explorer/#!/FIDO/assertionResult
A passkey can be used as either a first or second factor.
- https://securitypoc.ice.ibmcloud.com/developer/explorer/#!/Voice_One-time_Password_2.0/attemptVoiceotpVerification_2_0
The transient verification API also supports this flag. However, to use the JWT that is issued by it, the mapping of the subject claim must be configured.
- https://securitypoc.ice.ibmcloud.com/developer/explorer/#!/One-time_Password/attemptOtpVerification_2_0
- https://securitypoc.ice.ibmcloud.com/developer/explorer/#!/Time-based_One-time_Password_2.0/verifyTotpEnrollment_2_0
- https://securitypoc.ice.ibmcloud.com/developer/explorer/#!/Email_One-time_Password_2.0/attemptEmailotpVerification_2_0
- For transient factor APIs, the
sub
field of the JWT is populated with the transient information that is used in the request. For example, the email or the phone number rather than auserId
. - When
returnJwt=true
is set, verification APIs that usually return a status code of204
with no HTTP body, change their status code to a200
. They return thecontent-type
ofapplication/json
and have a response like:
For factor verifications that already return JSON, the{ "assertion:"ey..."}
assertion
property is added to the response.
Applying access policy to different grant types
When you configure an application, an option exists of whether the access policy is applied to a specific grant type.
This configuration controls whether the access policy is evaluated on a request to
/token
that is based on the value of the grant_type
parameter.
This evaluation applies regardless of any prior invocations of /token
for a
specific grant.
policyauth
- Access policy must always be enabled.
ROPC
- Access policy can be disabled if the consumption of the ROPC grant type doesn't support the
mfa_challenge
response. JWT Bearer
- When access policy is disabled on the
jwt-bearer
grant type, an MFA cannot be done through thepolicyauth
flow. An access policy won't run after the first factor is performed. Refresh token
- Can be applied to only a subset of
refresh_token
requests that use the context parameteroriginal_grant_type
as a context attribute condition.