- Building DPHP: What is it?
- Building DPHP: Event Sourcing
- Building DPHP: Distributed Locks
- Building DPHP: Authz and Ownership
- Building a New Type of Database
Durable PHP is a framework for writing arbitrarily complex code that scales. It’s still under active development, but I thought I’d write a few blog posts about it before I release the documentation on how to use it. Today, I want to talk about Authorization/Authentication and Ownership.
In any software project, there are users. These users interact with resources, usually via CRUD (Create, Read, Update, and Delete). However, Durable PHP has a bit more fine-grained actions:
- Start: creates a new orchestration
- Signal: send an event somewhere, but no return address.
- Call: send an event somewhere with a return address and be notified upon completion
- Read: retrieve snapshots of distant state
- Subscribe: be notified of status changes
- Delete: just what it sounds like
Durable PHP treats everything as a resource, whether it is an activity, entity, or orchestration and every resource must be owned by something or someone. The application developer is responsible for what those entities are and what the permissions are, which can be rather fine-grained.
From there, the are only a few basic rules you need to know:
- A user can own a resource. They have full control over the resource.
- A user can share an owned resource with another user or role.
- A user can share Read/Update/Delete rights to a resource they own.
- A user can only interact with a resource if they have a right to do so.
These rules are important to know because all code you write is operating in the context of the user, enforced by the infrastructure. This prevents a number of security concerns, where even if a user were to inject an ID of something they weren’t supposed to have access to, your code wouldn’t have access to it. This is much more similar to sandboxing that an OS does on a mobile device, where the user who owns the resource has to give you permission to access it.
There is, however, a sudo mode for users of the role admin
. These users are able to access anything, even if they don’t have permission to do so. This allows administrators to perform actions on behalf of other users, for performing customer support or other administrative tasks.
One technique I’ve used is to have an entity owned by an administrator. Code that needs to run elevated operations calls the singleton entity and asks for permission. If it’s allowed, it will simply execute the code as an admin, otherwise, request a human admin to check if it is allowed and approve/disapprove it.
For example, in the context of a chat app, an HR person might need to access private chats of a user. If, in the context of my app, they have the appropriate role, I would allow them to access that in the context of an admin; otherwise, I would elevate this to a human as this is either an application bug (the user seeing a button they shouldn’t see) or someone is doing something fishy.
I’m very happy with this authorization system, as it is extremely clean (<120 lines of code) and quite flexible.
Leave a Reply