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

Custom scopes in access token programmatically #684

Open
rscmendes opened this issue Feb 2, 2019 · 97 comments
Open

Custom scopes in access token programmatically #684

rscmendes opened this issue Feb 2, 2019 · 97 comments
Labels
cognito Issues with the AWS Android SDK for Cognito feature-request Request a new feature

Comments

@rscmendes
Copy link

Describe the bug
Impossible to get access tokens with custom scopes without using the hosted web ui. Authentication through the amplify drop-in UI for both Android and iOS -- used in the android-sdk-auth example -- or through cognito auth sdk always returns (the single scope) aws.cognito.signin.user.admin even if it is disabled on the app client settings.

To Reproduce
Steps to reproduce the behavior:
1.Follow the android (or iOS)-sdk-auth example;
2. Create custom scope and enable on app client settings;
3. Sign-in in the app, grab the access token and check the scopes in jwt.io

Which AWS service(s) are affected?
AWS Cognito (in all SDKs) and AWS API Gateway

Expected behavior
Access token should return custom scope(s), regardless of using the web ui.

Screenshots
scopes

Environment(please complete the following information):

  • Latest SDK versions (of both cognitoauth, mobileclient and auth-ui)

Device Information (please complete the following information):

  • We tested on both iOS and Android default simulators, although we believe that this happens with any device.
  • iOS 11.3 and Android API level 28.

Additional context
Our use case:
We have native apps (both Android and iOS) trying to authenticate end-users in a user pool. Our API Gateway resources are scoped (none including aws.cognito.signin.user.admin scope). We want to use implicit grant as we don't want to distribute the application with the client secret in its package as that would be stored in plain text. We'd rather not use the hosted web ui for improved user experience, specially since everything we have is native. We do understand the implications of not using the web ui, as well as not using the authorization code flow. Thus, the solution would be to use the cognito auth sdk, which we believe that it doesn't support implicit grant.

We might be approaching this the wrong way, any guidance would also be highly appreciated.

Unsolved related issues throughout the different SDKs:

[Amplify JS] - Access Token does not have required scopes (Http - 400)

[Amplify JS] - How do I use amazon-cognito-identity-js to get scopes in the access_token?

[Amplify iOS] - Feature Request: Cognito "InitiaateAuth" request allowed custom "scopes" in AccessToken

[Amplify Android] - Feature Request: Cognito "InitiateAuth" request allowed custom "scopes" in AccessToken

@sunchunqiang sunchunqiang added the cognito Issues with the AWS Android SDK for Cognito label Feb 4, 2019
@sunchunqiang sunchunqiang assigned minbi and rohandubal and unassigned minbi Feb 4, 2019
@rohandubal
Copy link
Contributor

Hello @bluetrickpt

Currently, specifying custom scopes is only supported via the Oauth client (Cognito Auth SDK) as you have mentioned above. It is not possible to to request custom scopes using the API flow.

I will take this as a feature request to the service team.

Thanks,
Rohan

@rohandubal rohandubal added feature-request Request a new feature and removed investigating labels Feb 6, 2019
@fcouceiro
Copy link

Any updates on this?

@spectorar
Copy link

spectorar commented Feb 13, 2019

Agree that this would be a really useful feature. My team has a use case that requires us to implement a custom auth flow and without being able to have scopes (both built in and custom) in the token we may have to look up the scopes on the app client's resource server at each authorization with a custom auth trigger to verify that the app client has access. Even with that implementation, we can't issues tokens that have are limited to a subset of the allowed scopes.

@minbi
Copy link
Contributor

minbi commented Feb 13, 2019

Hi all,

We don't have an update on this issue, but we are communicating your requests to the service team.

@uherberg
Copy link

This would be very helpful. Is there any plan to address this soon?

@JaysonSunshine
Copy link

Hey, Amplify

We too have run into this issue. It's very useful to have custom scopes so that we can have fine-grained Cognito authorizers on our API Gateway resource. Any update would be great. :)

-Jay

@qwertynature
Copy link

Any update on this?

@cristian-stoichin
Copy link

Anything?

@hasbisevinc
Copy link

Any update?

@uokitomer
Copy link

Any updates?

@karlkilgi
Copy link

Any updates on this? @minbi @rohandubal

@juanto121
Copy link

Updates would be much appreciated.

@ebaychannel
Copy link

Any updates?

@gauravchaddha
Copy link

Any Update?

@pcashdown-tu
Copy link

Any update on this?

@pmargom
Copy link

pmargom commented Nov 27, 2019

Please, give any update about this feature.

@rupertlssmith
Copy link

Also looking for an update on this.

@cristian-stoichin
Copy link

Come on AWS, at least throw us a bone here...

@sandeepsdixit
Copy link

