Building a Multi-tenant SaaS solution on AWS

Certified Fresh Events
30 Oct 202253:27

Summary

TLDRThe presenter provides best practices for building a multi-tenant SaaS solution on AWS using serverless technologies. Key topics covered include SaaS architecture patterns like application and control planes, deployment models like silos vs resource pools, authentication, authorization and access control with Amazon Cognito and AWS IAM, API throttling with usage plans and API keys, dynamically injecting tenant IDs into IAM policies at runtime for tenant isolation, CI/CD pipelines for consistent deployments across environments, and more.

Takeaways

  • 😊 The talk focuses on best practices for building a SaaS solution on AWS using serverless architecture
  • 💡 The application plane contains the core IP/service offering, while the control plane manages operational aspects
  • 📝 Registration and onboarding of new tenants is handled by a separate microservice
  • 🔐 Authentication uses API Gateway authorizers, API Keys, Usage Plans and Cognito to handle multi-tenant security
  • 🚦 Tenant isolation in the pool model is achieved using IAM dynamic policies injected at runtime
  • ⚙️ The CI/CD pipeline ensures consistent deployment across shared and dedicated tenant resources
  • 🌐 A tenant routing mechanism redirects requests to the appropriate API Gateway based on tenant ID
  • 🎚 API Keys allow throttling incoming requests at the tenant level to prevent abuse
  • 💵 Tiered pricing models influence provisioning and resource sharing strategies
  • 🗄 Row-level security in DynamoDB helps restrict tenant data access in the pool model

Q & A

  • What are the two main components of a SaaS application architecture?

    -The two main components are the application plane, which is the core IP and service offering, and the control plane, which manages deployment, security, metrics collection etc.

  • What are the two typical deployment models for the application plane?

    -The two models are silo, where each tenant has dedicated infrastructure, and pool, where infrastructure is shared across tenants. The reference architecture uses a hybrid approach.

  • How does the application handle authentication and authorization?

    -It uses Amazon Cognito for authentication, generating JWT tokens. The tokens are validated by a Lambda authorizer, which also handles throttling based on usage plans and applies authorization policies.

  • How is tenant isolation achieved?

    -For pooled resources, dynamic IAM policies at runtime restrict access to only a tenant's data rows. For siloed resources, Lambda execution roles limit access to dedicated DB tables.

  • How are infrastructure resources provisioned when onboarding new tenants?

    -A registration service handles tenant onboarding workflows including creation of admin users in Cognito, allocating API keys, and conditionally invoking a provisioning service to deploy dedicated resources for high tier tenants.

  • What is the benefit of using Lambda layers?

    -Lambda layers allow reuse of common logic around metrics, logs, and authentication across Lambda functions, avoiding code duplication.

  • How does the architecture support canary deployments?

    -It uses CodePipeline to shift traffic between Lambda function versions. This allows testing a new version before routing all traffic to it.

  • How are costs attributed across tenants in a pooled deployment?

    -There is a dedicated lab on implementing tagging and CloudWatch metrics to attribute resource utilization and costs back to specific tenants.

  • What mechanisms handle routing of tenants to the appropriate backend resources?

    -Tenants provide their tenant name in the UI. An API looks up the relevant API Gateway URL, Cognito user pool etc. to route requests.

  • How does the CI/CD pipeline ensure consistency across environments?

    -It uses the tenant DB table as source of truth to deploy builds across all tenant stacks and pooled resources in one pass.

Outlines

00:00

🎤 Introducing the speaker and topic

The speaker introduces himself as a solutions architect at AWS, with 20 years of software development experience. He will be talking about best practices for building a multi-tenant SaaS solution using AWS serverless services.

05:01

📝 Defining SAS and its importance

The speaker defines SaaS as a centralized, subscription-based application delivery model. He emphasizes the need for agility and operational excellence to keep customers satisfied. Both B2C and B2B SAS models can leverage the discussed best practices.

10:01

💡 SAS design principles and architecture

The speaker explains the high-level architecture of a SAS application consisting of an application plane for the core multi-tenant app/IP, and a control plane to manage operational aspects. He further describes dedicated resource (silo model) vs shared resource (pool model) deployment approaches.

15:02

✨ Overview of deployed architecture and components

The deployed architecture consists of multiple web UIs for signup/admin, API Gateway with authorizers for authentication/authorization, various microservices for managing users/tenants, shared and dedicated Lambda functions and DynamoDB tables in a hybrid model.

20:04

👥 Onboarding tenants and users

The speaker explains how new tenants are onboarded by the registration service, which creates tenant admins and assigns resources based on tiers. User management configures users with appropriate metadata for access control.

25:05

🔐 Authentication, authorization and API throttling

End users authenticate via Cognito, which passes signed JWT tokens containing tenant/role metadata. The authorizer uses this to build allow/deny policies and apply API throttling based on tenant-specific API keys mapped during onboarding.

30:06

🛡 Enforcing tenant isolation using IAM

Tenant isolation is inherently enforced in the silo model. For the pool model, dynamic IAM policies injected at runtime restrict access to only rows belonging to the tenant making the request, enabling row-level security.

35:07

🚀 Automated CI/CD deployments

A centralized build pipeline takes code from source, builds it, runs tests, and deploys updates across all environments consistently using infrastructure details saved during tenant provisioning.

40:08

📡 Routing requests to appropriate tenant resources

The speaker briefly mentions subdomain-based and lookup-based routing approaches to direct incoming requests to appropriate API Gateways, Cognito pools etc. based on tenant.

45:11

🎁 Helpful references for implementation

The speaker strongly recommends going through the hands-on workshop content on GitHub to gain a deeper understanding and leverage the extensive guidance provided around implementing such an architecture.

Mindmap

Keywords

💡SAS

SAS stands for 'Software as a Service'. It is a business model where applications are hosted centrally and customers subscribe to use them, rather than installing software locally. Examples given in the video include Dropbox, Slack, and Salesforce. Building reliable, scalable SAS solutions on AWS is a major theme of the video.

💡multi-tenancy

Multi-tenancy refers to serving multiple customers/tenants from the same software platform. It is a key requirement for SAS solutions. The presenter discusses various patterns like resource pooling vs silos and tradeoffs between utilization and customizability.

💡serverless

Serverless is a cloud architecture model where backend resources are provided as scalable services rather than provisioned servers. The presenter focuses on using AWS serverless services like Lambda, API Gateway, DynamoDB to build the SAS solution.

💡API Gateway

API Gateway handles application APIs and cross-cutting capabilities like auth, throttling, transformations. The video shows how to implement per-tenant auth and throttling quotas.

💡Lambda authorizer

Lambda authorizers are used in API Gateway to implement custom auth logic. The video uses a Lambda authorizer for validating JWTs, enforcing quotas, and integrating with identity services.

💡DynamoDB

DynamoDB is used as the persistent store for tenant data and metadata. The video discusses patterns for tenant isolation like separate tables or dynamic row-level security.

💡tenant isolation

Tenant isolation refers to preventing tenants from accessing each other's data. It is a major requirement in multi-tenant systems. The video covers isolation patterns like separate DBs, dynamic IAM policies.

💡CI/CD pipeline

CI/CD pipelines automate build, test, and deployment flows across environments. For multi-tenant SAS, the video shows pipelines to support consistent, low-risk deployments across many tenant stacks.

💡hybrid model

A hybrid model combines both resource pooling and per-tenant silos depending on tenant size/SLAs. The reference architecture has a hybrid approach with pooled resources for small tenants and dedicated DBs/namespaces for large tenants.

💡serverless application model

The serverless application model (SAM) is a framework used to define and deploy serverless applications on AWS. SAM templates are used in the video to provision some of the SAS infrastructure.

Highlights

