How to allow users to consume GCP API Gateway programmatically? - google-cloud-platform

I have a simple bussiness case, not real one, but common:
We have an API to sell, maybe weather API.
Users stored and managed with some identity provider.
Users can generate JWT token to use for machine-to-machine communication. For example using client_id and client_secret.
Now what GCP offers for this scenario:
API Gateway is the way to go, it has JWT auth available.
Firebase or Identity platform are good options to store and manage users.
Logged in users has JWT which can be used with API Gateway, but we need machine-to-machine flow to obtain the token. And both Firebase or Identity platform can't be used for this.
I am curious if this is a correct way to approach this case, because the only way to solve it is to use some third party identity provider like Auth0, or make inhouse solution to generate machine-to-machine JWT. I just can't believe GCP has nothing to offer for such common use case.

Related

Google Identity Platform OAuth server

I want to user Google Identity Platform as the CIAM solution for our GKE-based cloud service. We have a requirement to allow 3rd parties to access our cloud APIs using credentials they obtain via OAuth.
For example, our cloud service provides APIs that Google Assistant or Amazon Alexa can access on behalf of our users. Therefore, we want to provide an OAuth-based token manager that uses the identities of our customers as defined in the Google Identity Platform.
Is this type of OAuth service possible using Google Identity Platform, or the underlying Firebase service that drives it?
Based on the documentation for Google Assistant, you will need to implement your own OAuth2 endpoints. In the authorization code flow, you need two endpoints:
The authentication endpoint needs to sign in the user and get their permission to allow the third party (eg. Google) to call the customer's API on their behalf. If the user gives permission then they return an authorization code - which could be implemented by creating a custom token with Cloud Identity Platform.
Token exchange endpoint is also needed, which has two functions. The first is to exchange the authorization code created by the first endpoint for a refresh token and an ID token. The second is to exchange a refresh token for a new ID token. Both of these functions can be delegated to Cloud Identity Platform.
Additional note:
I would suggest to use custom claims to ensure that these tokens can only be used for the intended purposes, ie. to perform actions which the Google Assistant needs to do. Users shouldn't be allowed to perform other actions, eg. changing the user's password or providing authorization codes to other third parties.
Also make sure that this endpoint can't be used by malicious third parties. For example, you can check that the redirect URL provided matches what is expected, since this is where the authorization code will be sent to.

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 ...

Authorization in Google Cloud Endpoints for external clients

We are developing an API which is intended to be used by our external clients which are not inside Google Cloud.
It seems that Google Cloud Endpoints is a good candidate for such case.
What we need:
Client to be able to register in our "developer portal" to obtain necessary credentials.
To keep track of our clients (to see the number of requests of a particular client, to revoke his access to API, etc.)
The part which is not very clear to me is how to authenticate and identify our clients if they are not in Google Cloud.
We already use Firebase authentication by user email in one part or our application. It would be handy to continue using that authentication, but I am not quite understand how.
Google docs say that client application must send a JWT token. But what private key does it have to use to sign the JWT?
The second option to authenticate client we are thinking of is to use custom method to authenticate users. But I have the same question: What private key does the client application have to use to sign the JWT?
Is it intended that client generates its' own key pair?
If there are some better options for our use-case or if I am missing something, feel free to point me in the right direction.
You are on the right way!
With firebase, the JS library allow you to authenticate to the correct identity provider and the lib also allows you to generate a JWT. No private key needed here!
With custom method, it's different. Cloud Endpoint need to validate the signature of the JWT. For this, Cloud Endpoint need to know the public key of the private key used to sign the JWT. Most of time, it's provided by your own IdP system.
In your context, Firebase auth (or Cloud Identity Platform, if you want to manage your users on Google Cloud) is the best solution for you. With several customers, you can't register all their public keys, the only one solution is to have your own IdP and all your customer registered on it.
I have additional question: How do you plan to count the number of request per client? Through Cloud Endpoint or you own database?
We came up with a solution using custom method to authenticate users:
We implemented user authentication by email using firebase (as stated in my question).
Added a way for users to upload their public certificate to our "portal".
2.1. This was done using Google Cloud functions. Basically, we created a two endpoints:
2.1.1. to upload public certificate using firebase token.
2.1.2. to display all public certificates in JWKS format by some url (this way google is able to verify users JWT signature)
Published an instruction for users on how to form JWT to use our API (at this point every user have to have private key associated with their public key uploaded earlier).
Now users of our API are able to make API calls with JWT token provided.
Our technologies stack looks like following:
Cloud functions (for certificate handling).
Firestore (for authentication, storing certificates etc.).
Cloud Endpoints with ESPv2
Google App Engine standard environment

OpenID authentication in AWS API gateway

I created an API with AWS API gateway that triggers a lambda function. Now I want to restrict access to this API. I own an OpenID connect identity provider.
I want to require people to authenticate with my OpenID identity provider before accessing the API. What is the best way to do that? Apparently, I need an authorizer for my API. I read a lot of documentation, and from what is mentioned here, it seems that this would be possible with amazon cognito. However, here I can only find a way to use cognito user pools, while I want to use a cognito identity pool.
I want the typical authentication scenario, e.g. user calls the api, is redirected to my openid id provider, logs in, and can then access my api (which delivers html so all of this will be taking place in a web browser).
Is this actually possible with cognito, or do I need to write a custom lambda authorizer? If so, is there any documentation on writing an authorizer lambda that uses openid, prefereably in .NET?
You are mixing Authentication and Authorization.
Federated Identity Provider to Cognito:
You can use OpenID Federated Identity provider for Authentication.
Below documentation provides on how to configure it,
https://docs.aws.amazon.com/cognito/latest/developerguide/authentication-flow.html
Once authenticated you can create a signed URL to protect your assets for the URL which you want to allow to.
Creating Signed URLs:
Below documentation providers on how to created signed URL's using C#.
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CreateSignatureInCSharp.html
Custom Authorizer:
Following commit on github shows an example implementation of C# custom authorizer.
https://github.com/awslabs/aws-apigateway-lambda-authorizer-blueprints/pull/13/commits/79d75fb7c5ee4f29fa06fd2ec28c704224cf8a7a
Hope it helps.

Using AWS Cognito under the backend API

I wanted to check we can use a custom node.js implementation as wrapper for exposing the API's for identity and user management using aws cognito.
We already have a bunch of API's (on ASP.NET identity) and would not want to change anything in the downstream systems. We would like keep the API signatures and just move the implementation to node.js server for identity and user management
The current examples on awslabs and the documentation is mainly targeted for using this under a web/mobile applications. Is there any guideline/sample if we can use this as an API wrapper.
Apologies if I'm misinterpreting the question, but are you just trying to use Cognito with node instead of on a web app? Are you asking about Cognito federated identities or Cognito user pools?
If federated identities, yes, that will be fine and you shouldn't have any issues. All of the APIs are available in the node SDK, and the general flow should be identical to any other non mobile flow.
If you're asking about user pools, it's a bit trickier. Authentication uses SRP to validate passwords, and the mobile/web SDKs do this for you. Outside of those, you'd have to implement it yourself, which is no fun at all. You could rip out the code that does it from any one of those SDKs (each are published on Github) to help with that. Alternatively, you could use admin no srp authentication, which carries the risk of sending the username/password over the wire but passes off the authentication to the Cognito server.