This is a submission for the Permit.io Authorization Challenge: Permissions Redefined
What We Built
DockerSensei is a platform designed to bring robust and secure management to your Docker containers. It tackles the challenge of providing fine-grained access control over container operations, ensuring that only authorized users can perform specific actions such as spawning containers, starting/stopping containers, viewing logs and executing shell commands. By integrating Permit.io, DockerSensei leverages Role-Based Access Control (RBAC) to offer a scalable and auditable permission management system for your containerized environment.
Imagine a scenario where you have multiple teams working with different sets of containers. DockerSensei allows you to define roles like "Developer" who can manage the application containers, "Tester" who can only view logs for debugging, and "Admin" who has full control over the entire Docker infrastructure. This eliminates the "all or nothing" approach often associated with basic Docker management and enhances security significantly.
Demo
The application is hosted at: https://dockersensei.rushabhjaveri.com. The application is in Demo Mode, thus there can be only 10 containers at maximum at any given time on the server, to save on resources.
You can use the following credentials to explore the application:
- Admin: [email protected] / password: 2025DEVChallenge
- Developer: [email protected] / password: 2025DEVChallenge
- Tester: [email protected] / password: 2025DEVChallenge
- New User (Viewer): [email protected] / password: 2025DEVChallenge
These credentials may give unrestricted access to the entire system, please use them responsibly.
Screenshots:
- Listing Containers
- Container Management (Admin)
- Container Management (Tester)
- Container Management (Developer)
- User Management Dashboard (Admin)
- Audit Logs (Admin)
(In the Container management images, notice that the actions which the user does not have access to, such as start/stop are disabled.)
Project Repo
The GitHub repository URL is - https://github.com/MananGandhi1810/devto-permit-hackathon
Setup Steps
- Clone the repository:
git clone https://github.com/MananGandhi1810/devto-permit-hackathon.git dockersensei
cd dockersensei
- Set up the environment variables:
- Copy `.env.example` to `.env` in both `backend` and `frontend` directories.
- Fill in the required values, including Permit.io credentials.
- Start the services using Docker Compose:
docker-compose up -d
- Access the application:
- Frontend: http://localhost:8000
- Backend API: http://localhost:3000
Our Journey
Building DockerSensei was an insightful journey into the world of container management and the power of externalized authorization. Initially, we considered implementing a custom permission system directly within the Node.js backend. However, as the requirements for fine-grained control and the need for scalability grew, it became clear that a dedicated solution like Permit.io would be far more efficient and secure.
One of the main challenges we faced was understanding the nuances of RBAC and how to effectively model the different user roles and their corresponding permissions in the context of Docker container operations. Permit.io's documentation and CLI proved invaluable in navigating this learning curve.
Integrating Dockerode with the backend to interact with the Docker daemon also presented some interesting challenges, particularly around handling asynchronous operations and streaming container logs in real-time to the frontend. We used Socket.IO to establish real-time connections for the exec and logs functionalities, allowing users to interact with running containers and view log output in near real-time.
On the frontend, using React with Shadcn/UI and Tailwind CSS allowed for rapid development of a clean and responsive user interface.
We have hosted our frontend on Vercel, and the backend on a Virtual Machine from Digital Ocean. The backend is served via a Caddy reverse proxy, allowing us to connect our domain https://dockersensei.rushabhjaveri.com/ easily.
Throughout this process, we learned the importance of separating concerns – keeping the core application logic distinct from the authorization layer. This not only improves security but also makes the application more maintainable and adaptable to future changes in permission requirements.
Container management systems are the backbone of modern software deployment, running mission-critical applications that handle sensitive data and provide essential services. In such environments, robust access control is not just a best practice, but a necessity, because of the following reasons:
- Security: Unauthorized access can lead to severe security breaches, including data leaks and service disruptions.
- Compliance: Many industries have strict rules (e.g., GDPR, HIPAA) about data access.
- Operational Integrity: Access control prevents accidental or intentional misconfigurations.
Using Permit.io for Authorization
Permit.io is at the heart of DockerSensei's access control mechanism. We leveraged the Permit.io CLI and backend SDK to implement the following:
Defining Roles and Permissions: Using the Permit.io dashboard, we defined the four predefined roles (Admin, Developer, Tester, Viewer) and their associated permissions. For example:
- The Admin role has permissions to start, stop, restart, logs, exec, and list all containers, as well as assign roles to the users and view audit logs.
- The Developer role can start, stop, restart, exec, logs, and list containers.
- The Tester role can only logs and list containers.
- The Viewer role can list containers.
Implementing Permission Checks in the Backend: In the Node.js backend, before executing any container-related action, we used the Permit.io SDK to check if the currently authenticated user has the necessary permission for that specific action. For instance, before allowing a user to stop a container, the backend would perform a check like:
const accessControl = async (req, res, next, { action, resource }) => {
const isPermitted = await permit.check(req.user.id, action, resource);
if (!isPermitted) {
return res.status(403).json({
success: false,
message: "No permission",
data: null,
});
}
next();
};
// Permit.io is used here as middleware in Express.js to check for authorization
router.post(
"/:id/restart",
checkAuth, // Authentication middleware (verifies the user's identity)
(req, res, next) =>
accessControl(req, res, next, { // Authorization middleware (uses Permit.io)
action: "restart",
resource: "Container",
}),
restartContainerHandler, // The actual handler function for restarting the container
);
Dynamic Role Assignments: The Admin dashboard allows administrators to assign roles to users. When a role is assigned or revoked, the backend interacts with the Permit.io API to update the user's permissions in real-time.
Audit Logging: While Permit.io provides its own audit logs, DockerSensei also maintains internal audit logs, recording user actions and the outcome of permission checks, providing an additional layer of traceability.
By using Permit.io, DockerSensei achieves a robust, scalable, and easily manageable authorization system, freeing up development time that would otherwise be spent on building and maintaining a custom RBAC solution. The Permit.io CLI made it straightforward to define and manage the authorization model, and the SDK seamlessly integrated with the backend logic.
RBAC Policy:
Admin
Developer
Tester
Viewer
The DockerSensei team consists of Manan Gandhi (manangandhi1810) and Rushabh Javeri (rushabh).
Huge thanks to Dev.to and Permit.io for providing us with the opportunity of participating in this hackathon.