A SAS application has two key components - the application plane that delivers the core service, and the control plane that manages it.

SAS applications can deploy dedicated isolated resources per tenant (silo model) or share resources across tenants (pool model).

The onboarding process creates a tenant admin user, registers the tenant in a database, and conditionally provisions dedicated resources based on the tenant tier.

Custom user attributes in the identity provider associate each user with a tenant ID and user role for access control.

API keys throttle tenant API usage while authorizers validate tokens and build access policies based on user roles.

For resource pooling, IAM policies restrict each tenant's row-level access to shared databases at runtime.

Database access is controlled by dynamically injecting each tenant's ID into IAM policies to filter rows.

Primary keys are partitioned with a tenant ID prefix to enable row filtering while distributing data.

A pipeline builds and tests centrally before looping through a tenant database to consistently deploy across environments.

Tenants are routed to their dedicated resources via subdomains or by an API mapping tenant names to infrastructure.

For siloed resources, isolation is handled by restricting each Lambda and database to one tenant.

User pools logicaly separate groups of users to apply specific policies as needed.

Lambda authorizers cache token validation and access policies to reduce latency overhead.

Assuming cross-region IAM roles adds minimal latency, managed via caching.

For single table designs, execution role permissions remove the need for dynamic IAM policies.

Transcripts

play00:00

foreign

play00:03

[Music]

play00:08

first of all for inviting me here and um

play00:12

you know I'm really excited to to

play00:13

present this topic it's something very

play00:16

near and dear to me

play00:18

um in general just you know having you

play00:20

know building software for about 20

play00:21

years now

play00:23

um so today I'll be talking about how to

play00:25

build a SAS Solution on AWS using

play00:28

serverless

play00:29

so the idea here is to you know give you

play00:32

some best practices and how to use

play00:35

various AWS Services inside a reference

play00:37

solution

play00:39

um so if you are trying to build a SAS

play00:41

if you're trying to build a multi-tenant

play00:43

solution using AWS server services

play00:45

this is something you really want to you

play00:48

know maybe leverage as a starting point

play00:50

so before I begin just maybe a quick

play00:53

introduction about myself I am one of

play00:55

the solution Architects here at AWS I

play00:58

work for a team called SAS Factory and

play01:00

by the name maybe you can imagine that

play01:03

we help customers who are building SAS

play01:05

based Solutions on AWS right I have been

play01:08

writing code like for about 20 years now

play01:10

I started my career as a Visual Basic

play01:13

developer back then

play01:15

um and then I three years ago I joined

play01:17

AWS and and since then I've been working

play01:19

as part of this stream uh I'm outside

play01:22

work I have a family I have a wife and

play01:25

two boys 15 and 10

play01:27

um we live in Massachusetts and and

play01:29

recently we also got a dog and she keeps

play01:32

me busy sometimes all right so let me

play01:35

begin

play01:36

so I thought maybe it probably makes

play01:38

sense you know before I jump into the

play01:40

technical details to Define what

play01:43

software as a service really means

play01:45

um so if if you just you know look at

play01:47

this definition which we have here is

play01:50

it's more of a business delivery model

play01:52

right so SAS is a way of doing business

play01:55

where you centrally host your

play01:59

application and your customers come and

play02:02

they subscribe to that application right

play02:04

some examples if I have to give think of

play02:07

Dropbox slack Salesforce these are some

play02:11

of the examples pretty popular SAS

play02:13

platforms which you just go and

play02:15

subscribe so as an example for Dropbox

play02:17

you just you know buy some sort of

play02:19

storage and you just pay on monthly

play02:21

basis for the storage you don't have to

play02:24

like buy a hard disk or install anything

play02:26

on your machine right it's just some

play02:28

sort of consumption based model you're

play02:30

following right so today's discussion

play02:34

is relevant for both d2c or business to

play02:37

consumer or B2B or business to business

play02:39

uh SAS models although I would say that

play02:42

it's um it will be more beneficial it

play02:45

will be more beneficial if you are

play02:47

working on a B2B kind of SAS but you can

play02:49

apply the principles and best practices

play02:51

in both the cases

play02:54

so I thought it is relevant

play02:57

um to show this code from Jeff bizas

play03:00

which he wrote in his 2016 letter to

play03:03

shareholders and if you just pay

play03:05

attention to this one line which he says

play03:08

right that customers are always

play03:10

beautifully wonderfully dissatisfied I

play03:13

thought this was very relevant in this

play03:14

context because if you're a SAS provider

play03:17

you'll have hundreds and maybe millions

play03:19

of customers and tenants in your system

play03:21

and and it becomes really important for

play03:24

you to raise the bar in terms of agility

play03:27

and operational excellence uh just

play03:29

imagine like even like a small down time

play03:32

of 10 to 15 minutes can have a severe

play03:34

impact on your on your business right

play03:38

um so it's very important to to work

play03:40

backwards and be customer obsessed and I

play03:43

thought this quote is very much relevant

play03:44

for today's discussion

play03:46

all right so now what it means to be SAS

play03:49

right so

play03:51

you know before I jump into the

play03:53

serverless and how to use serverless

play03:54

services

play03:55

I'll probably have a couple of slides

play03:58

which talks about the high level

play03:59

architecture patterns or design

play04:01

principles that I need to understand

play04:03

while building a SAS application

play04:05

and the first thing you need to

play04:06

understand is

play04:08

broadly you can Define your SAS

play04:10

application or design your SAS

play04:11

application into high level components

play04:13

an application plane and a control plane

play04:16

so application plan is basically it's

play04:20

actually your IP it's the service that

play04:22

you're providing to your customers so in

play04:25

this case in the examples I gave storage

play04:28

as a service or a CRM platform or a

play04:31

messaging service it's basically your IP

play04:34

and that's pretty much your offering to

play04:36

your customers and this is an a platform

play04:39

that obviously is multi-tenant by

play04:42

default and what does it mean what it

play04:44

really means is you'll have multiple

play04:45

businesses multiple customers multiple

play04:48

users within those businesses who will

play04:50

be subscribed to your SAS platform and

play04:53

be leveraging all at same time

play04:56

on the other hand what we have is a

play04:58

control plane and the controller plane

play05:00

is pretty much what is managing this

play05:03

entire application plane right

play05:05

um this is basically your platform or

play05:08

set of micro Services which are

play05:10

responsible for onboarding a new tenant

play05:12

as an example right managing the

play05:14

security aspects of a SAS solution

play05:16

you'll have some sort of identity

play05:19

management system

play05:20

you will have some sort of micro

play05:22

Services which will collect the logs and

play05:25

Mattress metrics from a SAS platform and

play05:27

consolidate them together and and then

play05:29

be able to visualize them right and then

play05:32

you'll have some sort of microservices

play05:35

which will allow you to provision a new

play05:37

tenant or maybe provision the resources

play05:40

of a new tenant inside your SAS platform

play05:42

so this control plane are basically set

play05:44

of services which do not need to be

play05:47

multi-tenant I mean they are just to

play05:49

control the application plane or the

play05:51

deployment and and operational aspects

play05:54

of a SAS solution

play05:58

now within the application plane there

play06:01

are two typical deployment models that

play06:04

we see customers follow when they deploy

play06:06

inside AWS

play06:08

the first one which is pretty common is

play06:10

you have dedicated resources for each

play06:12

tenant so take an example where you have

play06:16

tenant one who is trying to onboard into

play06:18

your system and you provision may be a

play06:20

separate eqs cluster or an RDS database

play06:23

instance for them all together right and

play06:26

this model is what we call it a silo

play06:29

model

play06:30

basically you are just provisioning

play06:32

separate infrastructure resources for

play06:34

all of your tenants

play06:36

now the other model is what we call it

play06:38

as pool model and in this case as you

play06:41

