Raphael Medaer
Raphael Medaer

Reputation: 2538

What is the OAuth flow to generate access token without consent from resource owner?

Roles and terminology used in this question are the same as RFC 6749.

Description of the use-case

I want to allow a trusted OAuth client to ask authorization server to issue an access token on behalf of the resource owner without his consent (and without involving neither him nor his agent in the flow).

Investigations

As far as I know, there is not any grant matching this flow in RFC 6749, Section 4:

Grant Suitable Why
Authorization Code Grant
RFC 6749, Section 4.1
No It involves both Resource Owner and User-Agent.
Implicit Grant
RFC 6749, Section 4.2
No It also involves both Resource Owner and User-Agent.
Resource Owner Password Credentials Grant
RFC 6749, Section 4.3
No It might work if we knew the password of the resource owner, but we don't.
Client Credentials Grant
RFC 6749, Section 4.4
No, but.. It doesn't involve the Resource Owner or his User-Agent but it's not granting access on behalf of a user.
Token Exchange
RFC 8693, Section 2
No, but.. It requires an initial token (named subject_token) which doesn't exist in my scenario.

Client Credentials

The Client Credentials grant is promising because it allows a client to access protected resources owned by a resource owner without involving him. Although, in my understanding, it's not on behalf of the resource owner. Quoting the RFC 6749, Section 4.4:

The client can request an access token using only its client credentials (...) when the client is requesting access to the protected resources under its control, or those of another resource owner that have been previously arranged with the authorization server (...).

Therefore, with access token returned by Client Credentials grant, it is for instance impossible to assign a sub claim value as defined in RFC 7662, Section 2.2: OAuth 2.0 Token Introspection > Introspection Response (cf. RFC 7519, Section 4.1.2: JWT ).

Token Exchange

This grant has been suggested by @Kaankom. See @Kaankom 's answer.

The RFC 8693 defines how to obtain a security token employing impersonation and delegation. It sounds like the perfect grant for my use-case but this grant requires as input a subject_token parameter which "represents the identity of the acting party." The RFC says:

Typically, this will be the party that is authorized to use the requested security token and act on behalf of the subject.

I don't have this token. However, I could maybe forge a new one (see Solution 5).

Non-standard solutions

Solution 1: A new OAuth grant

RFC 6749, Section 4.5 allow us to implement a new grant type. Similar to Client Credentials, this brand new grant would REQUIRE an additional parameter in his Access Token Request. This parameter would define the resource owner identifier for which the client will act on behalf of the resource owner.

Solution 2: Tweak the Client Credentials grant

Instead of implementing a new OAuth grant (cf. solution 1), we could instead add an optional parameter in existing Client Credentials grant. If specified, the authorization server should validate that the client is allowed to act on behalf of the requested resource owner (specified by the new parameter).

Solution 3: Tweak the Authorization Code grant

Using the Authorization Code grant, we could bypass steps A, B and C as defined in RFC 6749, Section 4.1 and let the client request an access token without having to add a code or a redirect_uri but with its client credentials and an additional parameter which define the resource owner.

Solution 4: Implement it out of OAuth

Browsing the internet, you might find implementations which are bypassing the OAuth mechanism and its access_token. For instance, in article "How to Convert from APIKey to OAuth 2.0 Client Credentials", they are using an extra HTTP header Acting-For on resource server calls.

Solution 5: Token Exchange grant with self-forged token

The Token Exchange grant requires a subject_token but (as far as I know) it doesn't define the policy that the authorization server SHOULD apply based on this token. Therefore, it would be theorically possible for the client to forge an unsigned JWT with the target subject (sub claim) and obtain a signed JWT in return. It looks promising but requires more investigation.

Notes

I intentionally not named the parameter used in solution 1, 2 and 3. However OpenID Connect Core 1.0, Section 3.1.2.1/Section 4 is defining an optional parameter named login_hint which "hint to the Authorization Server about the login identifier the End-User might use to log in". However sub might be another good proposal.

