AWS cognito machine-to-machine oauth - amazon-web-services

I have an API which large number of devices connect to. These devices are distributed by us and can be considered as trusted. They do not have a built-in Web browser.
I'm considering to use OAuth Client Credentials flow (flow for machine-to-machine communication). However, I wonder if Cognito Client Credentials flow is not designed for this purpose as it allows only 25 App Clients.
Is there another OAuth flow (within Cognito) that can be used in this case?
I suppose Resource Owner Password Grant can be used here but can't figure out how to enable it in Cognito.

Related

Is there any OpenID Connect Identity Provider that can delegate autentication to other OpenID Connect IdPs?

I'm facing the following scenario:
There are several companies each one with its own OpenID Connect Identity Provider (IdP) which federates users from their respetive LDAP servers. These providers are used to perform SSO in the context of each company.
There's a requirement to create an application that offers a common login for all the users of those companies.
The idea is to provision or use an existing cloud solution (AWS Cognito, Google Cloud Identity, etc., ...) that offers a shared login screen but delegates/federates the actual login to each of the company IdPs.
Are there any solutions that allows this?
Could you point at any documentation/guide to implement it?
This is just standard OAuth and OpenID Connect behaviour, with these 3 roles:
Application, uses OIDC to redirect to ...
An Authorization Server, which you own, and which redirects to ...
An Identity Provider
So you need a standards based authorization server and to configure your app as an OAuth Client. Then include the openid scope so that OpenID Connect is used. SAML based identity providers can also be supported in this flow, even though your app only uses OIDC.
The way to manage this with best usability, is for the authorization server to present a usernane authenticator, which captures a user identifier first, such as an email. It then runs some custom logic, such as a user lookup, to determine which IDP to route the user to. The user then authenticates at the IDP.
After authentication, the IDP issues tokens to the authorization server, which validates them, then issues its own tokens to the application. In particular the app gets an access token whose scopes and claims you can control. Your app can then send these to your APIs, which can authorize access to business data correctly.
Aim for behaviour similar to that above, or adjust it based on your preferences. Then trial it, eg with a cloud or Docker based authorization server, and ensure that you select one with sufficient extensibility to meet your requirements.
Note also that Stack Overflow answers should not recommend particular vendors, so I have not done so.
There is a solution called cloudpods using which you can manage both on-prem and public cloud resources. Cloudpods supports integration with multiple cloud providers like aws, GCP, azure, alibaba and etc.,
Is there any OpenID Connect Identity Provider that can delegate autentication to other OpenID Connect IdPs?
Yes. https://github.com/apereo/cas is one. You can set it up as an OIDC identity provider and have it then delegate to as many OIDC Identity providers as you want.

Does Google Cloud API support MFA/2VS authentication?

I wanted to know if GCP supports multi-factor authentication (MFA) or 2-Step Verification (2SV) for cloud API calls.
From this link: https://cloud.google.com/docs/authentication, I read the following:
"Google Cloud APIs only accept requests from registered applications, which are uniquely identifiable applications that present a credential at the time of the request. Requests from anonymous applications are rejected.
Application credentials provide the required information about the caller making a request to a Google Cloud API. Valid credential types include API keys, OAuth 2.0 client credentials, or service account keys."
However, it does not specify if I can use these factors simultaneously.
Thanks in advance,
Vijay

How can I make AWS work as IdP for OIDC or SAML provider?

I am planning to use IAM and cognito identity pool as OIDC or SAML provider.
My goal is to use AWS as the provider without any third party integration.
I looked at IAM Identity Provider and have read through a doc https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html but it seems I need to provide Metadata document for SAML or Provider URL and audience for OIDC from third party providers.
Is there a way to use AWS as the provider? I don't want to use any other providers.
If this is your high level goal:
Modern and standard security for UIs and APIs via OAuth 2.0 and Open ID Connect
Then a Cognito user pool is probably what you are looking for. This will provide standards based endpoints, so that you can code your UIs and APIs in the preferred way.
If I remember rightly, an Identity Pool is a non standard solution for getting AWS specific tokens used to access user specific AWS resources. You should be able to use that when required by getting the User Pool to talk to the Identity Pool.
NOTES
From an application viewpoint the first step is usually always to locate the Open ID Connect metadata endpoint - a lot of security libraries in UIs and APIs will use that.
My Metadata Endpoint
Cognito OpenID Connect Setup
Cognito Federated Logins
Cognito is not the most mature of systems and has some annoyances and limitations. So it is worth keeping your solution based on OAuth 2.0 and Open ID Connect so that you have the best longer term options - and can switch providers if ever needed ...

What the settings mean in AWS Cognito User Pool App Client