can imagine you have your existing or

play06:45

your services or your resources shared

play06:48

across all these tenants so imagine an

play06:52

RDS cluster or maybe a eks cluster you

play06:56

know being accessed by and shared by all

play06:58

the tenants and as you can imagine right

play07:01

it's probably pretty evident that each

play07:04

model has their pros and cons right so

play07:07

in case of a silo model on the left side

play07:10

you see you have little bit of better

play07:13

compliance alignment so if you have

play07:15

customers who are little bit concerned

play07:17

about the compliance and security

play07:19

aspects or maybe you have Tighter slas

play07:22

and you want to tune the resources

play07:25

according to those tenants The Silo

play07:27

model will be more suitable in those

play07:29

cases whereas if you are trying to

play07:32

maximize your resource utilization if

play07:34

you're trying to make sure that you have

play07:36

resources which are shared by multiple

play07:39

users and customers and tenants which

play07:42

gives you obviously better cost

play07:43

efficiency you probably go for for us

play07:46

for a pool model

play07:47

now having said that it is important as

play07:50

a SAS provider that you make sure that

play07:52

proper tenant isolation and security

play07:54

requirements are followed regardless of

play07:57

what model you choose

play07:59

in fact today the reference solution

play08:01

that we will talk about I have a hybrid

play08:04

model in place where we will provision

play08:06

some resources or some tenants in a silo

play08:09

model and some tenants in a pool model

play08:12

and we will actually see how you can

play08:14

enforce the tenant isolation

play08:16

authentication authorization in in both

play08:19

both ways

play08:22

so let me just you know jump on to the

play08:24

reference solution that I was talking

play08:26

about which we have built which kind of

play08:28

uses all these design patterns

play08:31

um and it kind of applies them together

play08:33

to build a working solution

play08:37

um I'm going to first talk about the AWS

play08:40

services and features that we leverage

play08:42

as part of this reference solution

play08:44

um so what we did we we first leveraged

play08:46

what we call it as AWS serverless

play08:48

application model or Sam and we we

play08:51

deployed our resources using Sam so Sam

play08:54

is basically an open source framework to

play08:57

deploy your serverless resources on AWS

play09:00

and then alongside we also leverage cdk

play09:03

to deploy some more components mainly

play09:06

for the devops footprint of our SAS

play09:09

application now the difference between

play09:12

Sam and cdk Sam is more like markup you

play09:15

you probably use yaml or Json ctk is

play09:18

more programming language so basically

play09:20

you can actually write a typescript and

play09:23

deploy your resources the idea was to

play09:25

show that they both can work in parallel

play09:27

and hand in hand

play09:29

um but in your case you might just do

play09:31

cdk to deploy your resources but we

play09:33

intentionally use both just to show how

play09:36

the kind of work hand in hand

play09:39

so then our API layer was built using

play09:44

Amazon API Gateway and we specifically

play09:47

leveraged the rest API capabilities of

play09:51

API Gateway to build our API layer so

play09:54

all our apis are restful apis

play09:56

um they follow that get put post kind of

play09:59

methods

play10:01

then for the authentication and

play10:03

authorization purposes we leverage a

play10:05

feature we called as Lambda authorizer

play10:08

within API Gateway and I'll talk about a

play10:10

little bit more detail on how that works

play10:12

in subsequent slides

play10:15

another feature that we use was usage

play10:18

plans and API keys so typically in a SAS

play10:22

portal if you have multiple tenants who

play10:25

are trying to access the system

play10:26

you need to be really careful about

play10:29

enabling some sort of throttling

play10:31

mechanisms in your application right so

play10:33

think about it that you're trying to

play10:35

open up your apis to hundreds of

play10:37

customers what if one customer just run

play10:40

accidentally maybe run a script and just

play10:42

trying to bombard your apis right so

play10:44

there are chances that your resources

play10:46

might get exhausted so in order to

play10:49

enforce some sort of throttling

play10:50

mechanisms we leverage this feature and

play10:54

I'll show you how that works exactly as

play10:56

well

play10:57

then we leverage Amazon Cognito as our

play11:01

identity management platform and we we

play11:04

specifically leverage what we call it as

play11:07

user pools as a feature with Incognito

play11:09

to store our users

play11:12

um so your users can come and register

play11:13

themselves and then later can

play11:15

authenticate themselves using a username

play11:18

password based workflow

play11:21

then for the compute layer we leveraged

play11:24

AWS Lambda and specifically I will also

play11:27

talk about how we leverage the fine grid

play11:30

Access Control using AWS SDS service

play11:33

this is more relevant when you are

play11:36

working in that pool model where a

play11:38

single Lambda function is shared across

play11:40

multiple tenants and users like how does

play11:42

that find that access control work

play11:44

and then we leverage Lambda layers which

play11:48

is another functionality a feature

play11:50

inside Lambda service which basically

play11:53

let you create reusable libraries and

play11:56

share those reusable libraries across

play11:58

multiple Lambda functions so in our case

play12:01

specifically we we leverage metrics and

play12:04

logging and authentication authorization

play12:06

which was more like a reusable pattern

play12:09

and build them using Lambda layers and

play12:11

we then you know we basically then

play12:15

leverage those layers across multiple

play12:16

Lambda functions

play12:18

and then finally I'm not going to talk

play12:21

about this in more detail today but um

play12:23

obviously at the end of this slide I'll

play12:25

give you some links of of the reference

play12:28

solution in which is inside GitHub which

play12:31

you can go and refer yourself but there

play12:33

are more features like code Pipeline and

play12:35

Canary deployments like how to do

play12:37

traffic traffic shifting uh between your

play12:39

version of Lambda so let's say you're

play12:41

trying to deploy a new version of Lambda

play12:44

function you might want to you know

play12:46

slowly shift traffic towards that new

play12:48

function

play12:49

um just a way to you know automate the

play12:50

canary deployment so that's another

play12:52

feature that we implemented within this

play12:55

reference solution

play12:56

and then finally uh we use dynamodb as

play12:59

our layer of storage and um dynamodb

play13:03

again is a key Value Store provides you

play13:06

a great way to you know store your data

play13:08

in a serverless fashion

play13:12

one more thing I wanted to mention at

play13:15

this point is that the application plane

play13:18

as I mentioned to you is deployed in a

play13:20

hybrid model

play13:22

so I'll show you how you actually

play13:25

onboard your tenants into the system but

play13:27

you will see that when you once you

play13:29

onboard the tenant into the system the

play13:32

basic and the standard ta tenants are

play13:34

deployed in a pool model so basically

play13:37

these standards will be sharing the same

play13:40

set of API Gateway Lambda functions and

play13:42

dynamodb table

play13:44

whereas when we create a new tenant as a

play13:48

platinum tier tenant um we actually

play13:50

deploy separate resources for those

play13:52

tenants uh again you know the whole

play13:55

concept of tiering not sure if you if

play13:58

you are aware of that or not but

play13:59

typically when you're building a SAS

play14:01

model you try to create different sort

play14:03

of tiers for your for your tenants and

play14:06

you kind of maybe sometimes provide more

play14:10

um as you know maybe more functionality

play14:12

to certain tenants provide better slas

play14:14

to certain tenants so the idea here was

play14:17

to show like how you can leverage those

play14:18

steering based strategies to you know

play14:20

even influence your architecture in this

play14:22

case

play14:23

and then the control plane has been

play14:26

built using four different microservices

play14:28

all using Lambda functions

play14:32

um registration is for registering a new

play14:34

tenant tenant management

play14:37

is for managing the tenants and user

play14:39

management is basically a facade in

play14:42

front of your Cognito so if if if you

play14:45

need to you know use a different IDP

play14:47

instead of Cognito you can you just need

play14:48

to change and set this user Management

play14:50

Service

