O Firebase oferece várias ferramentas para gerenciar suas Rules. Cada uma é útil em casos específicos e usa a mesma API de back-end para gerenciamento das regras de segurança do Firebase.
Seja qual for a ferramenta usada para invocá-la, a API de gerenciamento:
- ingere uma origem de regras: um conjunto de regras, normalmente um arquivo de código contendo instruções de regras Firebase Security Rules.
- armazena a origem ingerida como um conjunto de regras imutável;
- monitora a implantação de cada conjunto de regras em uma versão. Os serviços ativados para regras de segurança do Firebase pesquisam a versão de um projeto para avaliar cada solicitação de um recurso protegido;
- permite executar testes sintáticos e semânticos em um conjunto de regras.
Usar a CLI Firebase
Com a CLI Firebase, é possível fazer upload de origens locais e implantar versões. O Firebase Local Emulator Suite da CLI permite fazer testes locais completos das origens.
Usar a CLI permite que você gerencie suas regras utilizando o controle de versões com o código do aplicativo e implemente regras como parte do processo de implantação atual.
Gerar um arquivo de configuração
Ao configurar o projeto do Firebase usando a CLI Firebase, você cria
um arquivo de configuração .rules
no diretório do projeto. Use o seguinte
comando para começar a configurar o projeto do Firebase:
// Set up Firestore in your project directory, creates a .rules file firebase init firestore
// Set up Realtime Database in your project directory, creates a .rules file firebase init database
// Set up Storage in your project directory, creates a .rules file firebase init storage
Editar e atualizar as regras
Edite sua origem de regras diretamente no arquivo de configuração .rules
.
Verifique se todas as edições feitas na CLI do Firebase são refletidas no console Firebase ou se você faz atualizações constantemente usando o console Firebase ou a CLI do Firebase. Caso contrário, será possível substituir as atualizações feitas no console do Firebase.
Testar as atualizações
O Local Emulator Suite fornece emuladores para todos os produtos compatíveis com as regras de segurança. O mecanismo de regras de segurança de cada emulador executa a avaliação sintática e semântica das regras, excedendo o teste sintático oferecido pela API de gerenciamento de regras de segurança.
Se você estiver trabalhando com a CLI, o pacote será uma excelente ferramenta para testes de Firebase Security Rules. Use o Local Emulator Suite para testar as atualizações localmente e confirmar se as Rules do app exibem o comportamento desejado.
Implantar as atualizações
Depois de atualizar e testar o Rules, implante as origens na produção.
Para Cloud Firestore Security Rules, associe arquivos .rules
aos bancos de dados padrão e
nomeados adicionais analisando e atualizando o
arquivo firebase.json
.
Use os comandos a seguir para implantar seletivamente o Rules ou como parte do processo normal de implantação.
// Deploy rules for all databases configured in your firebase.json firebase deploy --only firestore:rules
// Deploy rules for the specified database configured in your firebase.json firebase deploy --only firestore:<databaseId>
// Deploy your .rules file firebase deploy --only database
// Deploy your .rules file firebase deploy --only storage
Use o console Firebase
Também é possível editar origens do Rules e implantá-las como versões no console Firebase. Os testes sintáticos são realizados à medida que você edita na IU do console Firebase, e os testes semânticos estão disponíveis no Laboratório de testes de regras.Rules
Editar e atualizar as regras
- Abra o console do Firebase e selecione o projeto.
- Em seguida, selecione Realtime Database, Cloud Firestore ou Storage na navegação do produto e clique em Regras para acessar o editor Rules.
- Edite suas regras diretamente no editor.
Testar as atualizações
Além de testar a sintaxe na interface do editor, é possível testar o comportamento semântico do Rules usando os recursos de armazenamento e banco de dados do seu projeto, diretamente no console do Firebase, pelo Laboratório de testes de Rules. Abra a tela Laboratório de testes de regras no editor Rules, modifique as configurações e clique em Executar. Procure a mensagem de confirmação na parte superior do editor.
Implantar as atualizações
Quando você achar que as atualizações foram implementadas conforme o esperado, clique em Publicar.
Usar o SDK Admin
É possível usar o Admin SDK para conjuntos de regras do Node.js. Com esse acesso programático, é possível:
- Implementar ferramentas, scripts, painéis e pipelines de CI/CD personalizados para gerenciar regras.
- Gerenciar regras com mais facilidade em vários projetos do Firebase.
Ao atualizar as regras de maneira programática, é muito importante evitar alterações indesejadas no controle de acesso do seu app. Escreva seu código Admin SDK com a segurança em primeiro lugar, principalmente ao atualizar ou implantar regras.
Outra coisa importante a ser lembrada é que as versões de Firebase Security Rules levam alguns minutos para serem propagadas por completo. Ao usar o Admin SDK para implantar regras, evite disputas em que o app dependa imediatamente de regras cuja implantação ainda não foi concluída. Se o caso de uso exigir atualizações frequentes para regras de controle de acesso, considere soluções que usam o Cloud Firestore, que foi projetado para reduzir disputas, apesar das atualizações frequentes.
Observe também estes limites:
- As regras precisam ser menores que 256 KiB de texto codificado em UTF-8 quando serializadas.
- Um projeto pode ter no máximo 2.500 conjuntos de regras implantados. Quando esse limite for atingido, você precisará excluir alguns conjuntos de regras antigos antes de criar novos.
Criar e implantar conjuntos de regras Cloud Storage ou Cloud Firestore
Um fluxo de trabalho típico para gerenciar regras de segurança com o Admin SDK pode incluir três etapas distintas:
- Criar uma origem de arquivo de regras (opcional)
- Criar um conjunto de regras
- Libere ou implante o novo conjunto de regras
O SDK fornece um método para combinar essas etapas em uma única chamada de API para regras de segurança Cloud Storage e Cloud Firestore. Exemplo:
const source = `service cloud.firestore {
match /databases/{database}/documents {
match /carts/{cartID} {
allow create: if request.auth != null && request.auth.uid == request.resource.data.ownerUID;
allow read, update, delete: if request.auth != null && request.auth.uid == resource.data.ownerUID;
}
}
}`;
// Alternatively, load rules from a file
// const fs = require('fs');
// const source = fs.readFileSync('path/to/firestore.rules', 'utf8');
await admin.securityRules().releaseFirestoreRulesetFromSource(source);
Esse mesmo padrão funciona para regras Cloud Storage com releaseFirestoreRulesetFromSource()
.
Como alternativa, é possível criar o arquivo de regras como um objeto na memória, criar o conjunto de regras e implantá-lo separadamente para ter um controle mais próximo desses eventos. Exemplo:
const rf = admin.securityRules().createRulesFileFromSource('firestore.rules', source);
const rs = await admin.securityRules().createRuleset(rf);
await admin.securityRules().releaseFirestoreRuleset(rs);
Atualizar conjuntos de regras Realtime Database
Para atualizar os conjuntos de regras Realtime Database com o Admin SDK, use os métodos getRules()
e
setRules()
do admin.database
. É possível recuperar conjuntos de regras no formato
JSON ou como uma string com comentários incluídos.
Para atualizar um conjunto de regras:
const source = `{
"rules": {
"scores": {
".indexOn": "score",
"$uid": {
".read": "$uid == auth.uid",
".write": "$uid == auth.uid"
}
}
}
}`;
await admin.database().setRules(source);
Gerenciar conjuntos de regras
Para ajudar a gerenciar grandes conjuntos de regras, o Admin SDK permite listar todas as regras
com admin.securityRules().listRulesetMetadata
. Exemplo:
const allRulesets = [];
let pageToken = null;
while (true) {
const result = await admin.securityRules().listRulesetMetadata(pageToken: pageToken);
allRulesets.push(...result.rulesets);
pageToken = result.nextPageToken;
if (!pageToken) {
break;
}
}
Para implantações muito grandes que atingem o limite de 2.500 regras ao longo do tempo, é possível criar uma lógica para excluir as regras mais antigas em um ciclo de tempo fixo. Por exemplo, para excluir todos os conjuntos de regras implantados por mais de 30 dias:
const thirtyDays = new Date(Date.now() - THIRTY_DAYS_IN_MILLIS);
const promises = [];
allRulesets.forEach((rs) => {
if (new Date(rs.createTime) < thirtyDays) {
promises.push(admin.securityRules().deleteRuleset(rs.name));
}
});
await Promise.all(promises);
console.log(`Deleted ${promises.length} rulesets.`);
Usar a API REST
As ferramentas descritas acima são adequadas para vários fluxos de trabalho, incluindo o gerenciamento de Firebase Security Rules para vários bancos de dados Cloud Firestore no seu projeto, mas talvez você queira gerenciar e implantar Firebase Security Rules usando a própria API de gerenciamento. A API de gerenciamento oferece a maior flexibilidade.
Observe também estes limites:
- As regras precisam ser menores que 256 KiB de texto codificado em UTF-8 quando serializadas.
- Um projeto pode ter no máximo 2.500 conjuntos de regras implantados. Quando esse limite for atingido, você precisará excluir alguns conjuntos de regras antigos antes de criar novos.
Criar e implantar conjuntos de regras Cloud Firestore ou Cloud Storage com REST
Os exemplos nesta seção usam o Rules do Firestore, mas também se aplicam a Cloud Storage Rules.
Os exemplos também usam cURL para fazer chamadas de API. As etapas para configurar e transmitir tokens de autenticação são omitidas. Teste essa API usando o API Explorer integrado à documentação de referência.
As etapas típicas para criar e implantar um conjunto de regras usando a API de gerenciamento são as seguintes:
- Criar origens de arquivos de regras
- Criar um conjunto de regras
- Lançar (implantar) o novo conjunto de regras.
Criar uma origem
Vamos supor que você esteja trabalhando no seu projeto do Firebase secure_commerce
e queira
implantar o Cloud Firestore Rules bloqueado em um banco de dados no
projeto chamado east_store
.
É possível implementar essas regras em um arquivo
firestore.rules
.
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
}
}
Criar um conjunto de regras
Agora, gere uma impressão digital codificada em base64 para esse arquivo. Em seguida, use a
origem nesse arquivo para preencher o payload necessário para criar um conjunto de regras com
a chamada REST projects.rulesets.create
. Aqui, use o comando cat
para inserir
o conteúdo de firestore.rules
no payload REST.
Para rastrear e associar isso ao seu banco de dados east_store
, defina attachment_point
como east_store
.
curl -X POST -d '{
"source": {
"files": [
{
"content": "' $(cat storage.rules) '",
"name": "firestore.rules",
"fingerprint": <sha fingerprint>
},
"attachment_point": "firestore.googleapis.com/databases/east_store"
]
}
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets'
A API retorna uma resposta de validação e um nome de conjunto de regras, por exemplo,
projects/secure_commerce/rulesets/uuid123
.
Lançar (implantar) um conjunto de regras
Se o conjunto de regras for válido, a etapa final será implantar o novo conjunto em uma versão nomeada.
curl -X POST -d '{
"name": "projects/secure_commerce/releases/cloud.firestore/east_store" ,
"rulesetName": "projects/secure_commerce/rulesets/uuid123"
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/releases'
As versões do Firebase Security Rules levam alguns minutos para serem totalmente propagadas. Ao usar a API REST de gerenciamento para fazer a implantação, evite as disputas em que o app depende imediatamente das regras cuja implantação ainda não está concluída.
Atualizar conjuntos de regras Realtime Database com REST
O Realtime Database oferece a própria interface REST para gerenciar Rules. Consulte Como gerenciar Realtime Database Rules do Firebase usando a API REST.
Gerenciar conjuntos de regras com REST
Para ajudar a gerenciar implantações de regras grandes, além de um método REST para criar conjuntos de regras e versões, a API de gerenciamento fornece métodos para:
- listar, recuperar e excluir conjuntos de regras
- listar, receber e excluir versões de regras
Para implantações muito grandes que atingem o limite de 2.500 regras ao longo do tempo, é possível
criar uma lógica para excluir as regras mais antigas em um ciclo de tempo fixo. Por exemplo, para
excluir todos os conjuntos de regras implantados por mais de 30 dias, chame o método
projects.rulesets.list
, analise a lista JSON de objetos Ruleset
nas chaves createTime
e chame project.rulesets.delete
nos
conjuntos de regras correspondentes por ruleset_id
.
Testar as atualizações com REST
Por fim, a API de gerenciamento permite executar testes sintáticos e semânticos nos recursos Cloud Firestore e Cloud Storage nos projetos de produção.
O teste com este componente da API consiste em:
- Definir um objeto JSON
TestSuite
para representar um conjunto de objetosTestCase
- Enviar o
TestSuite
- Analisar os objetos
TestResult
retornados
Vamos definir um objeto TestSuite
com um único TestCase
em um
arquivo testcase.json
. Neste exemplo, enviamos a origem
da linguagem Rules in-line com o payload REST, junto com o conjunto de testes para executar
essas regras. Especificamos uma expectativa de avaliação de regras e a solicitação
do cliente que será usada para testar o conjunto de regras. Também é possível especificar
quão completo será o relatório de teste, usando o valor "FULL" para indicar os resultados de todas
as expressões de linguagem Rules que devem ser incluídas no relatório, incluindo
expressões que não corresponderam à solicitação.
{ "source": { "files": [ { "name": "firestore.rules", "content": "service cloud.firestore { match /databases/{database}/documents { match /users/{userId}{ allow read: if (request.auth.uid == userId); } function doc(subpath) { return get(/databases/$(database)/documents/$(subpath)).data; } function isAccountOwner(accountId) { return request.auth.uid == accountId || doc(/users/$(request.auth.uid)).accountId == accountId; } match /licenses/{accountId} { allow read: if isAccountOwner(accountId); } } }" } ] }, "testSuite": { "testCases": [ { "expectation": "ALLOW", "request": { "auth": {"uid": "123"}, "path": "/databases/(default)/documents/licenses/abcd", "method": "get"}, "functionMocks": [ { "function": "get", "args": [{"exact_value": "/databases/(default)/documents/users/123"}], "result": {"value": {"data": {"accountId": "abcd"}}} } ] } ] } }
Podemos enviar este TestSuite
para avaliação com o método
projects.test
.
curl -X POST -d '{
' $(cat testcase.json) '
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets/uuid123:test'
O TestReport
retornado (contendo o status de teste SUCCESS/FAILURE, listas de
mensagens de depuração, listas de expressões de regras visitadas e os relatórios de avaliação)
confirmaria com o status SUCCESS que o acesso foi permitido corretamente.
Gerenciar permissões de Cloud Storage Security Rules entre serviços
Se você criar Cloud Storage Security Rules que use o conteúdo do documento Cloud Firestore para avaliar as condições de segurança, será solicitado no console do Firebase ou na CLI do Firebase que você ative as permissões para conectar os dois produtos.
Se você decidir desativar esse tipo de segurança entre serviços, faça o seguinte:
Antes de desativar o recurso, edite as regras, removendo todas as instruções que usam funções Rules para acessar Cloud Firestore. Caso contrário, depois que o recurso for desativado, as avaliações de Rules farão com que as solicitações do Storage falhem.
Use a página IAM no Console do Google Cloud para excluir o papel "Agente de serviço do Firestore para regras do Firebase" seguindo o guia do Cloud para revogar papéis.
Você precisará reativar o recurso na próxima vez que salvar as regras de vários serviços na CLI Firebase ou no console Firebase.