From datum-platform
Covers the Identity and Access Management system including ProtectedResource, Role, and PolicyBinding definitions. Use when implementing authorization for new resource types or defining service roles.
npx claudepluginhub datum-cloud/claude-code-plugins --plugin datum-platformThis skill uses the workspace's default tool permissions.
This skill covers the Identity and Access Management (IAM) system in Milo, the Datum Cloud control plane.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
This skill covers the Identity and Access Management (IAM) system in Milo, the Datum Cloud control plane.
Milo uses a Kubernetes-native IAM system built on Custom Resource Definitions (CRDs). Services integrate declaratively by:
The IAM system handles authorization enforcement. Services don't need to understand the internal authorization backend — they only need to define protected resources and roles.
All IAM resources are in the iam.miloapis.com/v1alpha1 API group.
| Resource | Scope | Purpose |
|---|---|---|
ProtectedResource | Cluster | Declares a resource type and its permissions |
Role | Namespaced | Defines a collection of permissions |
PolicyBinding | Namespaced | Binds a role to subjects on a resource |
User | Cluster | Represents a platform user |
Group | Namespaced | A collection of users |
GroupMembership | Namespaced | Links users to groups |
Declares which resources require authorization and what permissions apply.
apiVersion: iam.miloapis.com/v1alpha1
kind: ProtectedResource
metadata:
name: workloads.myservice.miloapis.com
spec:
# Which service owns this resource
serviceRef:
name: myservice.miloapis.com
# Resource kind (matches Kubernetes Kind)
kind: Workload
singular: workload
plural: workloads
# Available permissions for this resource
permissions:
- list
- get
- create
- update
- delete
- patch
- watch
- use
# Parent resources for permission inheritance
parentResources:
- apiGroup: resourcemanager.miloapis.com
kind: Project
Permissions flow down the resource hierarchy:
Organization (admin)
└─→ Project (admin, inherited)
└─→ Workload (admin, inherited)
A user with admin on an Organization automatically has admin on all Projects and Workloads within that Organization.
Permissions follow the format: {service}/{resource}.{action}
Examples:
iam.miloapis.com/users.createmyservice.miloapis.com/workloads.getresourcemanager.miloapis.com/projects.deleteDefines a collection of permissions that can be granted to users.
apiVersion: iam.miloapis.com/v1alpha1
kind: Role
metadata:
name: workload-editor
namespace: datum-system
spec:
# Launch stage for the role
launchStage: Stable
# Direct permissions
includedPermissions:
- myservice.miloapis.com/workloads.get
- myservice.miloapis.com/workloads.list
- myservice.miloapis.com/workloads.create
- myservice.miloapis.com/workloads.update
# Inherit permissions from other roles
inheritedRoles:
- name: workload-viewer
namespace: datum-system
Roles support composition through inheritedRoles. The system computes effective permissions by flattening the inheritance tree:
# workload-admin inherits workload-editor
# workload-editor inherits workload-viewer
# Result: workload-admin has all permissions from all three roles
status:
effectivePermissions:
- myservice.miloapis.com/workloads.get
- myservice.miloapis.com/workloads.list
- myservice.miloapis.com/workloads.create
- myservice.miloapis.com/workloads.update
- myservice.miloapis.com/workloads.delete
Follow the viewer → editor → admin hierarchy:
| Role | Permissions |
|---|---|
viewer | get, list, watch |
editor | viewer + create, update, patch |
admin | editor + delete, manage roles |
Connects roles to subjects (users or groups) for specific resources.
apiVersion: iam.miloapis.com/v1alpha1
kind: PolicyBinding
metadata:
name: alice-workload-editor
namespace: my-project
spec:
# Which role to grant
roleRef:
name: workload-editor
namespace: datum-system
# Who receives the role
subjects:
- kind: User
name: alice@example.com
uid: "user-uuid-here"
- kind: Group
name: developers
namespace: my-org
# What resource(s) the role applies to
resourceSelector:
# Option 1: Specific resource instance
resourceRef:
apiGroup: myservice.miloapis.com
kind: Workload
name: my-workload
uid: "workload-uuid-here"
# Option 2: All resources of a kind (pick one, not both)
# resourceKind:
# apiGroup: myservice.miloapis.com
# kind: Workload
| Selector | Use Case |
|---|---|
resourceRef | Grant role on a specific resource instance |
resourceKind | Grant role on all resources of a type (within namespace) |
Services integrate with IAM declaratively, not programmatically.
Create YAML files in config/protected-resources/{service}/:
# config/protected-resources/myservice/myresource.yaml
apiVersion: iam.miloapis.com/v1alpha1
kind: ProtectedResource
metadata:
name: myresources.myservice.miloapis.com
spec:
serviceRef:
name: myservice.miloapis.com
kind: MyResource
singular: myresource
plural: myresources
permissions:
- list
- get
- create
- update
- delete
- watch
parentResources:
- apiGroup: resourcemanager.miloapis.com
kind: Project
Create role definitions in config/roles/:
# config/roles/myservice-viewer.yaml
apiVersion: iam.miloapis.com/v1alpha1
kind: Role
metadata:
name: myservice.miloapis.com-viewer
namespace: datum-system
spec:
launchStage: Stable
includedPermissions:
- myservice.miloapis.com/myresources.get
- myservice.miloapis.com/myresources.list
- myservice.miloapis.com/myresources.watch
---
# config/roles/myservice-editor.yaml
apiVersion: iam.miloapis.com/v1alpha1
kind: Role
metadata:
name: myservice.miloapis.com-editor
namespace: datum-system
spec:
launchStage: Stable
inheritedRoles:
- name: myservice.miloapis.com-viewer
namespace: datum-system
includedPermissions:
- myservice.miloapis.com/myresources.create
- myservice.miloapis.com/myresources.update
---
# config/roles/myservice-admin.yaml
apiVersion: iam.miloapis.com/v1alpha1
kind: Role
metadata:
name: myservice.miloapis.com-admin
namespace: datum-system
spec:
launchStage: Stable
inheritedRoles:
- name: myservice.miloapis.com-editor
namespace: datum-system
includedPermissions:
- myservice.miloapis.com/myresources.delete
# config/protected-resources/kustomization.yaml
resources:
- myservice/myresource.yaml
# config/roles/kustomization.yaml
resources:
- myservice-viewer.yaml
- myservice-editor.yaml
- myservice-admin.yaml
The platform uses a standard resource hierarchy:
Organization (tenant root)
└─→ Project (resource container)
└─→ Service Resources (workloads, networks, etc.)
When defining a ProtectedResource, specify parent resources for permission inheritance:
spec:
parentResources:
# Most service resources are children of Project
- apiGroup: resourcemanager.miloapis.com
kind: Project
For resources directly under Organization:
spec:
parentResources:
- apiGroup: resourcemanager.miloapis.com
kind: Organization
For resources that span the entire organization:
apiVersion: iam.miloapis.com/v1alpha1
kind: PolicyBinding
metadata:
name: org-admin-binding
namespace: my-org
spec:
roleRef:
name: organization-admin
namespace: datum-system
subjects:
- kind: User
name: admin@company.com
uid: "user-uuid"
resourceSelector:
resourceRef:
apiGroup: resourcemanager.miloapis.com
kind: Organization
name: my-org
uid: "org-uuid"
Grant roles to groups rather than individual users:
apiVersion: iam.miloapis.com/v1alpha1
kind: PolicyBinding
metadata:
name: dev-team-editor
namespace: my-project
spec:
roleRef:
name: workload-editor
namespace: datum-system
subjects:
- kind: Group
name: developers
namespace: my-org
resourceSelector:
resourceRef:
apiGroup: resourcemanager.miloapis.com
kind: Project
name: my-project
uid: "project-uuid"
Roles in datum-system namespace are available platform-wide. Service-specific roles can reference them:
spec:
roleRef:
name: resourcemanager.miloapis.com-organizationowner
namespace: datum-system
ProtectedResources and Roles are validated by admission webhooks:
| Validation | Description |
|---|---|
| Permission format | Must match {service}/{resource}.{action} |
| Role references | Referenced roles must exist |
| Subject UIDs | Required for Users (except system groups) |
| Resource references | Referenced resources must exist |
Apply IAM resources to a test cluster and verify:
# Apply protected resources
kubectl apply -k config/protected-resources/
# Apply roles
kubectl apply -k config/roles/
# Verify role effective permissions
kubectl get role -n datum-system myservice.miloapis.com-admin -o yaml
# Create test policy binding
kubectl apply -f test-binding.yaml
# Verify access (implementation-specific)
SKILL.md — This overviewconcepts.md — Deep dive into IAM concepts (Users, Groups, Permissions, Role composition)integration.md — Step-by-step service integration guidek8s-apiserver-patterns — For implementing API types that IAM protectskustomize-patterns — For organizing IAM resource YAML files