Skip to content

Breaking changes — administração global e alcance cross-tenant (ADR 0007) ​

Épico 986. Companion do ADR 0007, que registra por que cada mudança foi feita. Aqui fica o que muda no seu ambiente.

Contrato HTTP para o cliente: v1-http-contract-migration. Modelo de trilhos e parametrização de perfis: admin-scoping-guide.

Resumo em uma tela ​

#MudançaQuem sente
1Users.AllowCrossTenantAccess deixou de existirninguém perde acesso — ver §1
2Assumir o contexto de um tenant exige vínculo UserTenantautomação que mandava X-Tenant-ID arbitrário
3switch:any-group-tenant foi removidaquem trocava de tenant por herança de grupo
4A role SystemAdmin passou a existir; a Admin da plataforma mudou de conteúdocliente/automação que identifica role pelo nome
5Revogar permissão de role de sistema do catálogo responde 409quem editava GroupAdmin/Visitor/SystemAdmin por API
6Teto de menor privilégio ao conceder permissão de plataforma a uma roleAdmin de tenant que compunha roles com admin:system

Nenhum relogin forçado. Nenhuma migração deste épico bumpa token_version — ver §7.


1. Users.AllowCrossTenantAccess deixou de existir ​

A coluna, a propriedade de domínio, GrantCrossTenantAccess / RevokeCrossTenantAccess, os dois eventos e a entrada de cache foram removidos. O alcance cross-tenant passa a ser decidido só pela permissão: admin:system, manage:all-users ou manage:all-tenants.

