pythonfirebasefirebase-authenticationfirebase-storagefirebase-security

Firebase Storage Rules with Custom Claims


I am unable to get Firebase Storage work with custom rules and using custom claims.

In my Python Admin panel, I do the following to create the user and assign a claim client_id:

# Standard Auth
import firebase_admin
from firebase_admin import db, storage, auth
cred   = firebase_admin.credentials.Certificate('path_to_cert_json')
app    = firebase_admin.initialize_app(cred, 'config')
bucket = storage.bucket(app=app)

# Create User
auth.create_user(email=email) 

# Create custom claims
auth.set_custom_user_claims(uid, {'client_id': client_id})

Then for Firebase rules, I try to allow the user to only read (or download) files when the file is in a subfolder with the client_id:

File structure on storage:

/{environment}/{client_id}/other_folders_and_files

I set the following storage rules:

service firebase.storage {
  match /b/{bucket}/o {
    match /{environment}/{client_id}/{allPaths=**} {
      allow read: if request.auth.token.client_id == client_id
    }
  }
}

But that gives me an error that Permission is denied.

What am I doing wrong?

Note:


Solution

  • If I'm not wrong, you are using this incorrectly. Should be:

    service firebase.storage {
      match /b/{bucket}/o {
        match /{environment}/{client_id}/{allPaths=**} {
          allow read: if request.auth.uid == client_id
        }
      }
    }
    

    The token returns others objects, like:

    So for you to be able to compare the user Id you must use request.auth.uid. This way will compare the client's client_id. If you want to take a look at the docs, is everything about the request.auth.

    Edit

    In case you want your own custom token, like: request.auth.token.client_id, you need to do that with this code in Python:

    uid = 'some-uid'
    additional_claims = {
        'client_id': your_custom_client_id
    }
    
    custom_token = auth.create_custom_token(uid, additional_claims)
    

    Then you can use in your storage rules:

    service firebase.storage {
      match /b/{bucket}/o {
        match /{environment}/{client_id}/{allPaths=**} {
          allow read: if request.auth.token.client_id == client_id
        }
      }
    }
    

    See the docs