Auth based on Relationships - aws-amplify

I have a team with many tasks and tasks can have many submissions.
I want team admins to see all tasks for their team only and all submissions for all tasks of their team.
I can do a lambda authenticator (allow: custom) and query DynamoDB. Is this supported for DataStore?
I can implement through resolvers following this pattern here: https://dabit3.medium.com/intro-to-aws-appsync-pipeline-functions-3df87ceddac1. Is this recommended?
I can propagate admins and have a ownerField = [] on them. This works but if an admin is removed from the team I have to go and update all the rows async in a lambda
Finally I can create an auth group and propagate the group name to all the tasks and submissions. However there is a limitation on the number of groups (10,000) I think? so I can only have 10000 teams. Although would like to have a list of subscribers potentially on a task, etc..
How would you recommend I do this?

Related

How to model many-to-many relationship between users and tenants on Google Identity Platform?

In some B2B applications that employ multi-tenancy, a single user can belong to multiple tenants. Slack, for example, allows the same user (email+password combination) to view all the workspaces (tenants) they belong to and alternate between them seamlessly. As users switch workspaces, the application switches context to the selected workspace, loading workspace-specific entities such as channels, messages, and threads.
Is it possible to do something similar with Google Identity Platform (GIP)?
I understand that in multi-tenancy in GIP, all users are scoped to zero or one tenants. If a person needs to belong to 2 tenants, 2 users must be created - each with their unique uid. This is not a big deal when users sign up with Federated Identity Providers. They see a consent screen twice, confirm, and the application can apply some logic to know they are the same person. For example, it can hash their email address, and link the two tenants to it.
But if users log in with email+password, such approach requires users to maintain two passwords for the same service, diminishing the user experience.
I imagine that one solution is to disable multi-tenancy and store the user-to-tenant links in Firestore, or perhaps as a custom claim so that Firestore Security Rules checks don't require an extra read on every request. However, this might make it harder to enforce different authentication requirements for different tenants. For example, a user may switch context to a tenant that requires 2FA as part of their policy, and it could be advantageous to have GIP manage that part.
Are there better approaches for such a scenario?

Firestore, Firebase Authentication, and Firestore Rules with multiple business entities

I am trying to see if Firestore is the right tool for my need.
I am designing a multi-tenanted system using Firestore for scalability and security. Can this be done correctly using just Firestore, Firebase authentication, and Firebase rules to handle all CRUD operations? The idea behind the entities is:
System > Account > Business > Customer
Roles at each entity level would be:
Administrator, Manager, Support, Report, Unauthenticated (the customer)
Accounts have businesses and businesses have customers. Customers would not need to authenticate but read a specific document (designated by the business) and then create their own specific new document. They could create multiple documents but there would be time-based volume thresholds (no DOS!).
I believe Firestore Rules would work great if it didn’t have the Account as a superset that has multiple of the Businesses.
Is it possible to create a system like this with just Firestore, authentication, and rules alone? I want to keep things simple but also not pound a nail using a pair of pliers.
Thanks in advance for the insight!
With a set of well defined Custom Claims you can indeed use Firestore for such a multi-tenant system.
In your security rules, you would combined the different claims, depending on the access role.
In particular you should:
Check the user has the correct claims e.g. auth.token.businessId == "xyz", auth.token.role == "Support"
Check that the user is writing/reading a doc that corresponds to his entity, e.g. allow create: if request.auth.uid == userId && request.resource.data.businessId == auth.token.businessId
Don't forget that Security Rules are not filters, so in each query executed by a user, you need to add the different ids from his/her custom claims (businessId, accountId, etc...). Either by mimicking your entities tree with (sub)collections, or by using some where() clauses in the queries.
Note that since Customers would not need to authenticate, they could potentially read and create documents from/for others businesses, if they have the ID of these businesses (i.e. the DocumentReferences).
You will probably have to manage a set of claims for each user (role, account, business, ... ), which can become complex, so you might be interested by the following article which explains how to create an Admin module for managing Firebase users access and roles.

Create firebase project when user log in to SaaS application

