API Gateway Security

I'm using API Gateway to expose a Cloud Run instance to the internet.

The gateway is configured to use `oauth2` authentication, i.e. only clients with valid credentials from a service account JSON key file are able to authenticate and therefore access the backend functionality. The users of the API are creating their own self-signed JWT access tokens based on details from the JSON key file.

1. Is there some way for a user of the API to get an access token that doesn't involved having to craft one themselves?

The service was penetration tested and one of the findings was that TLS 1.0 and 1.1 are both offered.
2. Is it possible to disable TLS 1.0 and 1.1 while leaving TLS 1.2 and 1.3 enabled?

0 3 702
3 REPLIES 3

The users of the API are creating their own self-signed JWT access tokens based on details from the JSON key file.

1. Is there some way for a user of the API to get an access token that doesn't involved having to craft one themselves?

I think I understand what you're talking about. To get an access_token, systems create a self-signed JWT, and POST it to the /token endpoint ( https://www.googleapis.com/oauth2/v4/token ), and obtain an access_token in response.

The requirement is

  1. create a JWT with a few requirements.
    • issuer = the email of the service account
    • audience = https://www.googleapis.com/oauth2/v4/token
    • scope = the desired scope of the issued token
    • expiry = no more than 300s after "now"
    • signed with the private key of the service account
  2. POST the JWT to the /token endpoint, as application/x-www-form-urlencoded, with two form parameters:

    • grant_type = urn:ietf:params:oauth:grant-type:jwt-bearer
    • assertion = the generated JWT

If this is what you're referring to, then I would like to point out that the self-signed JWT is not an access_token, and the response is an access_token but it's not a JWT. I point these things out just to clarify my understanding of your scenario.

With those corrections, to answer your question, I think there is no way for users (really, they are systems) to get an access_token based on the JSON key file of the service account, without going through this flow. This is the flow that is required to get an access_token for a service account.

If you want an access_token on behalf of a user, and not a system, that would involve a different flow. That involves the OAuth 3-legged signin, and it implies some user interaction.

The result in either case is an access token. In the case of a service account, the access token simply authenticates the service account. In the latter case, the access token authenticates the user and the client application or extension that the user is using.


To address the second question

2. Is it possible to disable TLS 1.0 and 1.1 while leaving TLS 1.2 and 1.3 enabled?

If you are following this link for setting up an HTTPS Load balancer in front of API Gateway, then yes, there's a way to turn off TLS 1.0 and 1.1 and keep TLS 1.2 and 1.3. For that I think you'd need a custom SSL policy on the load balancer. Read about that here. The builtin RESTRICTED policy requires TLS 1.2.  If you'd like TLS1.2 or TLS1.3 then I think you can create a custom policy.  More on that here.

Does this help?

 

Thank you very much for the response. What you have described is somewhat
more complicated than the current situation. The current situation is
working but is a little convoluted.

ATM I'm generating a key file for each client of the API against a service
account, i.e. each API client is represented by a service account. Each
client of the API uses their key file to create ephemeral self-signed JWTs
which are passed in the Authorisation header for each call to the API (just
like an access token). The clients choose the TTL of the JWT.

The creation of the JWT is fiddly and it would be great if there was an
easier way for an API client to create one. I know that it is possible to
use google auth client libraries to do this, but this is not always an
option for an API user. I could create a special "/token" path on the API
which creates the JWT for the API user, but it would need to be API key
protected, which renders the whole API only as string as API key security.

Another downside of this method of API client management is that a new
service account needs to be created and the API Gateway config needs to be
updated for each new user of the API. Although this is fine for a small
number of API users, this model doesn't scale well.

I accept that perhaps API Gateway is not well suited to being internet
facing with many API users. It does seem to be very well suited to a small
number of "sophisticated" API users who are able to create their own JWTs.

May be there is an opportunity to modernize (un-sure if you would like it or not) but lets see  standard industry ways.

Read if you are really care about security else you can ignore..

1. Build a api(/register) which helps clients do a dynamic client registration (more information)

https://openid.net/specs/openid-connect-registration-1_0.html

Above steps provisions the clients with a proper pair of client id & client secret while registering the client on the platform.

Add a web authentication flavor on register api with mTLS + IP whitelist during registration.

2. Once the step 1 is done & assuming you have standard oAuth infrastructure - https://datatracker.ietf.org/doc/html/rfc6749 ( either choose a simpler /token  client_credentials grant type to provision a  JWE (Json web encrypted token) while validating the client.. (you can do standard JWT but prefer more encrypted ones)

https://docs.apigee.com/api-platform/reference/policies/jwt-policies-overview

if you choose to use symmetric based algo would prefer to have  a key rotation mechanism internally the shared key is changed..(you need to take little care with rotation though - corner cases to take care of previously issued token with old key but doable..) This is to avoid frauds..

3. Once JWT/JWE token is issued you will have clients use the generated token for the resource calls.

Add a flavor for further security with JWS (json web signature) for POST calls to make sure message is not tampered..

https://docs.apigee.com/api-platform/reference/policies/generate-jws-policy

For TLS just get away from 1.0/1.1 which is vulnerable just speak to your network security engineer & get rid of them at enterprise level as these are  vulnerable.