22

Afternoon y'all,

Just looking for someone to double check my work. Is the below an effective way to secure microservices?

Premise

Breaking up our monolithic application and monolithic Partner API into microservices oriented around specific business functions. They'll most likely be small expressjs applications running in a docker container, on elastic beanstalk, who knows. They'll live somewhere :)

I'm looking into either standing up Kong as my API Gateway or using AWS API Gateway to encapsulate the details of my microservices. Also, it just feels good.

The JWT plugin for Kong will verify the signature of the JWT and then pass the customer_id along in the header to the microservice. I should also mention that we have 3rd party developers that will be partaking in the integration fun as well. Here's a basic sketch of what I see happening:

Implementation

  1. Generate "consumers" for each platform and 3rd party developer we have. (Web app, mobile app, and the current integration partners we have. Note: I'm not looking to create consumers for every user that logs in. While certainly more secure, this adds a lot of work. Also, if you figure out how to get the secret out of my API Gateway I clearly have other issues)
  2. Let Kong verify the request for me. Kind of like a bouncer at the door, there's no authorization, just authentication.
  3. I don't need to know that the token is valid once it gets to the microservice, I can just use some middleware to decode it and use custom logic to decide if this user really should be doing whatever is they're trying to do.

Extra Stuff

  • There's a nice access control plugin for Kong. Our application and mobile app would run with "God" privileges, but I could definitely lock down the developers to specific routes and methods.

  • Revoking 3rd party access will be easy, revoking end users access won't be so simple unless I'm willing to invalidate all JWTs at once by generating a new secret. Perhaps I can limit token time to 10 minutes or so and make our applications check if they're expired, get a new token, and then get on with the original request. This way I can "flag" them in the database or something and not let the JWT be generated.

  • SSL used everywhere, JWT is stored in an SSL only cookie in the web browser and there's no sensitive information stored in any of the claims.

Thanks guys.

Community
  • 1
  • 1
Sean Lindo
  • 1,387
  • 16
  • 33

1 Answers1

20

I recently worked on a solution to this very question and premise, refactoring a large monolith into multiple services in an AWS architecture.

There is no right, wrong or definitive how to this question.
However, we did implement a solution very similar to the one described in the question above.
I hope this answer can deliver a good sense of direction for someone who's looking at this for the first time.

This is how we went about it...

What do we need from an API gateway?

  1. Highly available
  2. Secure
  3. Performant
  4. Authoritative
  5. Scalable

Solution 1: AWS API Gateway

pros

  1. Highly available managed solution.
  2. Don't need to worry about scalability.
  3. Supports SSL and custom domains.
  4. Authoritative through lambda and IAM.
  5. Plays nice with other AWS services.
  6. Supports API versioning out of the box.
  7. Easy monitoring with CloudWatch.

cons

  1. Traffic can't be routed directly into an internal network (private VPC segment), meaning an additional gateway would be required.
    Edit: Amazon API Gateway Supports Endpoint Integrations with Private VPCs. Thanks @Red for mentioning this.
  2. Slow, our benchmark showed each request through API Gateway added 100-150 ms latency.

Solution 2: Kong

pros

  1. Scalable, but needs to implemented and managed on our end.
  2. Supports SSL and custom domains.
  3. Authoritative through plugins, with solutions for JWT and OAUTH2 already packaged.
  4. RESTful API for easy integration with our authentication server.
  5. Extensible, in case we need some custom logic.
  6. Fast, our benchmark showed each request through Kong added 20-30 ms latency.

cons

  1. Requires management on our end (upgrades, deployment, maintenance).
  2. In order to achieve HA, requires an additional endpoint, in the form of a load balancer to route traffic to the actual GW(s).

Implementation

We decided to go with Kong.
The major issue with the hosted solution was the inability to route traffic to our private network, where we also host a private DNS zone.
Additionally, the extensible nature of Kong allowed us to create custom plugins with logic that is relevant to our solutions.
We work with an ALB to round robin between multiple instances of Kong in different AZs in order to achieve redundancy and high availability.
The API configuration is saved on a Postgres RDS which is also internal and multi AZ.

Flow

  1. Client authenticates against our authentication server. The authentication server is a micro service behind the Kong GW with a publicly exposed upstream.
  2. Authentication server creates a consumer with a JWT for the individual client.
  3. Authentication server replies with the JWT.
  4. Client requests access from an API with the JWT, traffic routed via Kong.
  5. Kong verifies the JWT and routes the request to the micro service with information about the consumer.
  6. Micro service responds to the client.

Other

  1. Revoking user access is as easy as deleting the token.
  2. No sensitive information is stored in the JWT claims.
  3. All services know about each other through a private DNS zone.

Schema:

Kong Gateway Schema

LifeQuery
  • 3,202
  • 1
  • 26
  • 35
  • I think you can use ELB instead of ALB in front of Kong. Map www.example.com/api/* to that ELB and let Kong to take care of the different path (which is API-Gateway's functionality any way) -- see https://dmhnzl5mp9mj6.cloudfront.net/application-management_awsblog/images/img3.png – chen Jul 13 '17 at 01:17
  • Awesome reply. Con #1 does no longer apply though: https://aws.amazon.com/about-aws/whats-new/2017/11/amazon-api-gateway-supports-endpoint-integrations-with-private-vpcs/ Also for con #2 it does not apply to serverless architecture (When you have lambda function behind API gateway) – Red Mar 29 '18 at 22:37
  • "Revoking user access is as easy as deleting the token" Do you mean blacklisting the token? If not how do you delete an issued JWT? – qrius Apr 06 '21 at 03:16