Setting permissions on Apigee BAAS - apigee

What's the best way to set permissions on objects in Apigee BAAS entities, collections in such a way that Users can edit what they create, and others can read them? There might be a case for Admins to be able to edit everything as well.
I asked a similar question here Securing apigee baas that was more around securing the app id/secret which would be needed to make the call to update permissions, but I was wondering if there is any best practice around doing this sort of thing from a mobile application.
My initial thought would still be the service callout (not sure how Apigee-127 which was mentioned in the previous question would be any different to a service callout directly to the BAAS as to me 127 looks like I'm just writing my apis in Node.js rather than using the edge console), but I don't know if there is an easier way in terms of securing all entities, in specific collections ,created by specific users? I guess I could add a created by column which I could check from an app perspective, but this wouldn't stop someone from potentially hitting the BAAS directly and retrieving this info unless permissions are also set at an entity level requiring a user access token.
Is it possible to secure the BAAS in such a way that only calls from Edge can hit the BAAS url?

(Disclaimer: I have not tried this myself but here is a suggestion.)
API BaaS Automatically sets the path segment to the UUID of the currently authenticated user when $user is used. For example, if you sent a request with a valid access token for a user with UUID bd397ea1-a71c-3249-8a4c-62fd53c78ce7, the path /users/${user} would be interpreted as /users/bd397ea1-a71c-3249-8a4c-62fd53c78ce7, assigning the permission only to that user entity.
In this way, through your application, you can set permission for each user, and each object as soon as the objects are created from your application. Assuming you have the user authenticated, of course.
Ref: http://apigee.com/docs/api-baas/content/using-permissions

Related

Sending extra (authentication) data with firestore request

Similar questions (eg. this) have already been asked and answered in negative. I'd like to if any alternatives exist.
I am developing an application where users can collaboratively edit a document. I don't want to force every user to login. I would like to allow users with a link to be able to edit a document (similar to what Google Docs allows). I was planning to share a token in the link which when presented would grant write access. I would have stored the tokens in a separate collection and matched them. But as per previous answers this is not possible and a security issue.
I don't consider it a security concern (for my purposes). The token is like a pre-shared key. Whoever presents the key is allowed access. If the owner thinks that the key is compromised, he can revoke the same. Kindly help me with a way to achieve this. I'm also curious to know how other apps like Google docs achieve this.
As Mentioned by #Dharmaraj,
In Firebase security rules, you have 3 pieces of information, namely the path, the data and the token. Except from those three you can't pass additional information in a security rule.
Cloud Functions would be a better fit here, given the flexibility. Additionally, with Cloud Functions you'd not be forced to authenticate users, and still be able to connect to Firestore if needed.

different types of user management on react-native

I'm new to react native. I am trying to develop an application that uses firebase user authentication. But there is something I can think of. For example, 2 users have registered to my application but I want to show extra information to the first user according to a condition.
How can I separate these two?
Where exactly should I manage this condition?
The question is not super clear as to what issue you are trying to tackle so I apologize if I am inferring incorrectly.
I use MongoDB personally with a Node/Express backend for user data and haven't used Firebase myself but I'm sure you can do the same things with it. I'll be speaking in Mongo terminology but again I'm sure you can do the same with Firebase and at the least this will give a good idea of the thought process.
I have a UserSchema that holds all the user information. When logged in the client app would get this information to be used on the frontend after authentication.
Assuming you are only displaying "extra" information that doesn't need additional privilege you can just pull in the users data stored in firebase and handle the display of this extra info with logic on your frontend client.
If its extra privilege you need to setup firebase to look at the user data that is authenticating and only serve back information if they have the proper privileges.
Also important to note, you should ensure that when you are updating user information from client -> firebase backend you should ensure that you can only update specific user fields via read/write authentication on firebase.
Hope this gives a little better idea on how this process might look. I'll let someone who has used firebase specifically add tech specifics.

Firestore security rules in auth less apps

I've developed an app which relies on Firestore for storing some user's data. This app doesn't have any login mechanism, as it uses the device UUID as identifier; we're not managing any sensitive data, btw.
I'm getting daily warnings from Firestore regarding the absence of security rules in my database, but as long as I don't have any login mechanism and my users need to both read and write from it, I can't see any way for implementing a useful security rule.
Is there any pattern I could follow in this situation? Is there any way to create a security rule for allowing to only read and write data created by the same user without any user authentication?
Thanks in advance
It sounds like you want to identify the user, but then without authentication. My guess is that you want to identify them, without requiring them to provide credentials.
If that is the case, you're looking for Firebase's anonymous authentication provider, which assigns a unique, unspoofable ID to each app instance. Signing in anonymously takes very little code, for example for Android it's:
FirebaseAuth.getInstance().signInAnonymously();
After this call completes, the user has an ID that you can then use in your security rules to identify the data from this user.

Extending Firebase Users

I am currently building a multi-platform web application and I'm currently busy with the authentication of users. I'm using vue on the client-side and django and the backend with postgres as the db.
I thought I would try out using firebase's authentication as it would speed up the process as well as take care of various issues like security etc. I have now come across a bit of a problem:
I need to add extra fields the user (gender, address etc.)
I need to set user roles (admin, manager etc.)
I am aware about some kind of way to set user roles but not really sure. In terms of extending the user in my mind I have two ideas:
Either I use the UID from firebase as a identifier to an extended user class
in my backend db. But that kinda defeats the purpose of speed.
Use Firestore - not sure how I would go about doing this though.
plz help
I have written a blog and made a video on how you can use custom claims to assign roles to your users. Essentially, you apply custom claims on a secure backend like inside of Cloud Functions, and these can be used to control access to Firebase backend features like Cloud Firestore and the Realtime Database. You can also check out the Firebase guide for more information.
As for additional data about a user like gender and addresses, that should be stored in Cloud Firestore, the Realtime Database, or whatever database you choose to use. It is not information that you constantly need when accessing a User object.

Understanding the Firebase and purpose of google cloud functions

Let's say I'm developing app like Instagram: for iOS, Android and Web. I decided to use Google Firebase as it really seems to simplify the work.
The features user needs in the app are:
Authorization/Registration
Uploading photos
Searching for other people, following them and see their photos
I come from traditional "own-backend" development where I do need to setup a server, create database and finally write the API to let the frontend retrieve the data from the server. That's the reason why it's unclear to me how it all works in Firebase.
So the question is how can I create such app:
Should I create my own API with cloud functions? Or it's ok to work with the database directly from the client-side?
If I work with the database directly why do I need cloud functions? Should I use them?
Sorry for such silly questions, but it is really hard to get from scratch.
The main difference between Firebase and the traditional setup you describe is that with Firebase, as far as the app developer is concerned, the client has direct access to the database, without the need for an intermediate custom API layer. Firebase provides SDKs in various languages that you would typically use to fetch the data you need / commit data updates.
You also have admin SDKs that you can use server-side, but these are meant for you to run some custom business logic - such as analytics, caching in an external service, for exemple - not for you to implement a data fetching API layer.
This has 2 important consequences:
You must define security rules to control who is allowed to read/write at what paths in your database. These security rules are defined at the project level, and rely on the authenticated user (using Firebase Authentication). Typically, if you store the user profile at the path users/$userId, you would define a rule saying that this node can be written to only if the authenticated user has an id of $userId.
You must structure your data in a way that makes it easily readable - without the need for complex database operations such as JOINs that are not supported by Firebase (you do have some limited querying options tough).
These 2 points allow you to skip the 2 main roles of traditional APIs: validating access and fetching/formatting the data.
Cloud functions allow you to react to data changes. Let's say everytime a new user is created, you want to send him a Welcome email: you could define a cloud function sending this email everytime a new node is appended to the users path. They allow you to run the code you would typically run server-side when writes happen, so they can have a very broad range of use-cases: side-effects (such as sending an email), caching data in an external service, caching data within Firebase for easier reads, analytics, etc..
You don't really need a server, you can access the database directly from the client, as long as your users are authenticated and you have defined reasonable security rules on Firebase.
In your use case you could, for example, use cloud functions to create a thumbnail when someone uploads a photo (Firebase Cloud Functions has ImageMagick included for that), or to denormalize your data so your application is faster, or to generate logs. So, basically you can use them whenever you need to do some server side processing when something changes on your database or storage. But I find cloud functions hard to develop and debug, and there are alternatives such as creating a Node application that subscribes to real time changes in your data and processes it. The downside is that you need to host it outside Firebase.
My answer is definitely NOT complete or professional, but here are the reasons why I choose Cloud Functions
Performance
You mentioned that you're writing an instagram-like mobile device app, then I assume that people can comment on others' pictures, as well as view those comments. How would you like to download comments from database and display them on users' devices? I mean, there could be hundreds, maybe thousands of comments on 1 post, you'll need to paginate your results. Why not let the server do all the hard work, free up users' devices and wait for the results? This doesn't seem like a lot better, but let's face it, if your app is incredibly successful, you'll have millions of users, millions of comments that you need to deal with, server will do those hard jobs way better than a mobile phone.
Security
If your project is small, then it's true that you won't worry about performance, but what about security? If you do everything on client side, you're basically allowing every device to connect to your database, meaning that every device can read from/write into your database. Once a malicious user have found out your database url, all he has to do is to
firebase.database().ref(...).remove();
With 1 line of code, you'll lose all your data. Okay, if you say, then I'll just come up with some good security rules like the one below:
This means that for each post, only the owner of that post can make any changes to it or read from it, other people are forbidden to do anything. It's good, but not realistic. People are supposed to be able to comment on the post, that's modifying the post, this rule will not apply to the situation. But again, if you let everybody read/write, it's not safe again. Then, why not just make .read and .write false, like this:
It's 100% safe, because nobody can do anything about anything in your database. Then, you write an API to do all the operations to your database. API limits the operations that can be done to your database. And you have experience in writing APIs, I'm sure you can do something to make your API strong in terms of security, for example, if a user wants to delete a post that he created, in your deletePost API, you're supposed to authenticate the user first. This way, 'nobody' can cause any damage to your database.

Resources