play14:51

um and and you and the rest of your

play14:53

application doesn't really get impacted

play14:54

a lot and then finally we have a

play14:57

microservice for provisioning resources

play15:00

for this Platinum tier tenants

play15:02

um and as you onboard

play15:04

okay so let's now dive a little deep

play15:07

um and and see you know how what you

play15:10

really get when you deploy this Baseline

play15:13

architecture right

play15:14

so when you get the code from GitHub

play15:17

you will see in the instructions that

play15:20

you will be asked to deploy the the the

play15:23

architecture using some sort of

play15:25

deployment Scripts and when you deploy

play15:27

that the first thing that you will see

play15:29

you will get a you will probably get

play15:30

three different web applications

play15:33

so the first web application that you

play15:35

will see here is um is the landing

play15:37

signup application which we built using

play15:40

angular 2 and the idea here was to

play15:43

automate that whole onboarding

play15:45

experience so your tenants can come and

play15:47

register themselves into this

play15:49

application

play15:50

then at the center right here you see a

play15:54

sample SAS application and this is just

play15:56

a example SAS application we we just

play15:59

took like a very basic e-commerce use

play16:02

case

play16:03

um basically it's it's very simple use

play16:06

case of a order and a product service

play16:09

um this will change depending upon your

play16:11

needs right so you might have a totally

play16:13

different use case but the sample SAS

play16:16

application will give you like an idea

play16:17

of how to implement multi-tenancy within

play16:19

your micro services

play16:21

and then we also built a admin console

play16:24

for SAS providers again built using

play16:27

angular 2. and in this case

play16:30

um we basically you know allowed SAS

play16:33

providers to manage tenants or onboard

play16:35

tenants

play16:36

um and you know just be able to add more

play16:39

users into the system

play16:40

the the authentication as I mentioned is

play16:43

being managed through a cognito

play16:45

then the next thing that that gets

play16:47

deployed inside your AWS account is the

play16:49

API Gateway and as I mentioned you will

play16:53

get a Lambda authorizer which will be

play16:55

responsible for the authentication and

play16:56

authorization of your application

play17:00

um you will get API keys and usage plans

play17:03

feature built into this authorizer now

play17:07

one thing you might notice which is

play17:08

little different and you know sometimes

play17:10

can get it confusing as well that we are

play17:13

not really passing the API key from the

play17:15

UI right normally typically the way

play17:19

developers think that they need to pass

play17:21

an API key to the API from the client

play17:23

which is obviously one way to do it but

play17:26

in our case what we actually did we were

play17:29

generating the API key and mapping to

play17:32

the tenant as part of the onboarding

play17:34

process

play17:35

and our Lambda authorizer is basically

play17:38

trying to map the API key depending upon

play17:40

the tenant so I'll show you how that

play17:43

works in little bit more detail but we

play17:45

are not really passing API key from the

play17:47

UI but rather just mapping the API key

play17:50

inside the Lambda authorizer itself

play17:52

and what that really allows us to do is

play17:54

it allows us to throttle all this

play17:57

incoming requests so just keep in mind

play18:00

that this API key is by tenant and the

play18:03

way is typical SAS solution works you'll

play18:05

have like a hierarchy right you'll have

play18:07

a tenant like a like a business who buy

play18:10

your SAS solution and you will have

play18:12

multiple users within those tenants

play18:13

right now the the whole concept of usage

play18:18

plans and API key in our case is at the

play18:20

tenant level so if you have a user who

play18:23

is trying to abuse the system what that

play18:27

basically means is that that abuse is

play18:30

limited within that tenant because now

play18:32

what you're saying is that hey

play18:34

this tenant can only access the API

play18:37

let's say 100 times in a day just an

play18:40

example or maybe a million times in a

play18:43

day right uh and if it tries to go

play18:45

beyond that this usage plan will not let

play18:48

you do so

play18:50

then the next thing that gets deployed

play18:52

as part of the architecture is those

play18:54

four microservices as I mentioned for

play18:57

registration tenant management

play18:59

provisioning a user management

play19:02

and then we are also deploying The Pool

play19:05

services for the application plane so in

play19:08

this case as I mentioned we took a very

play19:11

basic example of an order and a product

play19:14

service so we are deploying this order

play19:17

and product service which will be

play19:19

leveraged by all the basic and standard

play19:21

tier tenants so this is something that's

play19:23

that's getting deployed up front and

play19:26

then we are deploying some Lambda layers

play19:28

for authentication metrics logging Etc

play19:32

so this is the basic architecture that

play19:34

gets deployed initially

play19:37

um obviously there are some things that

play19:39

get added or provisioned as you onboard

play19:41

and more tenants um so that's kind of

play19:43

that's something I'm going to you know

play19:44

talk about next at how that really works

play19:47

all right so let's maybe dive a little

play19:50

deeper now so you know so far I've

play19:52

talked about some basic concepts I've

play19:53

talked about the high level architecture

play19:55

now I'll probably talk about some more

play19:58

deep Concepts and also maybe show you

play20:01

some code as we go along and how those

play20:03

things really work

play20:04

so the first thing I wanted to talk

play20:06

about is registering new tenants or

play20:09

onboarding new tenants right so if you

play20:11

remember

play20:12

we had two different user interfaces

play20:15

that we talked about that could be

play20:17

leveraged to onboard your tenants right

play20:19

now this could be

play20:21

in your case you might only have one or

play20:24

both so what we have seen is that if

play20:27

you're trying to operate a B2B kind of

play20:29

SAS application sometimes you don't

play20:31

expose your Landing or sign up

play20:33

application publicly you just have an

play20:35

admin console and you just use that to

play20:37

to register your tenants so what you

play20:41

will do is when you register a tenant

play20:42

the first thing that happens is you

play20:45

invoke the registration micro service

play20:47

and in this case

play20:49

um and this is by the way an open

play20:50

endpoint right

play20:52

um resistance microservice because this

play20:54

is something you're exposing to your

play20:55

public to your customers

play20:56

and depending upon the tenant tier so if

play21:00

it's a basic or a standard tier then you

play21:02

follow a different workflow and if you

play21:04

are like a platinum tier you follow a

play21:06

different workflow right and the

play21:08

workflow in this case is as I showed to

play21:10

you like in couple of slides back for

play21:12

for platinum tier tenants we are

play21:14

deploying a whole set of AWS resources

play21:17

separately in Asylum model foreign

play21:20

so this service kind of orchestrates

play21:23

some sort of workflow on how to

play21:26

provision a new tenant and the first

play21:27

thing that happens in this workflow it

play21:30

it's basically creating a new

play21:32

um user a new tenant admin user and this

play21:35

new tenant admin user is then

play21:37

responsible for onboarding more tenant

play21:40

users later on

play21:42

and as I mentioned depending upon the

play21:44

tier of the tenant this user management

play21:47

decides if I need to create a whole

play21:49

separate user pools pool Incognito or

play21:52

should I just kind of group

play21:54

all the users within a single user pool

play21:56

and for those who are not who don't know

play21:59

how I'm cognitive user pools work they

play22:02

are basically a way to kind of group

play22:04

your users right so so if you have a

play22:06

tenant who wants some sort of settings

play22:09

like multi-factor authentication

play22:11

different password policies it makes

play22:14

sense to have a silo user pool for them

play22:16

right but if you have tenants who don't

play22:20

really have any unique requirements you

play22:21

can just pull them into a single user

play22:23

pool so again based up in our case based

play22:26

upon the tenant tier we are making that

play22:27

decision at this point

play22:30

the second thing that happens is

play22:32

actually the creation of Canon inside a

play22:34

dynamodb table and this is we're used to

play22:36

attendant configurations like Canon name

play22:39

address billing information etc etc

play22:42

and then finally if it is a silo tenant