Need this badly

@jacogreyling
Copy link

Ditto. Any update will be greatly appreciated. Alternatively if we need to 'vote' for this feature please let us know so we can raise awareness through the product owner's radar.

@sandeepsdixit
Copy link

For now I am adding aws.cognito.signin.user.admin to custom authorizer / oauth scopes. Not a great choice but has allowed me to move forward while still using access tokens...

@ittijindaniSN
Copy link

Looking from someone in the Cognito team to provide an update. The request for custom scope has been pending for almost an year.

@kkdeveloper7
Copy link

kkdeveloper7 commented Nov 29, 2021

You know what's sad. I didn't do enough research, I don't even know what to research before I started coding. I've already wasted so much time just to run into this roadblock.

Now I'm just facing sunk cost fallacy.

Know what's even sadder? I worked at Auth0 and decided to go with Cognito for my startup because of its supposed frictionless development with AppSync.

There is a work around you can use in order to get this working. You will have to call same api they call from hosted UI and pass their Token that is set to your browser in the cookies I believe (Sorry I dont remember the name of the cookies, it is on my work computer, but it starts with X I believe). With this youll be able to sent your scopes in the url of the request.

@shawnmclean
Copy link

shawnmclean commented Nov 29, 2021

Thanks, I have both the id_token and the access_token. So the workaround for me right now is to send the id_token instead since that contains the claims.

However:

id_tokens are meant for the client and access_token for the API. See https://auth0.com/blog/id-token-access-token-what-is-the-difference/

I somehow need to override the default access_token with my claims from the source. Worst case I'm going to have to implement a lambda auth and use that to pull in my id_token with the claims (which is storing authz info such as tenant and role).

So while it's not an amplify issue but a cognito issue, the amplify team is taking the heat for this because it's mostly what we're interacting with, by the same company.

@kkdeveloper7
Copy link

kkdeveloper7 commented Nov 29, 2021

Thanks, I have both the id_token and the access_token. So the workaround for me right now is to send the id_token instead since that contains the claims.

However:

id_tokens are meant for the client and access_token for the API. See https://auth0.com/blog/id-token-access-token-what-is-the-difference/

I somehow need to override the default access_token with my claims from the source. So while it's not an amplify issue but a cognito issue, the amplify team is taking the heat for this because its mostly what we're interacting with, by the same company.

You should not use id token in place of access token, it is bad for security. Also, id token will have missing claims. I believe it won't have username claim as well as scopes I believe

@tobilg
Copy link

tobilg commented Nov 29, 2021

@kkdeveloper7 you can add claims via the PreToken trigger for id tokens. I outlined a solution/workaround in this issue

Can you elaborate regarding using of id tokens is bad from a security perspective?

@kkdeveloper7
Copy link

kkdeveloper7 commented Nov 29, 2021

@kkdeveloper7 you can add claims via the PreToken trigger for id tokens. I outlined a solution/workaround in this issue

Can you elaborate regarding using of id tokens is bad from a security perspective?

Generally speaking you can even sent a refresh token in a header that you can later take retrieve access token from and access your protected resource, but it is not recommended to do so because of the security concerns that if someone get a hold of your long living refresh token and will be able to issue them new access tokens.

Id token was created to be able to quickly gain current user information. This token dose not have to be secure and can be accessed via client to parse its contents in order to get users information. If you will store secure information in your Id token this mean that the client can access it and read secure claims that mean to be for access token only, such as scope claim (just an example there could be other scopes that you might use).

The point I am trying to make is that, yes passing id token is not as bad as passing refresh token, but it is not recommended since the use for this token is mean for other purposes. Its like trying to eat soup with tea spoon, yes you can get it done but there are better tools for that.

There are also scopes that you cant add or modify in lambda one of the is cognito:username. I think cognito:username is used in id token and username is used in access token. There are probably more, sorry I dont remember from top of my head but I ran into same issue and was cough of guard with certain limitations.

@andreashe
Copy link

After 3 days trying to find out why my Amplify token does not work with my proxy API, I figured out the scope issue and landed here.

Quite frustrated as I don't want to use hostet UI, I don't know how to continue. Shame on AWS.

@AlexMayleRdn
Copy link

AlexMayleRdn commented Dec 9, 2021 via email

@jsmpereira
Copy link

Found this: https://aws.amazon.com/blogs/security/use-amazon-cognito-to-add-claims-to-an-identity-token-for-fine-grained-authorization/ Is pretty new.

That is an article about adding claims to the id_token. That functionality has been available for quite some time. The missing functionality, and the context of this issue, is adding claims to the access_token. :)

@michaelakin
Copy link

+1 I am having this issue. How is Amazon using this to identify users? Are they using an access token or the id token?