I have seen a firebase api in which you can create firebase projects and it occurred to me for example, when a user wants to counter a SaaS, make it easier for me to create a project and connect it to their SaaS but I have the following questions:
If there are supposed to be limits to creating firebase projects in a google account, will there be a time when databases can no longer be created for new users?
If the above is true, how can this be solved?
I have seen that you can ask for more projects, but how many can I have?
I know that with firestore, I can model data and only in a database have all the information, but for example, each user may have special requirements in their system and also provide security and information saving operations that would be impossible if all information is in a single database.
Thanks for the help.
EDIT
"How many projects can you have as a developer?" Yes, that's what I mean, having all the user bases in a single firebase google account. For example, on a web page, the user wants to pay for the application, with firebase admin and google cloud functions, I can automatically create a project and have all the databases in a google account. And what I want to know is if you can have multiple databases. I have seen that you can ask google to give you permission to host several projects but, for example, can you have more than 100 projects or even 1000? (I may never have reached that number, but in that case, I would like to know the limits that can be reached).
Edit 2
This first structure I have all the documents in a "universal" collection and I identify them with an id to know the user who used it.
But the second structure seems to me more organized and clean, in addition to the fact that users at no time need to share information among others. I have read that having nested collections is not good but over the years and the progress that firestore has had, this is no longer or was a problem only that the limitation is that you can only have up to 100 collections anidades but I never think to reach that quantity.
Inside of list, have all products for that user, because inside of document, only can have 1 mb of data and download 1 mb and is not the best option.
in the firestore documentation I see that it does not reveal other problems, it only says that it is difficult to delete the subcollection, but I do not allow users to do that and if I need to delete the subcollections, with the Google Cloud functions i can do it.
So, the second structure is more intuitive for me, but is the best option for that? or actually firestore is not good for this strcucutre?

What is the best practice for a multi-tenant app with Collection Group Queries in Firestore?

What is the best practice for multi-tenant app collection group queries? For example query all invoices for a tenant's customers
/tenant/1/customer/2/invoices
If I create a collection group index called invoices, and I want to ensure that I can get all invoices for tenant 1, how do I do this easily?
I tried setting up some security rules to prevent from querying over the tenants but it still threw Access denied errors since it was still querying across tenants. What would the correct firestore rules look like
Firebase projects are not very well suited to multi-tenant apps. It's recommended that you create different projects for each tenant. This will save you a lot of problems in the future.
If you absolutely must have multi-tenancy on a single project, your current database structure does not support it very well for collection group queries. Collection group queries always query every collection of a given name, with no exceptions. You can't use security rules to filter the results, because rules are not filters. Filtering can only come from the client, and be confirmed by security rules. With your current structure, you would need to store the ID of the tenant in each document that you intend to query with a collection group query, and have the client use that as a filter for results.

Delivering Firebase Cloud Messaging notifications to specific Firebase Users

this is a bit of a composite question, I'll try my best to separate the various parts even if they all have a common intent.
Common intent
Having a clear way of delivering notifications about posts regarding specific topics to Firebase Users (and not simply to application instances).
I have tried various methods, and I can't find a definitive answer about which one is the best one.
Method 1 - Relying only on the database
Each Firebase User has its own document in the Firestore at users/{userId}
This document contains two collections: tokens and interests.
The token collection contains a list of documents which have FCM tokens as one of their fields. Each time an user signs in the application or FirebaseInstanceIDService.onTokenRefresh() is called, the collection is updated to add the new token.
The interest collection contains a list of interests which simply are strings and are used as tags for posts. This collection has a mirror as interests/{interestId}/users/{userId} showing all the users interested in something. (This is kept updated and synchronised via a Cloud Function)
When a new post is created under a specific interest, I can get a list of all the users interested and then get their tokens from their document. Finally, I send a notification to each individual token.
Problems
This solution is not elegant (this isn't that big of a problem)
With the new GDPR rules I fear I might not be allowed to save tokens
directly on the Database
If the user signs out when he's offline, the
token isn't removed from his document, and the new user receives
notifications for the old interests.
Should I keep track of what the current token is and update it each time an user signs in ignoring FirebaseInstanceIDService.onTokenRefresh()? Else only the user signed in when the service is called would update the database.
Method 2 - Using FCM topic subscriptions
This should be the best option for me, but I can't understand how to make it work with multiple users on the same phone (always one at a time though)
The way I would handle this is still have the users/{userId}/interests collection, removing users/{userId}/tokens and interests/{interestId}/users, and subscribe/unsubscribe from the various topics as the user signs in and out.
Problems
What happens if the user signs out when he's offline? There is no way to retrieve the current subscriptions and remove each one, potentially resulting in conflicting topics subscriptions.
Thank you very much for your time

Resources