play22:45

if it is a platinum tier tenant that

play22:47

requires separate AWS resources we

play22:51

conditionally invoke this tenant

play22:52

provisioning service to onboard those

play22:55

tenants in Asylum model and I'll

play22:57

actually talk about a devops pipeline as

play22:59

well later I hope we'll get enough time

play23:02

to talk about that which which will show

play23:04

you how you can you know automate that

play23:06

whole onboarding process across

play23:08

different tenets as well

play23:11

so I I have some code here in the slides

play23:14

itself

play23:15

um you know instead of Shifting screens

play23:17

I thought it would be easier if you just

play23:19

you know look at some of the code

play23:20

obviously you can go to the GitHub

play23:22

repository and do a deep dive but um so

play23:25

if you look at here this code snippet is

play23:28

from the user Management Service and one

play23:31

thing I wanted to highlight here is that

play23:33

so obviously you're getting you know in

play23:35

the even body you're getting the user

play23:37

details you get the tenant ID as well

play23:40

and by the way this tenant ID is being

play23:42

generated by the registration service

play23:44

which then invokes this service right so

play23:47

you get all this information and then

play23:49

you have this

play23:52

Cognito client and you basically are

play23:55

creating a user inside Cognito at this

play23:57

point and this is where we are providing

play24:00

all the user attributes and these two

play24:03

attributes if I just you know may pull

play24:05

your attention here these are two

play24:07

attributes we call as custom attributes

play24:10

um so for those who who understand how

play24:12

oauth and what custom attributes really

play24:14

means within um within the IDP

play24:17

um this is a way to add some sort of

play24:19

metadata to this user right um so in

play24:22

this case we are saying that okay this

play24:24

user has a user role let's say tenant

play24:27

admin or tenant read-only user and

play24:30

belongs to this particular tenant which

play24:32

is being registered which was being

play24:33

registered or or what tenant this user

play24:36

really belongs to right so this is our

play24:38

way of telling inside the RDP which user

play24:43

the standard belong to and the way we

play24:45

are enforcing this is by using custom

play24:47

attributes right

play24:49

and on the right side

play24:51

um this small code snippet is from the

play24:53

create tenant from the tenant Management

play24:55

Service

play24:56

and this is where you have all those

play25:00

um Talent attributes like name address

play25:02

email etc etc

play25:04

um but I am also saving an attribute

play25:08

called as API key here as well so what I

play25:11

do is you know I'm generating this API

play25:13

key as part of the registration process

play25:15

itself and mapping that API key to the

play25:18

Tanner inside the standard management

play25:19

table and then you know we are also

play25:22

saving what user pool and app client

play25:25

this um

play25:26

this this tenant is supposed to

play25:29

authenticate against so in this case you

play25:31

know if you are generating a new user

play25:33

pool per tenant for the for for The Silo

play25:36

tenants

play25:37

um this is where we are kind of saving

play25:39

all the information so basically all the

play25:40

internet information

play25:41

[Music]

play25:43

um is being saved inside this dynamodb

play25:44

table

play25:47

so at this point um you know you have

play25:50

onboarded a a tenant into the system

play25:53

right

play25:54

um now you have a tenant admin who who

play25:58

has access to your sample SAS

play26:00

application

play26:01

and the next thing your tenant admin or

play26:04

your tenant user will do it will try to

play26:06

you know login into your application

play26:08

into your SAS application so this is

play26:10

actually your application which they

play26:12

will be using in long term like it could

play26:13

be like a storage as a service or some

play26:15

sort of e-commerce platform right so

play26:18

it's important to understand how the

play26:21

authentication and authorization really

play26:23

works in this whole multi-tenant

play26:25

um complex system right

play26:28

so let's say a tenant user is trying to

play26:31

access the system the first thing

play26:33

obviously you will do is you will ask

play26:35

them to provide a their username and

play26:37

password credentials right

play26:39

um and and basically in our case since

play26:41

we are using Cognito we are just

play26:42

redirecting that tenant to the Cognito

play26:45

hosted UI which provides this nice

play26:48

username password

play26:49

um it's it's something which is already

play26:51

built in you don't have to build this

play26:53

username password UI right so they will

play26:55

authenticate so once the authentication

play26:58

is successful Cognito will send back a

play27:00

jar token and in this dot token as I

play27:04

showed to you you'll have tenant ID and

play27:06

use the role as as custom attributes

play27:08

right

play27:08

so now what you will do is you will try

play27:12

to access the API Gateway or your UI

play27:15

your sample SAS application will try to

play27:17

access the API Gateway

play27:20

and the first thing that happens in this

play27:22

whole workflow ad you will hit that

play27:23

authorizer which will first of all make

play27:26

sure that your jaw token is valid it

play27:29

will go back to the Cognito endpoint and

play27:32

make sure that your jaw token has an

play27:34

expired it's a valid token and then it

play27:38

will build something called as an

play27:40

authorizer policy and this authorizer

play27:42

policy

play27:43

will do at least two things for now

play27:46

right first of all based upon this user

play27:50

role it will say that okay you know what

play27:52

is this user even authorized to access

play27:54

this endpoint right so let's let's say

play27:57

you have a read-only user

play27:59

you don't want a read-only user to

play28:01

access your post and put endpoints it

play28:03

probably you only want them to access

play28:05

get right so in that case

play28:08

um this authorization policy will

play28:10

prevent you based upon the user role and

play28:13

then the second thing it will do it will

play28:15

basically you know provide that API key

play28:18

which is stored inside the tenant

play28:19

management table and enable the

play28:22

throttling

play28:23

um so or in other words it will say that

play28:25

hey this user or this tenant is only

play28:28

authorized to access your apis let's say

play28:31

100 times in a minute or 100 times in an

play28:33

hour and so on and so forth

play28:36

so and then you know once this whole

play28:38

authorization process completes once the

play28:40

jaw token is validated once you make

play28:42

sure that your your quotas are well

play28:44

within the limits once you make sure

play28:46

that the authorization is is valid then

play28:49

you actually go ahead and actually call

play28:51

that relevant Lambda function which is

play28:53

basically your compute layer right so

play28:55

this is like a typical workflow that you

play28:58

follow

play28:59

um and and I think the important things

play29:01

to highlight here was the whole concept

play29:04

around multi-tenancy in terms of how you

play29:07

match manage API keys and how you

play29:09

validate jaw tokens here

play29:12

now

play29:14

just kind of diving deep into the code

play29:16

again a little right so this is again a

play29:18

small code snippet I took from the from

play29:20

the GitHub repository

play29:22

and if you see this auth manager is

play29:26

basically a python module it's slammed

play29:28

earlier actually so what we have is we

play29:31

have some methods inside the Lambda

play29:33

layer which take the user role and tells

play29:36

you whether you should allow method or

play29:39

whether you should deny methods right so

play29:41

in this case I'm denying

play29:43

certain endpoints based upon certain

play29:45

user roles and I'm allowing certain

play29:47

endpoints based upon certain user roles

play29:49

and basically you just you know build

play29:51

that policy and pass to the uh

play29:53

authorization policy as I was mentioning

play29:55

previously

play29:58

now

play30:00

the whole tenant isolation

play30:02

um is a separate so so I so I just

play30:04

talked about the whole authentication

play30:05

authorization how that works right um

play30:07

the next next thing I want to talk about

play30:09

was how do you actually enforce tenant

play30:12

isolation into the system and what I

play30:15

really mean by that is like let's say

play30:17

you have data from multiple tenants

play30:19

multiple users inside your dynamodb or

play30:23

whatever data store of your choice right

play30:25

how do you make sure that one tenant is

play30:29

not able to access other tenants data

play30:31

typically like you know going back maybe

play30:34

15 years back you know I would say that

play30:37