Upvotes: 2

Views: 1351

Answers (3)

Raphael Medaer
Raphael Medaer

Reputation: 2538

Introduction

The following answer describes the flow, grant and parameters that may be used to allow a trusted OAuth client to obtain an access_token without the prior resource owner consent. This method is using the Token Exchange grant (defined in RFC 8693) in an impersonation scenario where the client would have to forge an unsecured subject_token and exchange it for a secured access_token. This method assumes that the authorization server produces and consumes JWT (RFC 7519). It would not work with opaque token.

Sequence Diagram

Sequence Diagram to allow a trusted client obtain access_token without resource owner consent thanks to token exchange grant

Step 1: Forge the initial JWT

In this first step, the client forges an initial unsecured JWT token (RFC 7519, Section 6). This JWT MUST contain at least the subject (sub) claim with, as value, the resource owner or another subject that the client want to impersonate.

Step 2: The client requests to exchange the initial unsecured JWT for a secured access token

The client exchanges the JWT forged in step 1 for a secured access token. According to RFC 8693 Section 2.1, the client sends a Token Exchange request with the following headers/parameters:

  • the Authorization header contains the client credentials (client id and client secret), following the Basic Authentication scheme.
  • the body parameter grant_type specify the grant type we want to use: token_exchange
  • the body parameter subject_token contains the JWT forged in step 1
  • the body parameter subject_token_type specify the subject token type we forged: an access_token (which is actually a JWT)

This is the bare minimum that the client MUST send. Although it SHOULD probably specify the audience, the target resource server and the list of scope.

Step 3: The authorization server returns the access token

According to its policy, the authorization server identifies the client as trusted and therefore allows to generate an access_token with unsecured subject_token in input. The subject defined in the subject_token (sub claim) is recycle in the generated access_token.

The authorization server will also add an Actor claim (act) according to RFC 8693, Section 4.1. The value of this claim is a JSON object with another sub key and the client id as value.

Step 4: The client requests a resource

In this example, the client requests a "personal" resource (/my/resource) with the access token. The sub claim inside the JWT is used to identify the "my" aka the subject.

Step 5: The resource is returned with an impersonation of the subject

That's it.

Disclaimer

I never implemented or tested this solution. It obviously requires a few changes in your authorization server and its policy. No security audit has been performed. Be careful with this flow. Confirmation from OAuth experts should be required prior to implementation.

Upvotes: 0

Kaankom
Kaankom

Reputation: 159

The Use Case you described sounds like impersonation.

Take a look at this: RFC 8693 - Token Exchange

Upvotes: 2

Gary Archer
Gary Archer

Reputation: 29218

You've not really described the use case / requirement, though I will describe something that may be in line with your use case and give you some ideas. Perhaps thinking more in terms of claims and API aauthorization will solve your problem in a standard way?

CORPORATE ASSETS USE CASE

Sometimes the assets don't belong to the end user and an entity has permissions to operate on a subset of users:

  • An investment bank may be able to update certain details for its employees in a wider trading system

  • A doctor's surgery may be able to update medical details for its patients in a system that contains nationwide data

In OAuth terms the bank / surgery would use the client credentials grant, and be identified by either a client ID or possibly a custom claim in the token issued.

If bank A tried to use their access token to update details for a trader at bank B, it would fail API authorization and they would receive an HTTP response with status 404, meaning data not found for caller.

It would not be natural though for bank A to get an access token for Jane Doe when updating that record, since that is not the caller identity. At an auditing level:

  • The Authorization Server would indicate that a token was issued to bank A
  • The API would indicate that the record for Jane Doe was updated by bank A.

The API could have many intricate domain specific rules around which type of data updates are allowed. These are usually managed in the API logic, while the access token contains only key caller identity information that the API can digitally trust before applying rules.

For more on this topic see our Claims Best Practices article.

Upvotes: 0

Related Questions