Saltar al contenido
DedicatedPHP Contactar

Autorización verificable en PHP: permisos sin excepciones

Convierta reglas de negocio en políticas de acceso comprobables: roles, contexto, aislamiento de datos, pruebas y auditoría en PHP.

Diagrama editorial de autorización en PHP que conecta roles, permisos, contexto organizativo y recursos protegidos

El diseño de permisos y autorización en PHP no se resuelve con una pantalla donde se asignan perfiles. El problema aparece cuando una misma acción depende de quién la ejecuta, para qué organización trabaja, sobre qué dato actúa y en qué estado se encuentra ese dato. Si esas condiciones viven repartidas entre controladores, consultas, plantillas y validaciones de interfaz, el sistema termina acumulando excepciones difíciles de revisar.

El objetivo debe ser que cada decisión sea explícita, repetible y verificable: una identidad intenta ejecutar una operación sobre un recurso dentro de un contexto, y una política decide si se permite. Este enfoque transforma reglas operativas ambiguas en controles técnicos que producto, operaciones y desarrollo pueden revisar conjuntamente.

Separar identidad, autorización y alcance de datos

Separar identidad, autorización y alcance de datos — guía visual de DedicatedPHP

La autenticación responde a quién es el usuario: sesión, credenciales, proveedor de identidad o token. La autorización responde a qué puede hacer esa identidad. No conviene deducir la segunda sólo a partir de la primera ni tratar ambas como una única capa.

Un rol agrupa responsabilidades, como administrador de organización, agente de soporte o aprobador. Un permiso representa una operación concreta, por ejemplo invoice.read, invoice.approve o member.invite. El alcance determina sobre cuáles recursos vale esa operación: facturas de una organización, expedientes de una unidad o registros propios.

Esta distinción evita un error frecuente: otorgar el permiso de lectura de facturas y asumir que ello permite leer cualquier factura. La política aún debe comprobar si el recurso pertenece a la organización activa, si el usuario tiene asignada la unidad correspondiente y si el estado del recurso admite la acción solicitada.

Construir una matriz de acceso a partir de operaciones

Antes de elegir clases o paquetes, enumere recursos y operaciones reales. Use verbos de negocio en lugar de etiquetas vagas como “gestionar”: crear pedido, ver pedido, corregir borrador, aprobar pedido, cancelar pedido, exportar pedidos o modificar miembros.

Para cada operación, acuerde con negocio cuatro elementos:

  • El recurso y la acción protegida.
  • Los perfiles que pueden solicitarla.
  • El alcance de datos aplicable: organización, unidad, propietario, cartera o asignación.
  • Las condiciones de contexto y estado: organización activa, delegación vigente, horario operativo o documento en borrador.

La matriz resultante no es el código de autorización, sino una especificación revisable. Además, obliga a detectar decisiones pendientes. Si se indica que soporte puede “ver pedidos”, hay que concretar si puede ver datos personales, documentos adjuntos, pedidos cerrados o información de todas las organizaciones.

Preferir acciones pequeñas y estables

Una acción demasiado amplia concentra privilegios y dificulta aplicar el mínimo privilegio. Separar order.read de order.export, o user.update de user.assign_role, permite otorgar acceso de forma precisa. Tampoco conviene crear un permiso para cada caso puntual: si la diferencia depende del recurso, suele ser una condición de la política, no un nuevo rol.

Elegir entre roles, permisos, atributos y contexto

Los roles simples funcionan cuando hay pocos perfiles estables y las operaciones no dependen apenas del dato. Son una buena puerta de entrada, pero se vuelven frágiles si aparecen nombres como manager_con_exportacion o supervisor_solo_unidad_norte. Esas combinaciones codifican excepciones como perfiles permanentes.

Los permisos explícitos son adecuados para desacoplar responsabilidades de perfiles y para asignar capacidades de forma administrable. Los atributos sirven cuando la decisión depende de propiedades del sujeto, recurso o entorno: organización, unidad, clasificación, propietario, país o nivel de riesgo. Las reglas contextuales completan el modelo cuando intervienen condiciones transitorias, como una delegación activa o la fase de aprobación.

En la práctica, un modelo híbrido suele ser más mantenible: los roles conceden permisos base; una política evalúa atributos del usuario y del recurso; y el contexto aporta la organización seleccionada o el canal de operación. El rol no debe sustituir al análisis del dato.

Centralizar las políticas y filtrar datos desde el origen

Una aplicación PHP necesita un punto coherente para expresar decisiones. Puede materializarse en clases de política, servicios de autorización o componentes equivalentes del framework elegido. Lo importante es que los controladores soliciten una decisión y que las vistas no sean la única barrera.

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