I will just write a rear class right

play30:38

where customer ID is equal to one where

play30:41

tenant ID is equal to ABC and that will

play30:44

that's probably sufficient right but but

play30:46

but then we are kind of handing over the

play30:49

whole security aspects of our system in

play30:52

the hands of developers right so what we

play30:54

are saying that hey it's supposed to be

play30:56

developers to write a code and make sure

play30:58

you have beer Clause everywhere and then

play31:00

you test them and then you test them

play31:01

against all those security measures so

play31:04

typically that that way of isolating

play31:07

tenants is prone to lot of errors and a

play31:10

lot of you know issues in general

play31:12

so in AWS you have a concept of IAM and

play31:16

I'll show you how you can apply that

play31:18

um typically to enforce tenant isolation

play31:21

so first of all in a silo model assume

play31:24

that there is a tenant now who is trying

play31:26

to access the system

play31:28

it has gone through all those

play31:30

authentication and authorization checks

play31:32

we just talked about it's all good and

play31:34

now it's time to access your Lambda

play31:36

function

play31:37

so now in case of a silo model we

play31:40

deployed separate Lambda functions and

play31:42

Separate dynamodb Tables per tenant

play31:45

so our isolation story is very simple in

play31:48

our case right so in our case all we are

play31:51

saying is that we will associate this um

play31:53

this Lambda function with an execution

play31:55

role and this execution role have access

play31:58

to only this dynamodb table right so

play32:01

this makes the whole tenant isolation

play32:04

story much more simpler

play32:06

but in case of a pool model you can

play32:08

imagine you could just when you have

play32:10

like a single Lambda function when you

play32:12

have a single dynamodb table shared

play32:14

across all the tenants

play32:16

this way of isolating may not be

play32:18

sufficient right so how do we solve that

play32:21

challenge so in order to solve that

play32:22

challenge we we introduce a concept of

play32:25

dynamic policies and the way it works is

play32:27

you are able to at runtime

play32:31

can inject a tenant ID into a dynamic

play32:35

policy so this policy by the way is

play32:37

stored in some sort of configuration

play32:38

right so what you are doing is you are

play32:40

saying that hey this policy allows you

play32:42

to

play32:43

make these five actions on a dynamodb

play32:45

table on this particular table but only

play32:49

allow an action to those rows which

play32:52

start with the primary key of tenant ID

play32:54

right and in this case the standard ID

play32:56

is is basically a placeholder which gets

play32:59

injected at runtime

play33:01

so let's let's look at the code and how

play33:03

that actually works right so

play33:06

imagine this this is one of my code

play33:08

which I have in my in my Lambda

play33:10

authorizer and this method get policy

play33:13

for user basically takes two arguments

play33:15

right user role and tenant ID and by the

play33:18

way these two arguments are already

play33:20

available to us as part of the jaw token

play33:22

right so what we typically do is we

play33:25

decide that for this user role what kind

play33:28

of policy I need to implement do I need

play33:30

to you know provide like get or just or

play33:33

or maybe maybe write as well and then

play33:35

this tenant ID which which I get from

play33:37

the Jaw token gets dynamically injected

play33:40

into that policy and then I'm leveraging

play33:43

this service which we call it as AWS STS

play33:46

and passing that policy to get back

play33:49

credentials which are now scoped to the

play33:51

tenant in short what we are trying to do

play33:54

is we are trying to enforce row level

play33:56

security inside dynamodb right

play33:59

um so basically this is a way of

play34:00

implementing row level security inside a

play34:03

dynamodb table by leveraging am AWS IM

play34:07

policies and that and these credentials

play34:11

um which are now only scope to their

play34:13

tenant are passed onto the Lambda

play34:15

function and when the Lambda function is

play34:18

now trying to access the dynamodb table

play34:21

it will Leverage

play34:23

and that these credentials to access the

play34:25

table right so in the typical uh

play34:27

database relational database you can

play34:30

think of it as a database user right so

play34:32

database users normally have access to

play34:34

let's say only database one database two

play34:36

so you create separate users to give

play34:38

access to different databases and and

play34:41

you basically make sure that that that's

play34:43

how you enforce some sort of security in

play34:46

this case we are we are basically

play34:48

leveraging the scope Dynamic policies to

play34:51

to implement that kind of isolation in a

play34:54

pool model

play34:55

so as I mentioned this this context or

play34:59

these credentials are passed as to your

play35:02

Lambda function as part of the context

play35:04

from the Lambda authorizer so this code

play35:06

I actually took from the Lambda

play35:08

authorizer and this is basically the

play35:09

entire policy I was talking about the

play35:11

authorization policy right

play35:13

um and and there are a bunch of things

play35:14

that I'm doing here so I'm passing those

play35:16

success secret key I'm also passing the

play35:19

API key which actually enforces the

play35:21

whole

play35:22

actually this is this is where you

play35:23

actually enforce that whole usage plan

play35:27

as well right so so you basically pass

play35:29

all these information to your authorizer

play35:31

output

play35:33

um and and now when you are into that

play35:36

whole authentication authorization

play35:37

workflow right so again

play35:39

you're trying to access a system this

play35:42

isn't this is a example where you're

play35:43

trying to access in a pool model

play35:45

your authorizer is now able to access

play35:48

that IAM STS service I was talking about

play35:50

to get that runtime acquired tenant

play35:53

scope

play35:54

and pass those credentials to a Lambda

play35:57

function and when now this Lambda

play36:00

function is trying to access your

play36:02

dynamodb table

play36:04

you have to make sure to pass you know

play36:06

these um so as long as you you have that

play36:08

reusable date access layer which you

play36:11

know passes the access secret key

play36:13

um you can be assured that

play36:16

that row level security is implemented

play36:18

because of the IM Dynamic policy that we

play36:20

talked about

play36:21

now

play36:23

one more thing I wanted to highlight at

play36:25

this point is how would you you know

play36:28

partition your dynamodb table right so

play36:30

if you remember the condition of the

play36:33

dynamic policy I was referring to

play36:35

had a concept that okay only allow

play36:39

where can where where your shot ID

play36:42

starts with or where your primary key

play36:43

starts with a tenant uh ID

play36:46

Etc right whatever tenant ID in your

play36:48

case

play36:48

so now in this case I have one two three

play36:51

four different rows for the tenant and a

play36:55

random

play36:56

suffix right so the reason I'm I'm not

play36:58

really just putting

play37:00

tenant ID as the primary key is just to

play37:01

avoid that hotkey issue right so I'm

play37:04

kind of Distributing the workload uh or

play37:08

just Distributing the data across

play37:09

multiple partitions but still be able to

play37:13

apply that condition by using a string

play37:16

like kind of fashion so basically all

play37:19

I'm all I'm saying is that hey this

play37:21

policy is basically applicable where

play37:25

your primary key starts with tenant ID

play37:27

right if you want to think of that way I

play37:29

mean I I totally understand this is a

play37:31

bit of a complex

play37:32

um thing to understand if you're not

play37:34

really used to these kind of terminology

play37:37

so I will highly recommend that you go

play37:39

back and look at the GitHub repositive

play37:41

which I'll just show you in a minute

play37:43

and then just one more thing I wanted to

play37:46

cover

play37:46

um and then we'll yes you know see if

play37:48

you have any questions right so there's

play37:50

one more thing I wanted to cover around

play37:51

the whole CI CD aspect of this SAS

play37:54

solution right

play37:56

um now you can imagine that you know you

play37:57

have all these environments you have a

play37:59

pool environment you have environment

play38:01

for tenant specific infrastructure

play38:03

and in a typical SAS

play38:05

in environment right our goal should be

play38:08

to make sure that we deploy in across

play38:11

all these environments in a consistent

play38:13

fashion right

play38:15

um in a SAS environment you don't do

play38:17

like one of deployments that's an

play38:19

anti-pattern you just deploy everything

play38:22

to all the tenants normally and you try

play38:25

to keep your versions as much consistent

play38:27

as possible right so the mechanism that

play38:30

we came up to do that was that we had a

play38:33

build pipeline

play38:35

um so which this build pipeline was

play38:37

getting the source from the code combat

play38:40

um repository it was building it into an

play38:42

S3 uh any test you want to run you can

play38:44

run right here and then we were actually

play38:48

leveraging this table that we created as

play38:50

part of Canon onboarding itself and if

play38:53

you pay attention right basically what

play38:55

the start deployment uh code block is

play38:57

doing it's basically looping through

play38:59

this

play39:00

through this table and updating all the

play39:03

stacks in a consistent fashion so in

play39:06

other words

play39:06

you just you know get your source of

play39:10

truth from the code at one time you

play39:12

build it one time and then you just

play39:14

deploy across all this environment so

play39:16

this is a a concept which you can

play39:19

probably apply to any multi-tenant

play39:21

system

play39:22

um I mean in case of eks you have a

play39:25

little bit more sophisticated open

play39:27

source tools to do this but in case of

play39:29

serverless we built this build Pipeline

play39:32

and deployment pipeline concept which

play39:34

you can follow

play39:37

um there are more Concepts you know I

play39:39

can go deep into but um I'll probably

play39:41

maybe just stop

play39:43

um but just one one maybe

play39:45

maybe a couple of minutes on this Tenon

play39:47

whole routing mechanism right so now you

play39:49

have this whole concept of you know

play39:51

making sure that you route your tenants

play39:54

to the appropriate API API Gateway right

play39:57

so whatever resources for Mana for the

play40:00

tenant you want to make sure that you

play40:01

route and and the way the routing

play40:03

typically works is you have some sort of

play40:05

way of identifying tenants in the UI

play40:07

right what we have seen customers doing

play40:10

is they follow an approach called

play40:12

subdomain so sometimes tenant one dot

play40:16

SAS application.com 10 and

play40:18

2.application.com so they build some

play40:20

sort of you know sub domains to to kind

play40:22

of solve that challenge in our case we

play40:24

were just asking

play40:26

um the tenant to provide the tenant name

play40:29

um and then we had an API which

play40:31

basically took that tenant name and gave

play40:33

you back okay what API Gateway URL this

play40:36

tenant should be pointing to like what

play40:38

user pool this tenant should be really

play40:40

pointing to right and then we just

play40:42

leverage those settings to redirect to

play40:45

the relevant Cognito user pool

play40:47

and then to redirect to the relevant API

play40:51

right so this whole concept of routing

play40:52

is another kind of complex piece that

play40:55

you need to solve when you're building

play40:56

this whole multi-tenant hybrid kind of

play40:59

SAS application

play41:01

so this is how the final you know

play41:04

architecture look like eventually you

play41:06

have a CI CD pipeline which takes care

play41:08

of deploying across this whole

play41:10

multi-tenant environment I talked about

play41:12

all this different components already

play41:15

right and then your application services

play41:17

are now deployed in a hybrid model where

play41:20

you have pooled tenants and you have

play41:22

certain silos for certain tenants right

play41:25

okay so

play41:27

um there's a lot to a lot to cover here

play41:29

and there are a lot of concept which I

play41:31

talked about in last like 40 minutes

play41:34

um

play41:34

I I would really you know encourage and

play41:36

appreciate

play41:37

um if you want to you know follow some

play41:40

of the workshops that we have built

play41:42

around this so if you are trying to

play41:44

build a SAS application a multi-tenant

play41:46

application using serverless

play41:48

um I highly encourage you to

play41:51

um you know dive deep into the solution

play41:52

into this GitHub repository

play41:55

um and I think I think it you'll

play41:57

probably definitely definitely leverage

play41:58

and benefit a lot by following some of

play42:01

the best practices and and and and the

play42:03

guidance that we have provided right try

play42:04

to provide here

play42:05

all right thank you so much

play42:07

um and that's it from I said Brian I

play42:10

hope let's see if there's any questions

play42:13

there were definitely some questions and

play42:16

um and folks if you want to add some

play42:19

more questions we've got time to answer

play42:21

them but we did have some questions and

play42:24

I'm grateful too because I I followed

play42:27

everything but this is like

play42:29

a little bit above my pay grade so I'm

play42:32

glad for the question I'm like I knew

play42:34

I've dealt with some of these services

play42:35

and stuff inside AWS but never had to

play42:38

build a multi-tenant yeah SAS

play42:41

application even though I've worked for

play42:43

companies that have them but

play42:45

um but not actually done them myself

play42:46

okay so I'll start getting to these

play42:50

these questions

play42:51

um

play42:52

uh we've got one question here when

play42:54

using Lambda authorizer with Federated

play42:57

identity identity provider what is the

play42:59

best way to Cache the auth token for

play43:02

some time instead of authorizing on

play43:03

every request in a serverless way yeah

play43:06

so Lambda authorizer actually provides

play43:08

you caching it's an inbuilt feature uh

play43:11

which Lambda authorizer provides you all

play43:12

you have to do is just enable the

play43:15

caching you can cache in fact in our

play43:16

case we were caching for like five

play43:18

minutes so whenever a new request comes

play43:21

in based upon the jar token it will

play43:23

figure out you basically provide okay

play43:25

what's your caching mechanism or what

play43:27

what's the key you want to use for

play43:29

caching right so it's basically cash on

play43:31

the jaw token so it won't necessarily go

play43:33

and make that call every time it will

play43:35

just figure out that hey it's within

play43:37

that five minute range so I'll just

play43:38

cache it and just authorize this in this

play43:40

particular jaw token so it's a feature

play43:42

that's already built in yeah okay so

play43:44

basically they don't need to really do

play43:46

anything it's built in okay excellent

play43:48

that's well that's easy uh all right

play43:52

next question we've got

play43:55

um how much latency will be added for

play43:58

the additional STS assume role logic is

play44:01

the strategy to Cache it yeah that

play44:03

that's that's a great question and

play44:05

thanks for asking I mean um so I mean I

play44:09

ran some tests I think it was about like

play44:11

200 millisecond or something when the

play44:13

last time I ran some tests

play44:15

um and uh and for that reason we're

play44:17

actually leveraging Lambda authorizer to

play44:20

generate the STS credential and as I

play44:22

mentioned we are caching the Lambda

play44:23

authorizers as well another approach

play44:26

which you can take is you can

play44:28

you can generate the express credential

play44:31

inside your micro Services right so you

play44:32

can just take that whole STS concept and

play44:35

generate them inside the Lambda function

play44:36

itself

play44:38

um

play44:39

that that way

play44:41

um you don't have to but but the whole

play44:43

point of Doing inside a Lambda

play44:45

authorizer was to just cache it and

play44:48

avoid that latency but there is

play44:49

definitely a very very small latency

play44:51

that gets added typically we have we

play44:55

have seen you know customers not really

play44:56

you know bothering about that you know

play44:58

200 millisecond or whatever

play45:00

um actually it's even less than that I

play45:02

might have screwed up some numbers here

play45:04

but it's definitely in milliseconds

play45:06

okay okay so so not nothing but but not

play45:11

necessary something to be aware of

play45:12

honestly like you know if you have a

play45:13

very low latency application something

play45:15

you should you should be really

play45:16

concerned and available aware of and

play45:19

make sure you test with with the sdsm

play45:20

without the SDS and what Behavior you're

play45:23

you know seeing in application it's

play45:24

worth considering as as a way yeah

play45:28

excellent

play45:30

um okay so next question is

play45:33

uh this he says this is basically what

play45:36

we're doing at my current employer the

play45:38

one thing that it doesn't allow

play45:40

for us is the use of direct Integrations

play45:44

like appsync or step functions in things

play45:47

like asynchrist is there a way to limit

play45:49

the access of those Integrations and if

play45:52

not as as is this something AWS is think

play45:54

about

play45:57

um so yes I mean um

play46:00

you you are you are kind of limited in

play46:03

this in this model to introduce a Lambda

play46:05

function even for a basic credit

play46:06

functionality right in some way or the

play46:08

other

play46:09

um in case of appsync I think from what

play46:13

I can remember there is a way to do the

play46:16

direct integration as well

play46:19

um I don't remember on top of my head or

play46:21

how to do it I I did at one point uh

play46:23

maybe as a follow-up I can try to find

play46:25

what I did a long time back uh but but

play46:28

eventually

play46:30

eventually if you've been able direct

play46:31

integration you will have to

play46:34

um you know somehow generate and pass

play46:37

the access and secret key as part of the

play46:39

direct integration as well right which

play46:41

normally

play46:43

um also there's a way to do it again you

play46:45

have to you know build that inside your

play46:47

um

play46:48

inside your cloud formation so it's a

play46:50

complex solution which you know we can

play46:53

which I have worked out in past but my

play46:55

advice would be to leverage Lambda

play46:57

function just to avoid that complexity

play46:59

so the short answer is you know you'll

play47:01

be better off if you have a Lambda

play47:02

function in between and provide you much

play47:04

more flexibility

play47:05

okay

play47:06

okay

play47:08

um and then uh Jason commented that 200

play47:11

milliseconds sounds like you're going

play47:12

from region from a region that is not Us

play47:15

East one and going to the default USC

play47:17

one for the STS calls yeah again

play47:20

um I need to go back and check my

play47:22

numbers I mean um I would I would I

play47:24

would maybe run I run the test like a

play47:26

year ago honestly

play47:29

um and uh there was some definite there

play47:31

was a lag and yeah you're right I mean

play47:33

typically Between Us East one and maybe

play47:36

U.S West that's pretty pretty much the

play47:38

kind of latency there's definitely an

play47:40

overhead to add SDS token uh to generate

play47:43

an SS token but as I mentioned if you

play47:46

use a Lambda authorizer and you cache

play47:48

that that

play47:50

latency or that you know that latency

play47:53

becomes manageable right so because now

play47:54

you're not doing that on the every call

play47:56

but rather every five to ten minutes

play47:58

okay

play48:00

um okay we have one more question uh if

play48:03

anybody wants to throw a last minute but

play48:05

I think we have a couple more minutes

play48:07

um but if so if you have an additional

play48:09

question feel free to throw it in the

play48:10

chat or on the ask a question module

play48:13

um while we answer this this one here uh

play48:16

how can we make the dynamic policy to

play48:18

work with Dynamo single table design

play48:20

what would be the strategy for partition

play48:23

key for multi-tenant with single table

play48:25

design

play48:27

well I mean you you don't even have to

play48:30

worry about Dynamic policy for a single

play48:32

table right because as I mentioned you

play48:33

can just provide that in your execution

play48:36

role which table you want to access

play48:38

right so so basically you can just say

play48:40

that hey hey

play48:42

um

play48:42

so let me if I just go back right maybe

play48:44

I can just show you

play48:46

oh yeah sure I'll share your screen

play48:48

again oh okay

play48:51

Yeah so basically you don't need this

play48:53

whole condition block if it's if it's

play48:55

just a table level isolation right you

play48:58

can just say Okay tenant one I think I

play49:00

had a slide on that um

play49:03

all right this one right so basically

play49:05

you just associate the execution role

play49:07

with the Lambda function itself and you

play49:09

just say that okay you know this Lambda

play49:11

function is only required or is only

play49:13

allowed to access

play49:15

table one the standard one order table

play49:17

or order tenant one table right so

play49:18

there's no need to for you to find good

play49:21

access it's much simpler you just say

play49:23

that your Lambda execution role has

play49:26

access to access only this dynamodb

play49:28

table and and basically you are not even

play49:31

allowed to access any other table so

play49:33

it's all built as part of the Lambda

play49:35

execution rule itself maybe just to

play49:38

clarify there are like two two different

play49:39

concepts we are talking about here

play49:41

there's a concept of Lambda execution

play49:42

role so basically when you create a new

play49:45

Lambda function you have to tell okay

play49:46

hey what permissions this Lambda

play49:48

function has and that is governed by the

play49:50

Lambda execution rule so what I'm trying

play49:52

to say is that when you just you know

play49:54

provide that as part of the execution

play49:55

rule itself it's a much simpler model

play49:58

versus Dynamic policy is inside your

play50:01

Lambda function right it's inside when

play50:03

it's basically a runtime construct you

play50:06

can't apply that as part of the

play50:07

execution rule itself so

play50:10

it gets much simpler just because of the

play50:13

execution role in Asylum model actually

play50:17

okay

play50:19

um

play50:20

all right so I think that's all the

play50:22

questions we have I shared the GitHub

play50:24

repo because this what this is basically

play50:27

they can take this entire application

play50:30

and just modify it and build upon it and

play50:33

and deploy their own

play50:36

um yeah

play50:37

in fact um

play50:40

exactly if you share if you share the

play50:42

screen again

play50:44

yes

play50:46

you know I'll probably just you know

play50:48

yeah so this is a workshop of the link

play50:50

um I mentioned um so this Workshop

play50:53

actually do a good job in in breaking

play50:56

out

play50:57

into steps right so this is a

play50:58

complicated thing to understand and to

play51:01

you know absorb in in one go so this

play51:04

Workshop actually takes you through that

play51:05

whole journey you know it kind of first

play51:07

talks about like it talks about you know

play51:09

shared services it talks about how to

play51:12

add multi-tenancy

play51:13

then it talks about the dynamic policy

play51:15

then it applies to steering based

play51:17

concept and then tenant rotting and in

play51:20

fact recently we also added this um

play51:23

this lab 7 into this Workshop which

play51:26

actually talks about how you can

play51:27

attribute cost in a pool model right and

play51:31

all those links uh I did mentioned um

play51:35

here

play51:36

um at the end

play51:46

yeah Nancy was asking if we can paste

play51:49

those into the chat or something so that

play51:50

they yeah yeah

play51:52

if you if you I don't know how to get

play51:56

them off uh do you are you on the the

play51:58

crowdcast chat if you can paste them I

play52:00

can I can go there yeah

play52:03

sure okay so Nancy we'll get you those

play52:06

links

play52:07

um otherwise you can uh maybe even just

play52:09

uh screenshot this right now and save

play52:13

and pick them up there as well

play52:15

um so I in in an above if you send me I

play52:20

can actually might be worth if you if

play52:22

you don't mind sharing the slide deck

play52:24

and I'll post it with the presentation

play52:27

on the site as well

play52:30

um yeah I know you can't click them off

play52:31

the screen she mentioned but uh so we

play52:34

will we will share them as well uh well

play52:37

I I think that's that's it for our time

play52:40

I this was this is actually fabulous I I

play52:45

know there was a lot uh you covered a

play52:48

lot of stuff in a very short time and I

play52:50

appreciate you kind of working to cram

play52:52

all that in for our yeah sorry about

play52:54

that I know right now

play52:58

okay yeah I mean um yeah yeah please

play53:01

please follow the links and you'll be

play53:03

fine if you want to dive deep further

play53:06

okay okay I will so folks I will share

play53:09

those links um as soon as I have them as

play53:12

well

play53:13

um and I will post the the once

play53:16

Annabelle sends me uh if you go to

play53:17

cfe.dev and you go to this event I will

play53:20

actually post a link to the PDF as well