I searched all over, tutorials, web, everybody jumps away without explaining(I understand why) the checkboxes in app client settings:
Enable sign-in API for server-based authentication
Only allow Custom Authentication
Enable username-password (non-SRP) flow for app-based authentication
The learn more link does not help me, lots of information and not so easy to understand, grasp. Can someone explain this settings?
Here is my take on the matter.
App client has several Auth Flow Configurations.
1. Enable username password auth for admin APIs for authentication (ALLOW_ADMIN_USER_PASSWORD_AUTH)
This enables Server-Side Authentication Flow. If you don't have an end-user app, but instead you're using a secure back end or server-side app.
2. Enable lambda trigger-based custom authentication (ALLOW_CUSTOM_AUTH)
This enables the Custom Authentication Flow. This can help you create a challenge/response-based authentication model using AWS Lambda triggers.
https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-challenge.html
Under User Pools -> Triggers you can see many lambda functions. You can use Create Auth Challenge, Define Auth Challenge and Verify Auth Challenge Response functions to create a custom authentication flow.
3. Enable username password based authentication (ALLOW_USER_PASSWORD_AUTH)
This enables Client Side Authentication Flow that uses user password-based authentication. In this flow, Cognito receives the password in the request.
You can use AWS Mobile SDK for Android, AWS Mobile SDK for iOS, or AWS SDK for JavaScript to implement this.
4. Enable SRP (secure remote password) protocol based authentication (ALLOW_USER_SRP_AUTH)
This is similar to the above flow in section 3. except for the password verification. This flow uses the SRP protocol to verify passwords.
http://srp.stanford.edu/whatisit.html
https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UserPoolClientType.html
5. Enable refresh token based authentication (ALLOW_REFRESH_TOKEN_AUTH)
After successful authentication, Amazon Cognito returns user pool tokens(Three tokens) to your app. You can use the tokens to grant your users access to your own server-side resources, or to the Amazon API Gateway. Or, you can exchange them for temporary AWS credentials to access other AWS services.
The three tokens are ID Token(JWT), Access Token, Refresh Token. The refresh token can be used to retrieve new ID and access tokens. Once you login to a mobile app, you are not needed to log in each time when you close and open the application and this functionality is implemented using refresh tokens.
https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html
What about Amazon Cognito hosted UI ?
App clients can be configured to use built-in Cognito webpages for signing up and signing in users. When using the hosted UI you can enable both the Authorization code grant and the Implicit code grant, and then use each grant as needed.
https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-app-idp-settings.html
Here is my attempt at explaining these options. Before that I would like to briefly mention about Oauth2, which is the protocol on which AWS Cognito is based.
In the context of AWS Cognito, Cognito itself is the Authentication (OAuth) server and also the Resource server (because we create users in Cognito user pool) and your app would be the Client (which sends the authentication request). The client has to first register itself with the OAuth server - this is what is being done in the "App clients" section of Cognito.
The recommended OAuth2 flow is Authorization Code Grant flow. In this flow,
i) The Client sends username/password to the OAuth Server.
ii) The OAuth server validates and calls back the client with a
authorization code.
iii) The Client again sends this code back to the OAuth server
iv) The OAuth server sends the tokens to the Client.
Please read the above linked article for more explanation on OAuth2.
Now explaining the options in Cognito App Client settings:
1. Enable sign-in API for server-based authentication
With this option, your client app can directly receive the tokens without having the additional step of first getting the authorization code.
There are Cognito APIs like AdminInitiateAuth, Admin-* which does this. However, these APIs require AWS admin credentials. Hence usually these calls are done by the backend server of the client app. The front-end can pass the username/password to the backend and the backend server can communicate with AWS Cognito and authorize the user.
2. Only allow Custom Authentication
Here you don't use the OAuth provided authorization code grant flow. Instead, you can define your own steps and challenges. Your client app can ask a secret question etc, before authenticating and giving tokens.
3. Enable username-password (non-SRP) flow for app-based authentication
This is the least safe flow. This skips the part of returning the authorization code and directly returns the tokens back to the client.
I hope this explains.

Amazon Cognito: How to pass credentials to server-side application

I have a client side application (developed in Java, not Android) that authenticate a user with an Amazon Cognito User Pool. To make things clear: that application display a username/password entry dialog, then authenticate with the Cognito user pool service using the SRP method; potential challenges are handled in that dialog (device id, password must be changed, two factors, etc). In the end, I have a series of tokens that allow the program to use AWS services with the user's credentials.
Now, I need the client application to communicate with a custom server side application. The client will have to prove its identity to the server application, which will then communicate with more AWS services. Here, I have two distinct use case:
1) The server only needs to know who the client-authenticated user is (in a safe manners, but without impersonating the user).
2) The client needs to delegate some or all of privileges of the user to the server; the server will then perform some actions on AWS services under that users behalf.
The server side application will most likely be developed in Java, running on an EC2 machine. I'm only interested in user authentification through the Cognito user pool source (that is, I have no interest in Facebook/Google/OpenID-based authentication flows).
It seems rather easy to achieve both objectives in very unsafe manners: just have the client application send to the server all the tokens it has been granted. But this is obviously not the way to go.
Yet, I'm having a hard time figuring out from Cognito User Pool/Cognito Identity Pool/IAM/STS documentation how this can be correctly achieved. I would expect for example the possibility for the client application to be able to generate some kind of "delegation token", which can be passed to the server; the server should then be able to validate that token and extract identity information from it (satisfying #1), or to impersonate the identity corresponding to the token in order to perform calls to AWS services (satisfying #2). Or maybe I'm thinking this incorrectly?
What you are pointing at is OAuth 2.0 code grant flow which is not currently supported by Amazon Cognito.
The current available safe way to do this is to pass the id token from the client to the server and then validate that token and extract identity information from it. This proves the identity of the caller as you can validate the signature of the id token.