Case study 12 · Engineering Lifecycle Services

Workspace-level permissions that carry down to every project and asset

A hierarchical access model in which permissions granted on a workspace or project apply to everything inside it, checked on every request.

Partner
A multinational advisory firm
Period
October 2024 to January 2026
Access rules
6
Direct, group, ownership, action rank, inheritance and parent read
Hierarchy levels
4
Workspace, project, asset and version
Token types
3
Entra ID, service-to-service and short-lived WebSocket

The challenge

Teams share some work and keep other work private. Assigning access asset by asset does not work when each project contains many pipelines, agents, dashboards and versions.

What we built

A Casbin policy model that follows the platform's resource hierarchy and is enforced on every route. Access can come from a direct grant, a group, ownership, a higher action or a parent resource, deny rules override allow rules, and every request is checked after the caller's identity is verified.

What was delivered

  • Permissions inherited from workspace to project, asset and version
  • Group-based access, ownership and deny rules
  • A permission check on every route outside an allowlist, verified by a test

Partner background

Our partner is a multinational advisory firm whose teams work with large volumes of documents, spreadsheets, databases and email. It wanted one internal platform where those teams could build data pipelines and AI agents themselves, instead of commissioning a new application for each need. The platform had to run inside the partner's Microsoft 365 and Azure environment, keep each team's work separate, and move work from experiment to production through controlled environments. This case study covers one part of that platform; nine case studies describe the whole.

The challenge

Too many assets to manage one by one

Each project holds pipelines, agents, dashboards, endpoints and their versions. Granting access to each separately is slow and error-prone.

Exceptions

Sometimes one person must lose access to one asset inside a project they can otherwise see.

Different kinds of callers

Requests come from users in the browser, from other services and over long-lived WebSocket connections.

Navigation needs context

A user with access to one pipeline still needs to see the project and workspace that contain it.

Objectives

  • Grant access once at the right level and have it apply below
  • Support groups and ownership
  • Rank actions so a broader permission covers a narrower one
  • Let a deny rule override inherited access
  • Verify every caller's identity before checking permissions
  • Make it impossible to add a route without a permission check

Our role

CharCentric provided technical leadership and architecture within a multidisciplinary engineering team, and contributed directly to implementation. The platform was built over 16 months, from October 2024 to January 2026, as a Python and FastAPI backend on Azure.

Scope and timeline

The authorization model and token handling were built between March and July 2025.

Delivery timeline from the project history, against the overall platform build
Delivery timeline from the project history, against the overall platform build

Approach

Model the hierarchy explicitly

Resources are linked child to parent in the policy store: versions to assets, assets to projects, projects to workspaces. A policy on a parent applies to its children.

Rank actions

Actions are ordered, so a user allowed to manage a resource can also edit and read it.

Separate identity from permission

Middleware verifies identity first, through an HTTP or WebSocket strategy. The policy check then answers a single question: can this subject perform this action on this resource?

Implementation

Architecture overview
Architecture overview

Policy model

Requests are evaluated as subject, object and action against a reviewed Casbin model file. Rules cover direct access, group access, ownership, action ranking, inheritance from parent resources and reading a parent when a child is accessible. A deny rule overrides any allow.

Enforcement

A FastAPI dependency checks permission on every route except an explicit allowlist, such as health checks and sign-in. A test lists every route and fails if any other route has no check. Policy changes reach every API instance through a Casbin watcher.

Policy storage

Policies are stored in PostgreSQL through an asynchronous Casbin adapter.

Identity

Users authenticate with Microsoft Entra ID tokens. Services use machine-to-machine tokens. WebSocket connections use short-lived authorization tokens issued by the platform.

How it works, step by step
How it works, step by step

Tools and technologies

ToolPurpose
CasbinPolicy model and enforcement
PostgreSQLPolicy storage
Microsoft Entra IDUser identity
FastAPI middlewareIdentity verification
SQLAlchemyAsynchronous policy adapter

What was delivered

Access rules
6
Hierarchy levels
4
Token types
3
Checked
Every route
  • A hierarchical permission model enforced on every route
  • Group, ownership, action-rank and deny rules
  • Identity verification for users, services and WebSockets
  • Parent visibility for users with access to a child resource

Why it matters

Access control that matches how an organization actually groups its work is easier to administer and harder to get wrong. Modelling the hierarchy once replaces grants on every individual asset.

If your organization is planning a platform of this kind, or needs a specific part of one designed and delivered, we would be glad to discuss it.