5

I would like to send some info to Firestore database (Firebase), preferably in key-value pairs (but not necessarily), so that it can use it to evaluate access in their rules (both when reading and writing).

However, I don't want this info to be part of the path.

For example, suppose I had some passParameters method:

DocumentReference docRef = 
      db.collection("cities")
        .document("SF")
        .passParameters("abc", 123);

Then I could access this info when writing rules, like so:

service cloud.firestore {
  match /databases/{database}/documents/cities/SF/ {
    allow read, write: if request.parameters.abc == 123;
  }
}

Please note, the above is just an example. Real-life uses cases are more complicated. In other words, don't pay too much attention to the example itself, but answer the more generic question: Is there any way to pass info to the Security Rules which is not part of the path?

Marcelo Glasberg
  • 29,013
  • 23
  • 109
  • 133
  • 1
    did you end up finding a solution for this? I'm trying to implement something similar but my users don't need to be authenticated. Security not being important for this use case either – SebastianG Mar 04 '20 at 12:20
  • @MichaelB Firestore rules are only important for security. They don't filter the results. They can only deny access. – Marcelo Glasberg Mar 08 '20 at 20:59
  • 1
    I'm not trying to filter the results though, just require a parameter that I can programatically attach to requests to firebase, without users being authenticated -- hence cannot use custom clains in the auth token. – SebastianG Mar 09 '20 at 13:33

2 Answers2

1

You can send such parameters using custom tokens. Include those values as claims in the custom token, and use that token in your client when sending request to firestore (or signin).

This link explains how to- 1) create custom tokens, 2) include custom claims in those tokens, and 3) access those claims in the security rules.

You can have a cloud function to generate that custom token with custom claims for a specific user.

If the information you want to pass to firebase as parameter changes frequently, then this is going to be a cloud function call everytime you want to change the parameter value you are passing- so a bit costly. But if parameter tend to change less frequently (like- some role or special privilege that the user have), then this solution should work perfect and that's one of the primary benefits of custom token.

Even though it is not as simple as your example expectation snippet, still this I believe is one way to achieve what you want.

AsifM
  • 680
  • 9
  • 21
-1

That's not supported. It wouldn't be a very "secure" security rule if the client could just specify whatever security parameters it wants with a query. That's really no different than allowing a client to pass a plaintext password that gives someone access to something. I would expect that sort of information to be discovered by an attacker.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • 1
    It's not meant as security, but as performance hints. For a simple example, suppose I have a ordered list of 100000 users allowed to get some resource. I have some security rule which reads the request.auth.uid of some user and checks all 100000 users to see if he's on that list. If the client know its location on that list he could pass its index as a hint to the security list engine. – Marcelo Glasberg Mar 05 '18 at 16:44
  • 1
    Another example: Suppose there are 5 resources that can be checked to give access for some specific user, and any of them would suffice. That forces the Security engine to get all 5 resources (this will take time and cost money). If the cliente knows which resource contains the necessary info for the authorization, he could indicate, in a parameter, which resource should be checked by the security engine. – Marcelo Glasberg Mar 05 '18 at 16:49
  • 1
    Another example: Suppose Cloud Functions processes some request, and needs some more info to work (some info which is not secure), then the function could read these parameters from the request. – Marcelo Glasberg Mar 05 '18 at 17:03
  • If you need to implement logic on the backend driven by parameters, just use a Cloud Functions HTTP trigger. – Doug Stevenson Mar 05 '18 at 17:57
  • 1
    same as passing `Authorization` header or `Cookie` header or any key/token for that matter. If the client got it from a reliable source (back end) server then it will be a secure mechanism – Blue Bot May 10 '18 at 19:43