Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

consent: Add ability to specify Access Token Audience #883

Closed
aeneasr opened this issue May 25, 2018 · 13 comments
Closed

consent: Add ability to specify Access Token Audience #883

aeneasr opened this issue May 25, 2018 · 13 comments
Assignees
Labels
Milestone

Comments

@aeneasr
Copy link
Member

aeneasr commented May 25, 2018

Currently, the audience of the ID Token is set explicitly in the oauth2 handler:

	// done
	response, err := h.OAuth2.NewAuthorizeResponse(ctx, authorizeRequest, &Session{
		DefaultSession: &openid.DefaultSession{
			Claims: &jwt.IDTokenClaims{
				Audience:    authorizeRequest.GetClient().GetID(),
				Subject:     session.ConsentRequest.Subject,
				Issuer:      h.IssuerURL,
				IssuedAt:    time.Now().UTC(),
				ExpiresAt:   time.Now().Add(h.IDTokenLifespan).UTC(),
				AuthTime:    session.AuthenticatedAt,
				RequestedAt: session.RequestedAt,
				Extra:       session.Session.IDToken,
			},
			// required for lookup on jwk endpoint
			Headers: &jwt.Headers{Extra: map[string]interface{}{"kid": h.IDTokenPublicKeyID}},
			Subject: session.ConsentRequest.Subject,
		},
		Extra: session.Session.AccessToken,
	})

and the audience of the access token is set by the extra session. Instead, the audience should be a first-class citizen of the consent flow/responses for both ID and access token.

@aeneasr aeneasr added this to the 1.0.0 milestone May 25, 2018
@aeneasr aeneasr self-assigned this May 25, 2018
@aeneasr
Copy link
Member Author

aeneasr commented Jul 8, 2018

Actually, the audience should probably be defined by the client making the request, not the consent endpoint.

@aeneasr aeneasr modified the milestones: v1.0.0, v1.0.0-beta.8 Jul 17, 2018
@aeneasr aeneasr modified the milestones: v1.0.0-beta.8, v1.0.0, v1.0.0-rc.1 Aug 10, 2018
@aeneasr aeneasr modified the milestones: v1.0.0-rc.1, v1.0.0, unplanned Aug 21, 2018
@bbulczynski
Copy link

How would you suggest to do that? Maybe using claims and setting value?

@aeneasr
Copy link
Member Author

aeneasr commented Sep 9, 2018

Not sure yet, needs investigation

@aeneasr
Copy link
Member Author

aeneasr commented Oct 29, 2018

So the proper course of action, to the best of my knowledge, is as follows:

  1. We're enabling clients to define audiences which they are allowed to request.
  2. We're defining one or more audience matching strategies (e.g. exact, wildcard, ...)
  3. We're checking every implicit, code, hybrid, cc flow for a request parameter called audience
  4. If audience is set (either in query or body), we will split that parameter using - well this one is tricky - some character. This could be whitespace or something else. The problem is we're dealing with URLs so all allowed characters could be the URL and it's not really easy to just pick one delimiter. I think to keep with previous practices of scope delimiters, we should go with whitespaces (or url encoded +)
  5. We check if each of the audiences is also an intended/allowed audience of the client using the matching strategy.
  6. We expose GetRequestedAudience() []string and GrantAudience(audience string) in the requester interface so that the consent endpoint can set/override this value.

@aeneasr
Copy link
Member Author

aeneasr commented Oct 29, 2018

Here's what I intend to add to the docs regarding this:

Audience

There are two types of audience concept in the context of OAuth 2.0 and OpenID Connect:

  1. OAuth 2.0: Access and Refresh Tokens are "internal-facing". The aud claim of an OAuth 2.0 Access and Refresh token
    defines at which endpoints the token can be used.
  2. OpenID Connect: The ID Token is "external-facing". The aud claim of an OpenID Connect ID Token defines which
    clients should accept it.

While modifying the audience of an ID Token is not desirable, specifying the audience of an OAuth 2.0 Access Token is.
ORY Hydra implements this feature, which is not defined as an IETF Standard but is
considered good practice in certain environments.

To use the audience feature, you must specify the intended audiences in the OAuth 2.0 Client's metadata on a per-client basis:

{
    "client_id": "...",
    "audience": ["https://api.my-cloud.com/user", "https://some-tenant.my-cloud.com/"]
}

The audience is a list of case-sensitive URLs. URLs must not contain whitespaces.

OAuth 2.0 Authorization Code, Implicit, Hybrid Flows

When performing an OAuth 2.0 authorize code, implicit, or hybrid flow, you can request audiences at the /oauth2/auth
endpoint https://my-hydra.com/oauth2/auth?client_id=...&scope=...&audience=https%3A%2F%2Fapi.my-cloud.com%2Fuser+https%3A%2F%2Fsome-tenant.my-cloud.com%2F
which requests audiences https://api.my-cloud.com/user and https://some-tenant.my-cloud.com/.

The audience query parameter may contain multiple strings separated by a url-encoded space (+ or %20). The
audience values themselves must also be url encoded. The values will be validated against the whitelisted
audiences defined in the OAuth 2.0 Client:

  • An OAuth 2.0 Client with the allowed audience https://api.my-cloud/user is allowed to request audience values https://api.my-cloud/user
    https://api.my-cloud/user/1234 but not https://api.my-cloud/not-user nor https://something-else/.

The requested audience from the query parameter is then part of the login and consent request payload as field requested_access_token_audience.
You can then alter the audience using grant_audience.access_token when accepting the consent request:

hydra.acceptConsentRequest(challenge, {
  // ORY Hydra checks if requested audiences are allowed by the client, so we can simply echo this.
  grant_audience: {
    access_token: response.requested_access_token_audience,
    // or, for example:
    // access_token: ["https://api.my-cloud/not-user"]
  },

  // ... remember: false
  // ...
})

When introspecting the OAuth 2.0 Access Token, the response payload will include the audience:

{
  "active": true,
  // ...
  "audience": ["https://api.my-cloud/user", "https://api.my-cloud/user/1234"]
}

OAuth 2.0 Client Credentials Grant

When performing the client credentials grant, the audience parameter from the POST body of the /oauth2/token is
decoded and validated according to the same rules of the previous section, except for the login and consent part which
does not exist for this flow.

@Aggouri
Copy link

Aggouri commented Oct 29, 2018

While modifying the audience of an ID Token is not desirable, specifying the audience of an OAuth 2.0 Access Token is.
ORY Hydra implements this feature, which is not defined as an IETF Standard but is
considered good practice in certain environments.

To use the audience feature, you must specify the intended audiences in the OAuth 2.0 Client's metadata on a per-client basis:

While I don't necessarily have the best writing skills, I think this would be slightly more clear:

While modifying the audience of an ID Token is not desirable, specifying the audience of an OAuth 2.0 Access Token is. This is not defined as an IETF Standard but is considered good practice in certain environments.

For this reason, Hydra allows you to control the aud claim of the access token. To do so, you must specify the intended audiences in the OAuth 2.0 Client's metadata on a per-client basis:

@bbulczynski
Copy link

  1. How do you plan to alter pairwise subject functionality to cooperate with that?
  2. Do you mind interchangeability of id_token between clients?
  3. How about client deciding about which of his auds should be visible to other? I think aud content should be decided per client by user on consent page.

@aeneasr
Copy link
Member Author

aeneasr commented Oct 29, 2018

How do you plan to alter pairwise subject functionality to cooperate with that?

Not related IMHO

Do you mind interchangeability of id_token between clients?

Not sure what you mean by that?

How about client deciding about which of his auds should be visible to other? I think aud content should be decided per client by user on consent page.

Depends on your understanding of audience. It can be user granted or defined per client. The audience is not officially specified nor is how you authorize audience.

@bbulczynski
Copy link

ok, i should have order 2. before 1. to make it clear, so let me explain that...

Do you think that id token could be shared between clients from aud list? Otherwise bother putting list of aud into token, ok client can check if that is intended for him, but why put there other aud values? I could imagine situation where third parties share id token, that is signed and can be verified, and pass information about user among themselves that way.

The open spec of aud explains rest.

Thank you.

