Tenancy
Uma instância do SlotBattle serve vários casinos ao mesmo tempo. Um tenant é um casino: as próprias batalhas, a própria allowlist de jogos, as próprias credenciais, o próprio endpoint de webhook. Você é um tenant na instância da plataforma.
O que é do tenant e o que é da plataforma
Essa divisão define a multi-tenancy no SlotBattle. Confira antes de prometer aos jogadores algo que a instância não pode entregar.
| É do tenant | É da plataforma (a instância) |
|---|---|
| Batalhas e assentos | A chave de assinatura de token de viewer |
| Allowlist de jogos | As três janelas de lobby |
| Credenciais SoftSwiss do backend | Configuração de e-mail |
| Endpoint e segredo do webhook de resultado | O gravador e o segredo do callback dele |
| Chaves de API e seus escopos | Storage, CDN, banco, Redis |
| Usuários de console e seus papéis |
Você pode mudar tudo na coluna da esquerda e nada na da direita. Uma janela de lobby diferente é um pedido à plataforma, não uma configuração sua.
Veja O que o host controla.
Como um tenant é identificado numa requisição
Duas superfícies, dois mecanismos, sem sobreposição.
A API S2S deriva o tenant da chave de API. Não há header de tenant nem campo de tenant para enviar: respostas e webhooks ecoam o id, e nada o aceita como entrada.
Um id de tenant lido de um payload transforma toda rota de recurso numa leitura cross-tenant para qualquer um disposto a editar um campo JSON. Derivá-lo da credencial torna essa classe de bug irrepresentável.
O console admin carrega o tenant ativo num header X-Tenant-Id, ao lado do cookie de
sessão. É um header, e não um claim no token, para que um operador com acesso a vários casinos
possa trocar entre eles sem se reautenticar. A associação é checada em toda requisição, então o
header declara uma intenção, e não um direito.
Leitura cross-tenant responde 404
Pedir uma batalha que pertence a outro casino retorna 404 Not Found, a mesma resposta de pedir uma batalha que não existe.
Um 403 confirmaria que a batalha existe, transformando um erro de permissão num oráculo de
enumeração: sonde ids, e os que responderem 403 são reais. Toda rota com escopo de batalha
carrega a batalha e checa a propriedade antes de mutar qualquer coisa, então uma escrita
cross-tenant não pode surtir efeito e depois ser recusada.
Um tenant suspenso é a exceção e recebe um 403. O chamador é legítimo, então nomear o
motivo é o correto.
Onde vivem as credenciais de um tenant
Dois lugares, resolvidos numa ordem fixa.
Documentos de settings, por tenant, editáveis pelo console:
| Categoria | Escopo | Guarda |
|---|---|---|
softswiss | Tenant | As credenciais de backend daquele casino |
webhook | Tenant | O endpoint de resultado e o segredo de assinatura daquele casino |
lobby | Plataforma | As três janelas de lobby |
As credenciais da própria plataforma são o fallback, e não são suas para mudar. Numa
instância em que cada casino traz as suas, o fallback fica vazio, e é por isso que um documento
softswiss ausente aparece como sessões de bot emitidas sob o id de casino errado, e não como
erro.
Três regras de resolução que evitam vazamento de credencial
Um documento completo vence; um vazio cai para o ambiente.
Um grupo de credencial é tudo ou nada. Preencher a sua URL de backend e deixar o token de auth em branco é recusado na escrita, enquanto ainda há um operador presente para corrigir. Pela metade, ele mandaria a credencial da plataforma para o seu endpoint.
Falha de resolução é erro, nunca fallback. Se a leitura de settings falhar, ou um segredo armazenado não puder ser decifrado, a operação falha. Cair para o fallback deixaria uma falha transitória de banco apresentar a credencial da plataforma sob a identidade de um casino.
Ler um documento de settings responde "<campo>Set": true|false em vez do valor. Um corpo
enviado que omite um segredo deixa o armazenado intacto, porque o cliente não teria como tê-lo
recebido. Tratar campo ausente como "limpe isto" faria o Salvar apagar uma credencial que
funciona.
Settings salvos são cacheados brevemente e invalidados explicitamente na escrita. Só com TTL, um salvamento do console ficaria invisível até a entrada expirar: o banco correto, o sistema em execução ainda na credencial antiga, e nada reportando erro.
A allowlist no nível da instância
Separada da tabela de tenants, SLOTBATTLE_TENANTS lista quais ids de tenant um processo vai
servir. Ela não carrega credencial e não faz autorização; é uma lista de associação. Um tenant
ausente dela é desconhecido para aquele processo mesmo que a linha no banco exista.
Allowlists de jogos
Cada tenant tem uma allowlist de jogos, e o endpoint de catálogo retorna só os liberados.
Não significa "todos os jogos". Um tenant recém-criado sem nada liberado vê zero jogos e toda criação de batalha falha, o que se parece com integração quebrada. Liberar jogos faz parte do onboarding.
A tela de jogos do console responde o catálogo inteiro com um booleano por jogo, porque uma tela limitada aos jogos liberados não poderia ser usada para liberar um novo.
Próximo
- Chaves e credenciais: as credenciais e como elas rotacionam
- O que o host controla: a mesma divisão, vista do seu lado
- Autenticação: a chave de API no fio