@matthew-mcdermott
Copy link

I run into this issue even using the hosted ui. I have no way around it that I know of. :/

@marcjulianfleck
Copy link

Why is there still no news on this? It's incredibly frustrating to see people including me paying money for Cognito and Amplify, yet this critical issue, which affects all Amplify SDKs, continues to be overlooked!

@abdallahshaban557
Copy link

Hello everyone, this is currently a limitation from the Amazon Cognito service, and we are working closely with them to resolve this. We will provide updates on this issue when we have more to share.

@hackmajoris
Copy link

Looking forward for a resolution for this issue.

@abdallahshaban557
Copy link

Since we are working with the Cognito team to identity the use cases for how developers would use this, can you please help us with providing us how you would set and also request these custom scopes? We want to make sure the mechanism we expose this in makes sense.

@hackmajoris
Copy link

hackmajoris commented Sep 1, 2023

Here is my use-case:

I have two Angular web apps integrated with Module Federation.
In the main application, I handle authentication using Amplify/Cognito APIs.
The second app is configured to use OpenID with Cognito.
Now, what I want to do is to reuse the token generated from sign-in calls in the main app to make API calls from the second app (Module Federated). When the native Amplify Auth is used, the generated token lacks the 'scope: openId,' and as a result, it can't be used to make requests to the second app. The solution is to eliminate the native Amplify Auth component and use Cognito APIs with OpenID (which forces the use of the native and somewhat unattractive Cognito authentication page - Hosted UI) to obtain a scoped token.

From my investigation, from the Cognito side, you can't have a programmatically generated scoped token, besides then going throw SSO Cognito(Hosted UI) login page.

Let me know if you need more details.

As on how to query those scopes: I think it's not necessary to query them because they should be returned by default if the SSO is configured, and they are returned but only throw Hosted UI:

This is the override of Amplify Auth, configured with SSO.
image

When going to the Hosted UI login - the scoped token is returned. When calling directly the APIs for that native Auth component, they are not.

@jsmpereira
Copy link

Since we are working with the Cognito team to identity the use cases for how developers would use this, can you please help us with providing us how you would set and also request these custom scopes? We want to make sure the mechanism we expose this in makes sense.

Setting and requesting custom scopes is not the issue. This is possible with the current functionality:

What is missing and would add immense value and flexibility is allowing developers to take control over the structure of the access_token. I make the case in #684 (comment) (June 2020):

