Hi everyone, I’m trying to build a prototype for a...
# help
t
Hi everyone, I’m trying to build a prototype for a “multi-tenant app” (let’s say a Shopify, something similar to seed.run) which might turn kinda complex, here are the main features: • Teams/ACL support: so you can create a team and invite members to manage or access the app (depending on permissions). • Each team (tenant) has it’s own list of items (let’s say products), store settings and so In my mind there is an app for the dashboard where the user can manage it’s team and the team can manage the items of the store and then there is a separated table for each store and their stuff. That said here are my questions: Do you think it makes sense to create an individual table for each store (+ also a dedicated bucket for each store’s assets)?; it make sense to me b/c that way I can have a better accuracy on the actual billing for each customer (team) Have you seen any example for these kind of situations? (I was just able to find a issue without any other reference: https://github.com/AnomalyInnovations/serverless-stack-com/issues/331) This is pretty much a complex scenario, right, but also I think it’s a common one so I just wanted to have thoughts on what would make more sense here for the SST and serverless approach.
k
If you are using dynamodb one limitation I can think of is the max 256 tables per account limit
What you could do to track tenants and usage is keep aggregations in a separate table and store the things you want to track there
Make sure to always include a tenant id on the hash keys also so you separate them at the partition level
t
@Kujtim Hoxha ouch, I wasn’t aware of that limit… then I guess a single table is the way to go no matter what.
k
I need to double check id it is a hard or soft limit (meaning it can be raised on your account if you request it)
Yeah you can increase it
t
Awesome 😄
k
One thing you could also do is instead of having one single table for every tenant you could group some tenants into one table and only have a dedicated table for a big tenant
The main thing I would suggest you do is do the right abstraction at the database layer that makes it easier for you to introduce these single table tenants later
t
that makes sense
g
You can keep the data in a single table and let the PK be the thing that segregate tenants data.. you can even use this: https://aws.amazon.com/blogs/aws/fine-grained-access-control-for-amazon-dynamodb/ I've used in my project and works great to make Fine-Grained Access Control...
so the IAM Policy would allow item interaction where the pk belong to your tenant
k
Oh that is awesome I need this
I did not know you can protect the access using PK
g
yep you can.. let me get a better doc
here
and if you authenticate users with cognito user pool and identity pool: works great!!!
t
@Gabriel Araújo that’s pretty cool, I wasn’t aware of how much you can restrict at IAM level on dynamodb, this is so interesting; so I guess my db would have some sort of partition where the PK would be the user and the ST would be the role+store (like: ADMIN#123 or SUPPORT#123) and then let IAM handle the access right?
k
@Gabriel Araújo thanks for sharing this this helps a lot
g
you can map your user to reader group that would map to reader role that has a policy that allows to interact with table x and only get item with this pk
then it would have to access dynamo with user credentials not the lambda credentails.. lambda -> sts to user -> call dynamo with user credentials
t
interesting, omg this is so awesome (and I like the fact of this “security” layer which users the user’s credentials itself to call dynamo
ty both for your help here, definitely a lot to learn and read about before moving forward but now I have a better idea where to look at and how to think about it
g
@Tonny (sstNerd) it really depends of your use case.. but: you need to use the pk to create groups of data... and create IAM policies that allow read/update/delete this groups of data.. this is only possible with pk since this is the only thing you have to explicit provide to dynamo
k
@Gabriel Araújo I did not check the docs since I am on my phone just wondering if you know if you can use ‘starts with’ condition on the PK
g
sure! let me get something i've used in my project
1 sec
Copy code
- Effect: Allow
    Action:
      - dynamodb:GetItem
      - dynamodb:Query
      - dynamodb:DescribeTable
    Resource: "arn:aws:dynamodb:*:*:table/${self:custom.serviceName}-TenantContent-${self:custom.currentStage}"
    Condition:
      "ForAllValues:StringLike":
        "dynamodb:LeadingKeys": "${<http://cognito-identity.amazonaws.com:aud|cognito-identity.amazonaws.com:aud>}"
in this case you need to use
ForAllValues:StringLike
IAM operator and your data must have the thing in the pk
k
Thanks
g
in my case i've used the identity pool id
but it can be any string
t
ty so much for this @Gabriel Araújo
g
@Gabriel Araújo do you know where a list of all the variable replacements that can be used are?
g
it can be any arbitrary value.. like a tenantKey for example... just remember to pass this policy as inline to sts when using arbitrary values with the actual value.. lets say:
Copy code
Condition:
      "ForAllValues:StringLike":
        "dynamodb:LeadingKeys": "my-tenant-key"
@Garret Harp 1 sec
Maybe an sst example for multi-tenant application would be great..
k
@Gabriel Araújo one last question 😅 how are you making the db interactions as the logged in user and not the lambda iam role?
g
it's a process called sts.. you assume the user role and aws will give you a pair of credentials..
k
Ok awesome I will need to read about that this seems very much needed I have a very similar scenario
g
basically you generate a credentials for the user role.. it has a max duration of 15 min.. you can pass in custom policies mention above or just use the role policy.. it will return a access_key and secret_key that you can instantiate aws-sdk and call any services as the "user"
I need to go now.. but this is good for a blog post.. maybe a good for the holidays! bye
k
Thanks for the help here, I will read it if you post it 😂
g