Ir para o conteúdo
DedicatedPHP Contato

Autorização verificável em PHP: permissões sem exceções

Transforme regras de negócio em políticas de acesso verificáveis: papéis, contexto, isolamento de dados, testes e auditoria em PHP.

Diagrama editorial de autorização em PHP que conecta papéis, permissões, contexto organizacional e recursos protegidos

O design de permissões e autorização em PHP não se resolve com uma tela em que são atribuídos perfis. O problema surge quando uma mesma ação depende de quem a executa, para qual organização trabalha, sobre qual dado atua e em que estado esse dado se encontra. Se essas condições estiverem distribuídas entre controladores, consultas, templates e validações de interface, o sistema acabará acumulando exceções difíceis de revisar.

O objetivo deve ser que cada decisão seja explícita, repetível e verificável: uma identidade tenta executar uma operação sobre um recurso dentro de um contexto, e uma política decide se é permitida. Essa abordagem transforma regras operacionais ambíguas em controles técnicos que produto, operações e desenvolvimento podem revisar em conjunto.

Separar identidade, autorização e escopo dos dados

Separar identidade, autorização e escopo dos dados — guía visual de DedicatedPHP

A autenticação responde quem é o usuário: sessão, credenciais, provedor de identidade ou token. A autorização responde o que essa identidade pode fazer. Não convém deduzir a segunda apenas a partir da primeira nem tratar ambas como uma única camada.

Um papel agrupa responsabilidades, como administrador de organização, agente de suporte ou aprovador. Uma permissão representa uma operação concreta, por exemplo invoice.read, invoice.approve ou member.invite. O escopo determina sobre quais recursos essa operação é válida: faturas de uma organização, processos de uma unidade ou registros próprios.

Essa distinção evita um erro frequente: conceder a permissão de leitura de faturas e assumir que isso permite ler qualquer fatura. A política ainda deve verificar se o recurso pertence à organização ativa, se o usuário tem a unidade correspondente atribuída e se o estado do recurso permite a ação solicitada.

Construir uma matriz de acesso a partir de operações

Antes de escolher classes ou pacotes, liste recursos e operações reais. Use verbos de negócio em vez de rótulos vagos como “gerenciar”: criar pedido, ver pedido, corrigir rascunho, aprovar pedido, cancelar pedido, exportar pedidos ou modificar membros.

Para cada operação, defina com a área de negócio quatro elementos:

  • O recurso e a ação protegida.
  • Os perfis que podem solicitá-la.
  • O escopo de dados aplicável: organização, unidade, proprietário, carteira ou atribuição.
  • As condições de contexto e estado: organização ativa, delegação vigente, horário operacional ou documento em rascunho.

A matriz resultante não é o código de autorização, mas uma especificação revisável. Além disso, obriga a identificar decisões pendentes. Se for indicado que o suporte pode “ver pedidos”, é necessário especificar se pode ver dados pessoais, documentos anexos, pedidos fechados ou informações de todas as organizações.

Preferir ações pequenas e estáveis

Uma ação ampla demais concentra privilégios e dificulta a aplicação do menor privilégio. Separar order.read de order.export, ou user.update de user.assign_role, permite conceder acesso de modo preciso. Tampouco convém criar uma permissão para cada caso pontual: se a diferença depender do recurso, geralmente é uma condição da política, e não um novo papel.

Escolher entre papéis, permissões, atributos e contexto

Os papéis simples funcionam quando há poucos perfis estáveis e as operações quase não dependem do dado. São uma boa porta de entrada, mas tornam-se frágeis se surgirem nomes como gerente_com_exportacao ou supervisor_apenas_unidade_norte. Essas combinações codificam exceções como perfis permanentes.

As permissões explícitas são adequadas para desacoplar responsabilidades de perfis e para atribuir capacidades de forma administrável. Os atributos servem quando a decisão depende de propriedades do sujeito, do recurso ou do ambiente: organização, unidade, classificação, proprietário, país ou nível de risco. As regras contextuais completam o modelo quando intervêm condições transitórias, como uma delegação ativa ou a fase de aprovação.

Na prática, um modelo híbrido costuma ser mais sustentável: os papéis concedem permissões base; uma política avalia atributos do usuário e do recurso; e o contexto fornece a organização selecionada ou o canal de operação. O papel não deve substituir a análise do dado.

Centralizar as políticas e filtrar dados desde a origem

Uma aplicação PHP precisa de um ponto coerente para expressar decisões. Ele pode se materializar em classes de política, serviços de autorização ou componentes equivalentes do framework escolhido. O importante é que os controladores solicitem uma decisão e que as views não sejam a única barreira.