@aeneasr aeneasr modified the milestones: unplanned, v1.0.0-rc.1 Oct 31, 2018
@aeneasr aeneasr changed the title consent: Add ability to specify ID Token and Access Token Audience consent: Add ability to specify Access Token Audience Oct 31, 2018
@aeneasr
Copy link
Member Author

aeneasr commented Oct 31, 2018

Do you think that id token could be shared between clients from aud list? Otherwise bother putting list of aud into token, ok client can check if that is intended for him, but why put there other aud values? I could imagine situation where third parties share id token, that is signed and can be verified, and pass information about user among themselves that way.

Personally, I think it could be shared. However, this will not be addressed as part of this PR. The access token audience is the real deal, requests/use cases for oidc audience have not come up yet.

@aeneasr
Copy link
Member Author

aeneasr commented Oct 31, 2018

Thank you @Aggouri for the correction, updated in the docs!

@bbulczynski
Copy link

OK, thanks for sharing.

aeneasr pushed a commit that referenced this issue Oct 31, 2018
This patch adds the ability to whitelist and request an audience
when performing any OAuth 2.0 Flow. The audience is useful in multi-
tenant environments where access tokens should be restricted to certain
resources.

Closes #883
Closes #1144

Signed-off-by: arekkas <aeneas@ory.am>
aeneasr pushed a commit that referenced this issue Oct 31, 2018
This patch adds the ability to whitelist and request an audience
when performing any OAuth 2.0 Flow. The audience is useful in multi-
tenant environments where access tokens should be restricted to certain
resources.

Closes #883
Closes #1144

Signed-off-by: arekkas <aeneas@ory.am>
aeneasr pushed a commit that referenced this issue Oct 31, 2018
This patch adds the ability to whitelist and request an audience
when performing any OAuth 2.0 Flow. The audience is useful in multi-
tenant environments where access tokens should be restricted to certain
resources.

Closes #883
Closes #1144

Signed-off-by: arekkas <aeneas@ory.am>
aeneasr pushed a commit that referenced this issue Oct 31, 2018
This patch adds the ability to whitelist and request an audience
when performing any OAuth 2.0 Flow. The audience is useful in multi-
tenant environments where access tokens should be restricted to certain
resources.

Closes #883
Closes #1144

Signed-off-by: arekkas <aeneas@ory.am>
aeneasr pushed a commit that referenced this issue Oct 31, 2018
This patch adds the ability to whitelist and request an audience
when performing any OAuth 2.0 Flow. The audience is useful in multi-
tenant environments where access tokens should be restricted to certain
resources.

Closes #883
Closes #1144

Signed-off-by: arekkas <aeneas@ory.am>
aeneasr pushed a commit that referenced this issue Oct 31, 2018
This patch adds the ability to whitelist and request an audience
when performing any OAuth 2.0 Flow. The audience is useful in multi-
tenant environments where access tokens should be restricted to certain
resources.

Closes #883
Closes #1144

Signed-off-by: arekkas <aeneas@ory.am>
aeneasr added a commit that referenced this issue Nov 1, 2018
This patch adds the ability to whitelist and request an audience
when performing any OAuth 2.0 Flow. The audience is useful in multi-
tenant environments where access tokens should be restricted to certain
resources.

Closes #883
Closes #1144

Signed-off-by: arekkas <aeneas@ory.am>
Signed-off-by: aeneasr <aeneas@ory.sh>
aeneasr added a commit that referenced this issue Nov 1, 2018
This patch adds the ability to whitelist and request an audience
when performing any OAuth 2.0 Flow. The audience is useful in multi-
tenant environments where access tokens should be restricted to certain
resources.

Closes #883
Closes #1144

Signed-off-by: arekkas <aeneas@ory.am>
Signed-off-by: aeneasr <aeneas@ory.sh>
aeneasr added a commit that referenced this issue Nov 2, 2018
This patch adds the ability to whitelist and request an audience
when performing any OAuth 2.0 Flow. The audience is useful in multi-
tenant environments where access tokens should be restricted to certain
resources.

Closes #883
Closes #1144

Signed-off-by: arekkas <aeneas@ory.am>
@ErwinSteffens
Copy link

@aeneasr

We're defining one or more audience matching strategies (e.g. exact, wildcard, ...)

Was the wildcard part also implemented? Not finding anything in the documentation about this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants