45

This is my first foray into Firebase & nosql, I come from a SQL background.

Using Simple Login Security Email/Password, how do I limit access to data in Firebase? For example, some user will have access to create a business object (users, customers, categories, etc), others won't. Is there a way to attach a list of permissions to the "auth" variable?

acole76
  • 533
  • 1
  • 5
  • 8

3 Answers3

35

There isn't a way to attach permissions directly to the auth variable (or at least that doesn't seem to be an intended strategy). I'd recommend creating a collection of users organized by auth.uid and you can keep whatever kind of permission attributes you want in there, such that your security rules might something look like this (untested):

{
  "rules": {
    ".read": true,
    "users": {
      ".write": "root.child('users').child(auth.uid).child('role').val() == 'admin'"
    }
  }
}

Where role is an attribute belonging to all objects in your users collection.

UPDATE

See comment below:

"There isn't a way to attach permissions directly to the auth variable" This changed in 2017. You can now attach custom claims to an auth profile, which are available in security rules. See bojeil's answer and the Firebase documentation for custom claims. – Frank van Puffelen

hiattp
  • 2,326
  • 1
  • 20
  • 23
  • thanks for the response. Just so I am clear, you are suggesting that I add a boolean value to every user record that indicates whether they have access to the resource they are accessing. Is that correct? Would I need to create a similar rule for every type of business object (users, customers, categories, etc.)?. – acole76 Oct 22 '13 at 21:08
  • 3
    It's hard to know what exactly you'll need without knowing your app requirements, I'm justing trying to convey the general strategy for how you might manage this type of "permissioning" in Firebase. Depending on how you structure the actual data, you may or may not need to use that rule more than once. And you may or may not need a boolean for every user, maybe they just have a user `type` string, like `"admin"`, and you match to that. And maybe only "admins" need that attribute, because without it the privilege will fail by default. See what I mean? – hiattp Oct 22 '13 at 23:25
  • Great Explanation! @hiattp – mattc19 May 23 '17 at 14:51
  • This is perfect! just what I was looking for. Helped me greatly – Srini Oct 01 '17 at 23:02
  • 3
    "There isn't a way to attach permissions directly to the auth variable" This changed in 2017. You can now attach custom claims to an auth profile, which are available in security rules. See [bojeil's answer](https://stackoverflow.com/a/46457754) and the [Firebase documentation for custom claims](https://firebase.google.com/docs/auth/admin/custom-claims). – Frank van Puffelen Sep 23 '18 at 14:45
  • Though it seems like the 2017 update is worse in many ways than your solution. Your approach generalizes to managing the permissions themselves using permissions, while custom claims offers no solution. – user239558 Dec 24 '18 at 02:56
15

Firebase launched support for role based access on any user via custom user claims on the ID token: https://firebase.google.com/docs/auth/admin/custom-claims

You would define the admin access rule:

{
  "rules": {
    "adminContent": {
      ".read": "auth.token.admin === true",
      ".write": "auth.token.admin === true",
    }
  }
}

Set the user role with the Firebase Admin SDK:

// Set admin privilege on the user corresponding to uid.
admin.auth().setCustomUserClaims(uid, {admin: true}).then(() => {
  // The new custom claims will propagate to the user's ID token the
  // next time a new one is issued.
});

This will propagate to the corresponding user's ID token claims. You can force token refresh immediately after: user.getIdToken(true)

To parse it from the token on the client, you need to base64 decode the ID token's payload: https://firebase.google.com/docs/auth/admin/custom-claims#access_custom_claims_on_the_client

You can upgrade/downgrade users as needed. They also provided a programmatic way to list all users if you have recurring scripts to change a users' access levels: https://firebase.google.com/docs/auth/admin/manage-users#list_all_users

bojeil
  • 29,642
  • 4
  • 69
  • 76
9

Looking at this again a year later "Custom Tokens" may be a better option.

https://www.firebase.com/docs/security/guide/user-security.html#section-custom

Jamey McElveen
  • 18,135
  • 25
  • 89
  • 129