Ninguém perde acesso. Quem alcançava /admin/* tinha a flag e a permissão — a permissão basta. Quem tinha só a flag nunca alcançou nada.

O que passa a funcionar: conceder manage:all-users ou manage:all-tenants pela API de roles é o procedimento inteiro. Não há mais um UPDATE no banco a lembrar depois — que era, até aqui, o único caminho existente para criar um segundo administrador global. O scripts/auth/grant-cross-tenant-access.sql foi removido junto.

Se você tem scripts ou dashboards que leem a coluna, eles quebram: a coluna não existe mais no schema.

2. Assumir o contexto de um tenant exige vínculo UserTenant ​

Vale para todo mundo, inclusive quem tem admin:system. O middleware faz uma pergunta só: existe vínculo UserTenant ativo no tenant nomeado? Nenhuma permissão responde por ela.

Alcançar dados de outros tenants (o trilho /admin/*, o filtro do EF suspenso) e ser um tenant são perguntas separadas, com portões separados. A primeira é permissão; a segunda é vínculo.

Quem sente: automações que mandavam um X-Tenant-ID arbitrário com o token do admin do seed. Elas passam a receber 403. A correção é criar o vínculo — e só; não há permissão que substitua.

O header X-Tenant-ID e a query tenantId continuam existindo, e continuam sendo lidos apenas quando o token não traz tenant_id (token global, o seletor de tenant). O fluxo de seleção de tenant não mudou.

3. switch:any-group-tenant foi removida ​

POST /auth/switch-tenant para um tenant sem vínculo agora responde 403 TENANT_FORBIDDEN no próprio switch, em vez de emitir um token que falharia na requisição seguinte.

A permissão saiu do catálogo e do template GroupAdmin, que caiu de 5 para 4 permissões (read:group-tenants, read:group-analytics, read:group-data, manage:child-tenants).

Ninguém perde capacidade real. O caminho removido produzia um token que já não servia para nada: só o handler do switch honrava a permissão, enquanto o middleware continuava exigindo vínculo — a troca era aceita e toda requisição seguinte respondia 403.

A leitura consolidada não muda. ?scope=group continua resolvendo o direito no tenant do grupo (ADR 0006, G4), e os dois gates seguem intactos.

4. A role SystemAdmin passou a existir ​

AntesDepois
Roles do tenant plataformaAdmin (wildcard), Visitor, GroupAdminSystemAdmin (wildcard), Admin (13 granulares), Visitor, GroupAdmin
Roles de um tenant comumAdmin, Visitor, GroupAdmininalterado
Role do admin@local.comAdminSystemAdmin
Permissões efetivas do operador do seedadmin:systeminalteradas — admin:system

SystemAdmin só nasce no tenant plataforma e carrega admin:system sozinha. A Admin do tenant plataforma virou uma Admin comum: as mesmas 13 granulares de qualquer outro tenant.

Quem referencia role por nome em cliente ou automação precisa ajustar. O operador da plataforma não está mais na role chamada Admin. Um código que procura Admin para achar o super-admin passa a achar um administrador de tenant.

Não há migração de dados. A AuthInitialMigration foi regenerada e já nasce no estado final — a role, seu grant, o Admin da plataforma com as 13 granulares e o UserRole do admin@local.com apontando para SystemAdmin. Bancos anteriores à consolidação das migrations do GrydAuth não são alcançáveis e são recriados; a base recriada nasce correta pelo seed.

5. Revogar permissão de role de sistema responde 409 ​

A proteção deixou de comparar o literal "Admin" e passou a ser derivada do catálogo. Cobre agora toda role que o catálogo possui.

OperaçãoAntesDepois
DELETE /roles/{id}/permissions/{permId} numa Admin de sistema409 CONFLICT409 CONFLICT
idem em SystemAdmin, GroupAdmin ou Visitor de sistemasucesso409 CONFLICT
idem numa role que o tenant criousucessosucesso
PUT /roles/{id} reconciliando permissões de role do catálogofalhava só para Adminfalha para qualquer role do catálogo

Conceder (AssignPermission) não ganhou simetria: é o método pelo qual o seed e o bootstrap convergem uma role para o template, e uma guarda ali proibiria a plataforma de fazer o próprio trabalho.

6. Teto de menor privilégio ao conceder permissão a uma role ​

OperaçãoAntesDepois
POST /roles/{id}/permissions/{permId} com permissão de alcance de plataforma, por caller que não a possui200403 ROLE_ASSIGNMENT_ESCALATION_BLOCKED
idem pelo PUT /roles/{id}200403
as duas, com permissão de alcance de tenant200200 — inalterado
as duas, por caller com admin:system200200 — inalterado
DELETE /roles/{id}/permissions/{permId}—inalterado, sem teto

O teto cobre apenas as permissões que o catálogo declara PermissionReach.Platform: admin:system, manage:all-users e manage:all-tenants. Permissão que o próprio tenant cria para o negócio dele — product:create e afins — o Admin compõe livremente nas roles dele.

Por que isto entrou junto: enquanto a flag da §1 existia, pôr admin:system numa role era um ato de meio efeito. Com a permissão bastando sozinha, e com o endpoint gated apenas por update:roles (que está nas 13 granulares de todo Admin de tenant), o mesmo ato passaria a produzir um administrador global. O teto é a contrapartida da §1.


7. Nenhum relogin forçado ​

Nenhuma migração deste épico bumpa token_version. Isso corrige o que o backlog do épico afirmava:

  • a migração que dropou a coluna não bumpa: a coluna nunca foi claim, então nenhum token vivo carrega um valor dela;
  • a migração que removeu switch:any-group-tenant não bumpa: depois dela, nada no código lê a string, então uma claim velha não autoriza nada;
  • a migração de dados do split SystemAdmin × Admin não existe — a base nasce no estado final.

Tokens emitidos antes do deploy continuam válidos até expirarem. Os eventos normais que afetam autorização (mudança de role, de permissão, de vínculo) seguem invalidando como sempre.

8. O que não está no checklist deste release ​

Duas coisas que o backlog do épico previa e que deixaram de existir. Registradas aqui porque a ausência delas é a informação:

Não há migração de dados a rodar manualmente em homologação. O backlog registrava que TenantAdminPermissionDemoter e GroupScopePermissionMigrator só rodam sob ApplyGrydAuthMigrationsAsync, chamada pelo template do host apenas em IsDevelopment() — e que por isso um ambiente com ASPNETCORE_ENVIRONMENT ≠ Development estaria com admin:system em toda role Admin. Os dois migradores foram removidos, com scripts e runbooks. O gatilho de cada um era um banco provisionado antes de uma mudança de catálogo, e a consolidação das migrations do GrydAuth tornou esses bancos inalcançáveis: a base é recriada e nasce correta pelo seed. Não há o que rodar, e não há ninguém para lembrar de rodar.

Não há janela de migração compartilhada a coordenar. O backlog pedia que as USs 1.4 e 3.4 entrassem na mesma janela para não cobrar dois ciclos de relogin. Ver §7: nenhuma das duas bumpa token_version, e a 3.4 não existe.


9. Checklist de deploy ​

  1. Aplicar as migrations. Bancos anteriores à consolidação do GrydAuth não sobem — recrie.
  2. Conferir se alguma automação sua manda X-Tenant-ID de um tenant onde a conta de serviço não tem vínculo (§2). Se manda, crie o vínculo antes do deploy.
  3. Conferir se algum cliente ou automação identifica o operador da plataforma pelo nome da role Admin (§4). Se identifica, troque para SystemAdmin.
  4. Conferir se alguma rotina revoga permissão de GroupAdmin, Visitor ou SystemAdmin por API (§5) — passa a receber 409.
  5. Conferir se alguma rotina de provisionamento anexa admin:system / manage:all-* a roles usando credencial que não possui a permissão (§6) — passa a receber 403.
  6. Nada a fazer sobre sessões: não há relogin forçado (§7).

Released under the MIT License.