La política debe recibir sólo los datos necesarios para decidir: identidad, operación, recurso y contexto. Evite consultar variables globales o depender implícitamente de la ruta actual; eso vuelve las reglas difíciles de probar y reutilizar.

La comprobación individual no basta en pantallas de listado. Si una consulta devuelve pedidos de varias organizaciones y después la interfaz oculta algunos, ya se produjo una exposición. Aplique el alcance en el repositorio o capa de consulta: filtre por organización autorizada, unidad permitida o cartera asignada antes de cargar resultados. Para recursos por identificador, compruebe tanto la operación como la pertenencia del recurso.

Estados y transiciones como parte de la política

Las operaciones sensibles suelen depender del estado. Un aprobador puede aprobar un pedido pendiente, pero no uno cancelado ni uno ya aprobado. Modele la transición permitida de forma explícita y valide de nuevo en el punto que persiste el cambio. La interfaz puede desactivar un botón para orientar, pero la política del servidor es el control efectivo.

Evitar excepciones permanentes y denegaciones reveladoras

Los roles genéricos como “administrador” necesitan límites claros. Un administrador de una organización no debería convertirse automáticamente en administrador de la plataforma. Del mismo modo, una excepción como “puede editar este registro concreto” debe tener propietario, motivo, fecha de revisión o caducidad y trazabilidad. Si se repite, probablemente falta una regla de negocio o un atributo del modelo.

Las denegaciones deben ser útiles sin revelar información sensible. Para una consulta directa a un recurso ajeno, normalmente es preferible una respuesta indistinguible de que el recurso no existe. En una acción sobre un recurso ya visible, puede indicarse que faltan permisos sin detallar reglas internas, asignaciones o atributos protegidos.

Registre acciones sensibles autorizadas y denegadas cuando aporten valor operativo: cambios de roles, exportaciones, aprobaciones, accesos delegados y modificaciones de configuración. La auditoría debe incluir actor, acción, recurso, organización o contexto, momento y resultado. No registre credenciales, tokens ni datos personales innecesarios.

Probar la autorización como una propiedad del producto

Las pruebas de autorización deben cubrir decisiones permitidas y denegadas. Una batería mínima incluye: un usuario con permiso sobre su organización; el mismo usuario frente a otra organización; un usuario sin permiso; un recurso en un estado no válido; y un cambio de contexto, como retirar una asignación o finalizar una delegación.

Pruebe las políticas directamente porque ofrecen diagnósticos precisos, y añada pruebas de integración para confirmar que rutas, controladores, consultas y operaciones de escritura aplican la decisión. Las regresiones más peligrosas son las de privilegio: añadir un rol, una ruta o una optimización de consulta que amplía el acceso de forma involuntaria.

  • Compruebe que un listado no contiene recursos fuera del alcance.
  • Compruebe que conocer un identificador ajeno no concede acceso.
  • Compruebe que un cambio de estado exige la política correspondiente.
  • Compruebe que retirar un permiso invalida la capacidad en la siguiente solicitud.

Adoptar el modelo en una aplicación con reglas dispersas

No es necesario reescribir todo el sistema. Empiece por inventariar rutas, comandos, tareas programadas y puntos de exportación que cambian o exponen datos. Priorice acciones de alto impacto y recursos compartidos entre organizaciones. Extraiga una política por dominio, cubra el comportamiento actual con pruebas y corrija las reglas que concedan más acceso del previsto.

Después, sustituya comprobaciones dispersas por llamadas al servicio de autorización y mueva el filtrado de alcance a las consultas. Revise periódicamente permisos sin uso, roles con demasiadas capacidades, delegaciones vencidas y excepciones activas. El diseño de permisos y autorización en PHP será mantenible cuando una nueva funcionalidad pueda responder, antes de desarrollarse, quién opera, sobre qué recurso, bajo qué condiciones y con qué evidencia se ha comprobado.

Checklist para cada módulo nuevo

Checklist para cada módulo nuevo — guía visual de DedicatedPHP
  • ¿Están definidas las operaciones de negocio y sus recursos?
  • ¿La matriz distingue permiso, alcance y condición de estado?
  • ¿Las políticas se aplican en lectura, escritura, exportación y procesos no interactivos?
  • ¿Las consultas filtran datos antes de entregarlos a la interfaz?
  • ¿Existen pruebas de acceso permitido, denegado y entre organizaciones?
  • ¿Las acciones sensibles dejan una auditoría proporcional y segura?
¿Quieres aplicar estas ideas a tu proyecto?Hablemos de tu plataforma PHP.
Ver servicio relacionado