Firebase Security rules to restrict access on all paths but one?
up vote
0
down vote
favorite
Question:
For the different top-level firestore collections below, how to restrict access to all but one of the paths?
We are building a data schema in Firestore to support a chat app for teachers across multiple schools.
The top-level firestore collections include:
/siteAdminUsers/schools/schools/{schoolId}/teachers/schools/{schoolId}/chats
Below is the security rules setup we are trying now - where we check for:
- valid user auth
- expected value exists in userClaim variable
request.auth.token.chatFlatList
However, the read listener for /messages is being blocked.
Error message:
FirebaseError: [code=permission-denied]: Missing or insufficient permissions
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
match /schools/{schoolId}/chats/{discussionId}/messages {
allow write: if false;
allow read: if request.auth != null
&& request.auth.token != null
&& request.auth.token.chatFlatList.val().contains($discussionId);
}
}
Details
We are using cloud functions for all data read/write, so for almost every case we can just block all client access.
The one exception is for the chat discussions, where we need to set a snapshot listener in the mobile client to know when there are new messages.
Sub-collection notes:
At a school, there are discussion sessions for school staff (teachers, admins, etc)
/schools/{schoolId}/chats/{discussionId}
Where each discussion-document contains:
- list of participant teacher ids
- subcollection for actual messages where each document is an indivual posted message:
/schools/{schoolId}/chats/{discussionId}/messages
User Claim code from Cloud Function
Looking at the cloud function logs, we have verified that the userClaim is being set.
return firebaseAdmin
.auth()
.setCustomUserClaims(
uid, {
chatFlatList: 'id1 id2 id3'
}
);
UPDATE #1
Tried the following variation where rules skip/omit the check on userClaim and auth.token.
However, still same permission error.
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
match /schools/{schoolId}/chats/{discussionId}/messages {
allow write: if false;
allow read: if request.auth != null;
}
}
}
google-cloud-firestore google-cloud-functions firebase-security-rules
|
show 2 more comments
up vote
0
down vote
favorite
Question:
For the different top-level firestore collections below, how to restrict access to all but one of the paths?
We are building a data schema in Firestore to support a chat app for teachers across multiple schools.
The top-level firestore collections include:
/siteAdminUsers/schools/schools/{schoolId}/teachers/schools/{schoolId}/chats
Below is the security rules setup we are trying now - where we check for:
- valid user auth
- expected value exists in userClaim variable
request.auth.token.chatFlatList
However, the read listener for /messages is being blocked.
Error message:
FirebaseError: [code=permission-denied]: Missing or insufficient permissions
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
match /schools/{schoolId}/chats/{discussionId}/messages {
allow write: if false;
allow read: if request.auth != null
&& request.auth.token != null
&& request.auth.token.chatFlatList.val().contains($discussionId);
}
}
Details
We are using cloud functions for all data read/write, so for almost every case we can just block all client access.
The one exception is for the chat discussions, where we need to set a snapshot listener in the mobile client to know when there are new messages.
Sub-collection notes:
At a school, there are discussion sessions for school staff (teachers, admins, etc)
/schools/{schoolId}/chats/{discussionId}
Where each discussion-document contains:
- list of participant teacher ids
- subcollection for actual messages where each document is an indivual posted message:
/schools/{schoolId}/chats/{discussionId}/messages
User Claim code from Cloud Function
Looking at the cloud function logs, we have verified that the userClaim is being set.
return firebaseAdmin
.auth()
.setCustomUserClaims(
uid, {
chatFlatList: 'id1 id2 id3'
}
);
UPDATE #1
Tried the following variation where rules skip/omit the check on userClaim and auth.token.
However, still same permission error.
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
match /schools/{schoolId}/chats/{discussionId}/messages {
allow write: if false;
allow read: if request.auth != null;
}
}
}
google-cloud-firestore google-cloud-functions firebase-security-rules
Have you tried simply allowing all access to messages, just to see if the problem is specifically with the interpretation of chatFlatList?
– Doug Stevenson
Nov 13 at 3:26
@Doug, post is updated with listing for trying rules setup as you descibe. I was wondering - is it maybe that the main "global rule"match /{document=**}, somehow overwrites the custom rule for messages? I was trying to find something in the docs that explains if at least 1 rule is matched for true, then that is enough .. not sure if I missed that detail, but didn't see it. Thanks
– Gene Bo
Nov 13 at 3:39
You can reject the entire database like that, then allow specific parts. It's totally doable. You just can't allow some part of the database, then reject it later. Once allowed, always allowed for that user.
– Doug Stevenson
Nov 13 at 4:21
It sounds like I'm missing something - because I am trying to implement as you describe where first part rejects all, and the next part allows for a specific path. The above rules structure is still rejecting the specific path (listed in update #1) that I am trying to allow read access to. Is there some variation I can maybe try that you know to have worked for you .. either with ordering of the rules, or some different pattern cfg? If I can't figure this out - the back-up plan is to just run a poll thread on client every 15 seconds to call a cloud function asking for new messages. Thank you
– Gene Bo
Nov 13 at 17:16
Hi @Doug, tho I have a work-around to poll the server, I would like to understand this for security setups likely to be nec. down the road; and also since the poll-server option is not inline w/best practices. Next steps for me: a) Set 100-200 point bounty here to see about finding a solution, b) Look to hire a freelancer versed in security rules. Any suggestions are appreciated, thank you
– Gene Bo
Nov 15 at 2:15
|
show 2 more comments
up vote
0
down vote
favorite
up vote
0
down vote
favorite
Question:
For the different top-level firestore collections below, how to restrict access to all but one of the paths?
We are building a data schema in Firestore to support a chat app for teachers across multiple schools.
The top-level firestore collections include:
/siteAdminUsers/schools/schools/{schoolId}/teachers/schools/{schoolId}/chats
Below is the security rules setup we are trying now - where we check for:
- valid user auth
- expected value exists in userClaim variable
request.auth.token.chatFlatList
However, the read listener for /messages is being blocked.
Error message:
FirebaseError: [code=permission-denied]: Missing or insufficient permissions
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
match /schools/{schoolId}/chats/{discussionId}/messages {
allow write: if false;
allow read: if request.auth != null
&& request.auth.token != null
&& request.auth.token.chatFlatList.val().contains($discussionId);
}
}
Details
We are using cloud functions for all data read/write, so for almost every case we can just block all client access.
The one exception is for the chat discussions, where we need to set a snapshot listener in the mobile client to know when there are new messages.
Sub-collection notes:
At a school, there are discussion sessions for school staff (teachers, admins, etc)
/schools/{schoolId}/chats/{discussionId}
Where each discussion-document contains:
- list of participant teacher ids
- subcollection for actual messages where each document is an indivual posted message:
/schools/{schoolId}/chats/{discussionId}/messages
User Claim code from Cloud Function
Looking at the cloud function logs, we have verified that the userClaim is being set.
return firebaseAdmin
.auth()
.setCustomUserClaims(
uid, {
chatFlatList: 'id1 id2 id3'
}
);
UPDATE #1
Tried the following variation where rules skip/omit the check on userClaim and auth.token.
However, still same permission error.
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
match /schools/{schoolId}/chats/{discussionId}/messages {
allow write: if false;
allow read: if request.auth != null;
}
}
}
google-cloud-firestore google-cloud-functions firebase-security-rules
Question:
For the different top-level firestore collections below, how to restrict access to all but one of the paths?
We are building a data schema in Firestore to support a chat app for teachers across multiple schools.
The top-level firestore collections include:
/siteAdminUsers/schools/schools/{schoolId}/teachers/schools/{schoolId}/chats
Below is the security rules setup we are trying now - where we check for:
- valid user auth
- expected value exists in userClaim variable
request.auth.token.chatFlatList
However, the read listener for /messages is being blocked.
Error message:
FirebaseError: [code=permission-denied]: Missing or insufficient permissions
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
match /schools/{schoolId}/chats/{discussionId}/messages {
allow write: if false;
allow read: if request.auth != null
&& request.auth.token != null
&& request.auth.token.chatFlatList.val().contains($discussionId);
}
}
Details
We are using cloud functions for all data read/write, so for almost every case we can just block all client access.
The one exception is for the chat discussions, where we need to set a snapshot listener in the mobile client to know when there are new messages.
Sub-collection notes:
At a school, there are discussion sessions for school staff (teachers, admins, etc)
/schools/{schoolId}/chats/{discussionId}
Where each discussion-document contains:
- list of participant teacher ids
- subcollection for actual messages where each document is an indivual posted message:
/schools/{schoolId}/chats/{discussionId}/messages
User Claim code from Cloud Function
Looking at the cloud function logs, we have verified that the userClaim is being set.
return firebaseAdmin
.auth()
.setCustomUserClaims(
uid, {
chatFlatList: 'id1 id2 id3'
}
);
UPDATE #1
Tried the following variation where rules skip/omit the check on userClaim and auth.token.
However, still same permission error.
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
match /schools/{schoolId}/chats/{discussionId}/messages {
allow write: if false;
allow read: if request.auth != null;
}
}
}
google-cloud-firestore google-cloud-functions firebase-security-rules
google-cloud-firestore google-cloud-functions firebase-security-rules
edited Nov 13 at 3:37
asked Nov 13 at 3:13
Gene Bo
5,49244192
5,49244192
Have you tried simply allowing all access to messages, just to see if the problem is specifically with the interpretation of chatFlatList?
– Doug Stevenson
Nov 13 at 3:26
@Doug, post is updated with listing for trying rules setup as you descibe. I was wondering - is it maybe that the main "global rule"match /{document=**}, somehow overwrites the custom rule for messages? I was trying to find something in the docs that explains if at least 1 rule is matched for true, then that is enough .. not sure if I missed that detail, but didn't see it. Thanks
– Gene Bo
Nov 13 at 3:39
You can reject the entire database like that, then allow specific parts. It's totally doable. You just can't allow some part of the database, then reject it later. Once allowed, always allowed for that user.
– Doug Stevenson
Nov 13 at 4:21
It sounds like I'm missing something - because I am trying to implement as you describe where first part rejects all, and the next part allows for a specific path. The above rules structure is still rejecting the specific path (listed in update #1) that I am trying to allow read access to. Is there some variation I can maybe try that you know to have worked for you .. either with ordering of the rules, or some different pattern cfg? If I can't figure this out - the back-up plan is to just run a poll thread on client every 15 seconds to call a cloud function asking for new messages. Thank you
– Gene Bo
Nov 13 at 17:16
Hi @Doug, tho I have a work-around to poll the server, I would like to understand this for security setups likely to be nec. down the road; and also since the poll-server option is not inline w/best practices. Next steps for me: a) Set 100-200 point bounty here to see about finding a solution, b) Look to hire a freelancer versed in security rules. Any suggestions are appreciated, thank you
– Gene Bo
Nov 15 at 2:15
|
show 2 more comments
Have you tried simply allowing all access to messages, just to see if the problem is specifically with the interpretation of chatFlatList?
– Doug Stevenson
Nov 13 at 3:26
@Doug, post is updated with listing for trying rules setup as you descibe. I was wondering - is it maybe that the main "global rule"match /{document=**}, somehow overwrites the custom rule for messages? I was trying to find something in the docs that explains if at least 1 rule is matched for true, then that is enough .. not sure if I missed that detail, but didn't see it. Thanks
– Gene Bo
Nov 13 at 3:39
You can reject the entire database like that, then allow specific parts. It's totally doable. You just can't allow some part of the database, then reject it later. Once allowed, always allowed for that user.
– Doug Stevenson
Nov 13 at 4:21
It sounds like I'm missing something - because I am trying to implement as you describe where first part rejects all, and the next part allows for a specific path. The above rules structure is still rejecting the specific path (listed in update #1) that I am trying to allow read access to. Is there some variation I can maybe try that you know to have worked for you .. either with ordering of the rules, or some different pattern cfg? If I can't figure this out - the back-up plan is to just run a poll thread on client every 15 seconds to call a cloud function asking for new messages. Thank you
– Gene Bo
Nov 13 at 17:16
Hi @Doug, tho I have a work-around to poll the server, I would like to understand this for security setups likely to be nec. down the road; and also since the poll-server option is not inline w/best practices. Next steps for me: a) Set 100-200 point bounty here to see about finding a solution, b) Look to hire a freelancer versed in security rules. Any suggestions are appreciated, thank you
– Gene Bo
Nov 15 at 2:15
Have you tried simply allowing all access to messages, just to see if the problem is specifically with the interpretation of chatFlatList?
– Doug Stevenson
Nov 13 at 3:26
Have you tried simply allowing all access to messages, just to see if the problem is specifically with the interpretation of chatFlatList?
– Doug Stevenson
Nov 13 at 3:26
@Doug, post is updated with listing for trying rules setup as you descibe. I was wondering - is it maybe that the main "global rule"
match /{document=**} , somehow overwrites the custom rule for messages? I was trying to find something in the docs that explains if at least 1 rule is matched for true, then that is enough .. not sure if I missed that detail, but didn't see it. Thanks– Gene Bo
Nov 13 at 3:39
@Doug, post is updated with listing for trying rules setup as you descibe. I was wondering - is it maybe that the main "global rule"
match /{document=**} , somehow overwrites the custom rule for messages? I was trying to find something in the docs that explains if at least 1 rule is matched for true, then that is enough .. not sure if I missed that detail, but didn't see it. Thanks– Gene Bo
Nov 13 at 3:39
You can reject the entire database like that, then allow specific parts. It's totally doable. You just can't allow some part of the database, then reject it later. Once allowed, always allowed for that user.
– Doug Stevenson
Nov 13 at 4:21
You can reject the entire database like that, then allow specific parts. It's totally doable. You just can't allow some part of the database, then reject it later. Once allowed, always allowed for that user.
– Doug Stevenson
Nov 13 at 4:21
It sounds like I'm missing something - because I am trying to implement as you describe where first part rejects all, and the next part allows for a specific path. The above rules structure is still rejecting the specific path (listed in update #1) that I am trying to allow read access to. Is there some variation I can maybe try that you know to have worked for you .. either with ordering of the rules, or some different pattern cfg? If I can't figure this out - the back-up plan is to just run a poll thread on client every 15 seconds to call a cloud function asking for new messages. Thank you
– Gene Bo
Nov 13 at 17:16
It sounds like I'm missing something - because I am trying to implement as you describe where first part rejects all, and the next part allows for a specific path. The above rules structure is still rejecting the specific path (listed in update #1) that I am trying to allow read access to. Is there some variation I can maybe try that you know to have worked for you .. either with ordering of the rules, or some different pattern cfg? If I can't figure this out - the back-up plan is to just run a poll thread on client every 15 seconds to call a cloud function asking for new messages. Thank you
– Gene Bo
Nov 13 at 17:16
Hi @Doug, tho I have a work-around to poll the server, I would like to understand this for security setups likely to be nec. down the road; and also since the poll-server option is not inline w/best practices. Next steps for me: a) Set 100-200 point bounty here to see about finding a solution, b) Look to hire a freelancer versed in security rules. Any suggestions are appreciated, thank you
– Gene Bo
Nov 15 at 2:15
Hi @Doug, tho I have a work-around to poll the server, I would like to understand this for security setups likely to be nec. down the road; and also since the poll-server option is not inline w/best practices. Next steps for me: a) Set 100-200 point bounty here to see about finding a solution, b) Look to hire a freelancer versed in security rules. Any suggestions are appreciated, thank you
– Gene Bo
Nov 15 at 2:15
|
show 2 more comments
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53273250%2ffirebase-security-rules-to-restrict-access-on-all-paths-but-one%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Have you tried simply allowing all access to messages, just to see if the problem is specifically with the interpretation of chatFlatList?
– Doug Stevenson
Nov 13 at 3:26
@Doug, post is updated with listing for trying rules setup as you descibe. I was wondering - is it maybe that the main "global rule"
match /{document=**}, somehow overwrites the custom rule for messages? I was trying to find something in the docs that explains if at least 1 rule is matched for true, then that is enough .. not sure if I missed that detail, but didn't see it. Thanks– Gene Bo
Nov 13 at 3:39
You can reject the entire database like that, then allow specific parts. It's totally doable. You just can't allow some part of the database, then reject it later. Once allowed, always allowed for that user.
– Doug Stevenson
Nov 13 at 4:21
It sounds like I'm missing something - because I am trying to implement as you describe where first part rejects all, and the next part allows for a specific path. The above rules structure is still rejecting the specific path (listed in update #1) that I am trying to allow read access to. Is there some variation I can maybe try that you know to have worked for you .. either with ordering of the rules, or some different pattern cfg? If I can't figure this out - the back-up plan is to just run a poll thread on client every 15 seconds to call a cloud function asking for new messages. Thank you
– Gene Bo
Nov 13 at 17:16
Hi @Doug, tho I have a work-around to poll the server, I would like to understand this for security setups likely to be nec. down the road; and also since the poll-server option is not inline w/best practices. Next steps for me: a) Set 100-200 point bounty here to see about finding a solution, b) Look to hire a freelancer versed in security rules. Any suggestions are appreciated, thank you
– Gene Bo
Nov 15 at 2:15