if (!$authorizer->can($actor, 'order.approve', $order, $context)) {
    throw new AccessDeniedException();
}

A política deve receber somente os dados necessários para decidir: identidade, operação, recurso e contexto. Evite consultar variáveis globais ou depender implicitamente da rota atual; isso torna as regras difíceis de testar e reutilizar.

A verificação individual não basta em telas de listagem. Se uma consulta retornar pedidos de várias organizações e a interface ocultar alguns depois, uma exposição já terá ocorrido. Aplique o escopo no repositório ou na camada de consulta: filtre por organização autorizada, unidade permitida ou carteira atribuída antes de carregar os resultados. Para recursos por identificador, verifique tanto a operação quanto a pertença do recurso.

Estados e transições como parte da política

As operações sensíveis costumam depender do estado. Um aprovador pode aprovar um pedido pendente, mas não um cancelado nem um já aprovado. Modele a transição permitida de forma explícita e valide novamente no ponto que persiste a alteração. A interface pode desativar um botão para orientar, mas a política do servidor é o controle efetivo.

Evitar exceções permanentes e negações reveladoras

Papéis genéricos como “administrador” precisam de limites claros. Um administrador de uma organização não deveria se tornar automaticamente administrador da plataforma. Do mesmo modo, uma exceção como “pode editar este registro específico” deve ter proprietário, motivo, data de revisão ou expiração e rastreabilidade. Se ela se repetir, provavelmente falta uma regra de negócio ou um atributo do modelo.

As negações devem ser úteis sem revelar informações sensíveis. Para uma consulta direta a um recurso de outra pessoa, normalmente é preferível uma resposta indistinguível daquela em que o recurso não existe. Em uma ação sobre um recurso já visível, pode-se indicar que faltam permissões sem detalhar regras internas, atribuições ou atributos protegidos.

Registre ações sensíveis autorizadas e negadas quando agregarem valor operacional: alterações de papéis, exportações, aprovações, acessos delegados e modificações de configuração. A auditoria deve incluir ator, ação, recurso, organização ou contexto, momento e resultado. Não registre credenciais, tokens nem dados pessoais desnecessários.

Testar a autorização como uma propriedade do produto

Os testes de autorização devem cobrir decisões permitidas e negadas. Uma bateria mínima inclui: um usuário com permissão em sua organização; o mesmo usuário diante de outra organização; um usuário sem permissão; um recurso em um estado inválido; e uma mudança de contexto, como remover uma atribuição ou encerrar uma delegação.

Teste as políticas diretamente, pois oferecem diagnósticos precisos, e adicione testes de integração para confirmar que rotas, controladores, consultas e operações de escrita aplicam a decisão. As regressões mais perigosas são as de privilégio: adicionar um papel, uma rota ou uma otimização de consulta que amplie o acesso de forma involuntária.

  • Verifique que uma listagem não contém recursos fora do escopo.
  • Verifique que conhecer um identificador de terceiros não concede acesso.
  • Verifique que uma mudança de estado exige a política correspondente.
  • Verifique que remover uma permissão invalida a capacidade na solicitação seguinte.

Adotar o modelo em uma aplicação com regras dispersas

Não é necessário reescrever todo o sistema. Comece inventariando rotas, comandos, tarefas agendadas e pontos de exportação que alteram ou expõem dados. Priorize ações de alto impacto e recursos compartilhados entre organizações. Extraia uma política por domínio, cubra o comportamento atual com testes e corrija as regras que concedam mais acesso do que o previsto.

Depois, substitua verificações dispersas por chamadas ao serviço de autorização e mova a filtragem de escopo para as consultas. Revise periodicamente permissões sem uso, papéis com capacidades em excesso, delegações expiradas e exceções ativas. O design de permissões e autorização em PHP será sustentável quando uma nova funcionalidade puder responder, antes de ser desenvolvida, quem opera, sobre qual recurso, sob quais condições e com quais evidências isso foi verificado.

Checklist para cada novo módulo

Checklist para cada novo módulo — guía visual de DedicatedPHP
  • As operações de negócio e seus recursos estão definidos?
  • A matriz distingue permissão, escopo e condição de estado?
  • As políticas são aplicadas em leitura, escrita, exportação e processos não interativos?
  • As consultas filtram os dados antes de entregá-los à interface?
  • Existem testes de acesso permitido, negado e entre organizações?
  • As ações sensíveis deixam uma auditoria proporcional e segura?
Deseja aplicar essas ideias ao seu projeto?Vamos discutir sua plataforma PHP.
Veja os serviços relacionados