Lion Cipher Lab
Reimplement Azure RBAC evaluation from scratch: Actions, NotActions, DataActions, deny assignments and scope inheritance (offline)
- Cloud Security
- Advanced
- ~90 min
- Free · no account required
Why it matters
Ask 'who can read the payments data?' about an Azure storage account and most people open the storage account's Access control (IAM) page and read the list. That list is the input to a decision, not the decision. Azure Resource Manager walks up from the storage account through the resource group, the subscription and every management group above it, collects every role assignment that reaches down, checks deny assignments first, subtracts NotActions from Actions role by role, and only then evaluates conditions. Three misunderstandings live in that pipeline and every one of them shows up in…
What you'll learn
- Reading a real Azure role definition (Actions, NotActions, DataActions, NotDataActions, AssignableScopes) and computing its effective permissions by hand
- Implementing the documented Azure RBAC decision order: deny assignments first, then role assignments at this scope or above, then per-role subtraction, then conditions
- Proving with a running engine that NotActions is not a deny: a second role assignment restores the action that Contributor subtracts
- Separating the control plane from the data plane, and explaining why Owner and Contributor cannot read a blob through Entra ID yet can list the storage account keys
- Modelling scope inheritance across management groups, subscriptions, resource groups and resources, plus transitive group membership
- Modelling deny assignments with All Principals, ExcludePrincipals and DoNotApplyToChildScopes, and knowing who actually creates them
- Writing a small, fail-closed evaluator for a subset of Azure ABAC condition syntax, including constrained role-assignment delegation
- Auditing a toy tenant for who can write role assignments at each scope, and measuring the before/after effect of disabling Shared Key authorization
Steps in this lab
- The question this engine answers, and the words you need first
- Set up: one folder, two files, no installs
- Role definitions are data: copy seven real built-in roles
- Matching an operation, and the subtraction that happens per role
- Scope inheritance: walk from a resource up to the root
- Deny assignments: the only real 'deny', and you cannot write one by hand
- Conditions: a small evaluator that refuses what it does not understand
- The tenant: eleven principals, fourteen role assignment attempts, one rejection
- The full engine: create azure_rbac_eval.py and run it
- Read the matrix: 28 requests, 28 correct, and three naive models that are not
- Watch three decisions step by step
- The audit: who can write role assignments at each scope
- Measure the fix: data reach before and after allowSharedKeyAccess=false
- What this engine ignores, and why you must not ship it
- Azure versus AWS versus Google Cloud: the one-paragraph difference