It makes sense that there is a trigger to modify the id_token, given the support for custom/additional claims (https://openid.net/specs/openid-connect-core-1_0.html#AdditionalClaims).
However it makes even more sense to have one for the access_token since id_token is arguably more strict in it's structure (there's a spec for it: https://openid.net/specs/openid-connect-core-1_0.html#IDToken) while an OAuth2 access_token has no specific format or structure as per the OAuth2 spec (https://tools.ietf.org/html/rfc6749#section-1.4, https://tools.ietf.org/html/rfc6750) effectively making it application specific.

In terms of supporting this, it would make sense to keep consistency with current Cognito functionality and simply provide a pre (or post) (access) token generation trigger similar to the one available for the id token (https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-token-generation.html).

Note that there are a significant number of claims in theid_token that can't be modified in the existing trigger. I would advise that when the Cognito team considers adding the new trigger 🙏 that the constraints on the modification of the claims in the access_token be carefully thought out and likely very loose. As I refer to above, the id_token has a spec, the access_token doesn't.

See also #684 (comment) for some context about our use case and the workaround I've implemented to have full control over the structure of the access_token.

I, of course, don't have the context the Cognito team possesses regarding the architecture, design and implementation of the Cognito service, however, I might be so bold to argue that the uses cases are of less importance and not really relevant in the consideration of what should be a core functionality: allowing developers to have full control over the access_token that is used to access their APIs.

🙇

@abdallahshaban557
Copy link

Thank you @hackmajoris and @jsmpereira so much for the feedback! Exactly the type of insight we needed! We will get back to you when we make more progress with the help of the Cognito team!

@AlexMayleRdn
Copy link

@jsmpereira Perhaps I'm misunderstanding the guides, but the custom scopes seemed to be mapped to app clients only? This is fine for app clients but what about users in the pool? It would be nice to a have custom logic when it comes to issuing scopes regardless of the client type.

@jsmpereira
Copy link

jsmpereira commented Sep 4, 2023

@AlexMayleRdn From the OP (#684 (comment)):

Describe the bug
Impossible to get access tokens with custom scopes without using the hosted web ui. Authentication through the amplify drop-in UI for both Android and iOS -- used in the android-sdk-auth example -- or through cognito auth sdk always returns (the single scope) aws.cognito.signin.user.admin even if it is disabled on the app client settings.
...
Expected behavior
Access token should return custom scope(s), regardless of using the web ui.

The issue initially described seems to be a "limitation" with amplify and related SDKs, where unless you used the hosted ui, any custom scopes would not be present in the access token. At this point, 4 years passed I honestly don't know if that issue is addressed. It sparked however a more "generic" discussion about access token customisation.

Custom scopes are defined on a Resource Server (https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-define-resource-servers.html). These scopes can then be enabled in app clients. When executing OAuth grants "in the context" of a user pool app client (https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-client-apps.html) you get an access_token which includes the requested scopes, if enabled.

An app client is not a client type and it "links" your application to a pool of users.
An app client can have different types: "Public client", "Confidential client" or "Other".

If you want to leverage Cognito to authorize your own API you can do so with Resource Servers and custom scopes, then you can enable the desired custom scopes on your app client. If you have no users to authenticate, you can execute a client_credentials grant (specifying the app client credentials) and get an access_token with the enabled (custom) scopes. if you have users to authenticate you can execute an authorization code grant (also specifying app client credentials) and get an id_token with OIDC claims (and some cognito specific claims) and an access_token with the enabled (custom) scopes in the scope claim.

@tobilg
Copy link

tobilg commented Sep 5, 2023

I don’t think it currently works as you described @jsmpereira. In my tests the custom scopes are only present in the Access Token if you use the Hosted UI

@jsmpereira
Copy link

@tobilg 🙇 That is indeed the issue initially described, as I do mention in #684 (comment):

The issue initially described seems to be a "limitation" with amplify and related SDKs, where unless you used the hosted ui, any custom scopes would not be present in the access token. At this point, 4 years passed I honestly don't know if that issue is addressed. It sparked however a more "generic" discussion about access token customisation.

This however seems to be by design. From the Cognito access token page (https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-the-access-token.html):

scope
A list of OAuth 2.0 scopes that define what access the token provides. A token from the Token endpoint can contain any scopes that your app client supports. A token from Amazon Cognito API sign-in only contains the scope aws.cognito.signin.user.admin.

It does seem that something like Amplify's Auth.signIn (aws-amplify/amplify-js#1370 (comment)) doesn't trigger an OAuth flow and hence won't be in context of resource servers and custom scopes. It could be nice if the Cognito team could share the rationale for this design decision. Maybe the Cognito API sign-in is only intended to provide an access_token to access Cognito APIs, like updating user information 🤷.

I also mention in a previous comment #684 (comment):

It seems the use cases presented are mostly in the context of users and the hosted UI.

I believe however that the underlying issue is more general and not exclusive to the context of amplify. It boils down to allowing the access_token to be modified, for example via a trigger (see related issue aws-amplify/amplify-js#4015).

Providing something like a pre-token-generation trigger (used to modify the id_token) for the access_token would address any issues related to what is/should/shouldn't be in the access_token. How the authentication is being done (hosted UI or API) should be irrelevant. What the developer decides to put on the access_token is application specific and should just be there.

I make the case on that comment that having a trigger for the access_token (like the one that exists for the id_token) is (arguably) core functionality that seems to arbitrarily be absent, that would address the reported issue while giving developers optimal flexibility and control over the access_token used to authorize their APIs. But again, as I mention above, maybe the access tokens issued by cognito are not all intended to authorize our APIs 😅

Sorry about the ramblings. I'm all over the place 🙇

@tobilg
Copy link

tobilg commented Sep 5, 2023

I‘m aware of all these things. They have been mentioned years ago in other issues. Current discussion seems to revolve around aws-amplify/amplify-js#3732 (comment)

@DavidWells
Copy link

CHRISTMAS CAME EARLY FRIENDS

https://aws.amazon.com/about-aws/whats-new/2023/12/amazon-cognito-user-pools-customize-access-tokens/

@rupertlssmith
Copy link

@michaelakin
Copy link

Does this mean that api gateway will use access tokens instead of id tokens now?

@DavidWells
Copy link

#684 (comment)

Well... not exactly. You must turn on advanced security features to use this. This bumps per user price up 800%....

Surely we can get this without needing to opt into every other feature.

image

@josephharkins
Copy link

It looks like they have gotten their act together and sorted this, new better pricing tiers, access tokens incl.

https://aws.amazon.com/cognito/pricing/

@github-actions github-actions bot added the pending-maintainer-response Issue is pending response from an Amplify team member label Dec 14, 2024
@tylerjroach tylerjroach removed the pending-maintainer-response Issue is pending response from an Amplify team member label Dec 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cognito Issues with the AWS Android SDK for Cognito feature-request Request a new feature
Projects
None yet
Development

Successfully merging a pull request may close this issue.