Search code examples
firebasegoogle-cloud-firestorefirebase-security

Firebase Cloud Storage: can I test if an authenticated user can read an object based on the rules?


I'm going to be mirroring my Cloud Storage bucket to another Object Store, and want to only make publicly accessible objects that Cloud Storage would allow any unauthenticated user to read.

I'd like to, when given an object path to an object in Cloud Storage, determine if the object is publicly accessible (the check would be happening in a server context that has access to firebase admin).

What are the options here? Is there some way to run a test request through existing rules? Or would I need to GET (or HEAD?) the object using fetch w/o auth to determine if it's accessible? I could access the rules directly and manually parse them, but that feels really fragile.

Maybe storing some info in metadata where I tag the level of access unauthenticated users should have, and tie that into the metadata rules one can write for cloud storage?

Anyhow, curious if there is an existing pattern for this. Thanks in advance!


Solution

  • I believe you are interested in the projects.test method from the REST API. You would construct a test case with an expectation of ALLOW. Your code may look something like this :

    {
      "testSuite": {
        "testCases": [
          {
            "expectation": "ALLOW",
            "request": {
              "path": "/b/myapp.appspot.com/o/folder/obj_id",
              "method": "get",
              "auth": null,
              "time": "2022-11-30T23:30:08.199Z",
              "params": {}
            },
            "functionMocks": [],
            "pathEncoding": "PLAIN",
            "expressionReportLevel": "VISITED"
          }
        ]
      },
      "source": {
        "files": [
          {
            "name": "simulator.rules",
            "content": "rules_version = '2';\nservice firebase.storage {\n  match /b/{bucket}/o {\n    match /{allPaths=**} {\n      allow read, write: if\n          request.time < timestamp.date(2022, 12, 30);\n    }\n  }\n}"
          }
        ]
      }
    }
    

    The test results would then contain an array of results with a state containing whether or not the test succeeded or failed:

    On Success

    {
      "testResults": [
        {
          "state": "SUCCESS",
    ...
    

    On Failure

    {
      "testResults": [
        {
          "state": "FAILURE",
    ...
    

    I would just use the admin sdk to lookup your security rules for the source JSON file beforehand or I would cache it and update it in your function.