feat: add Milo IAM (ProtectedResource + Roles) for inventory group (#39)#40
Merged
Conversation
Inventory CRDs were Established on the Milo core control plane but no principal could write them: Milo authz is ProtectedResource-driven IAM, not k8s RBAC, and config/base shipped no IAM resources. Every apply was rejected with "cannot get resource ... in API group inventory.miloapis.com". Ship inventory IAM under config/base/iam: - A ProtectedResource per kind (12) registering the group's permission strings. Cluster-scoped root resources, no parentResources. - Group-wide Roles in milo-system: viewer, editor, admin, operator. - An example PolicyBinding (per-kind resourceKind, platform-wide) plus a README documenting who can populate inventory and the self-serve gap. Mirrors config/base/crd: applied to Milo by the same Flux Kustomization, intentionally not wired into config/base (which forces inventory-system and feeds the dev overlay against a kind cluster with no IAM CRDs). Also extends the CLAUDE.md "Adding a new kind" checklist with the IAM step. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
kevwilliams
approved these changes
Jun 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #39. Inventory CRDs are
Establishedon the Milo core control plane but no principal can write them: Milo authz isProtectedResource-driven IAM, not k8s RBAC, andconfig/baseshipped zero IAM resources. Every apply was rejected:What's shipped —
config/base/iam/protected-resources/— oneProtectedResourceper kind (12). Cluster-scoped root resources (noparentResources), mirroring thequotaservice. Registering them is what makesinventory.miloapis.com/<plural>.<verb>addressable by IAM.roles/— group-wideRoles, namespaced tomilo-system:inventory.miloapis.com-viewer—get/list/watchon all kindsinventory.miloapis.com-editor— viewer +create/update/patch/deleteinventory.miloapis.com-admin— inherits editor (full)inventory.miloapis.com-operator— read +update/patchfor the controllerpolicybindings.example.yaml+README.md— documents the binding a loader/operator principal needs (per-kindresourceKind, platform-wide) and the self-serve gap (a caller with onlypolicybindings.createcan't bind itself without an existingRole).Deployment model
Mirrors
config/base/crd: targets Milo, not the manager pod's local cluster (theiam.miloapis.comCRDs only exist on Milo). Applied by the same Flux Kustomization that appliesbase/crd+ the webhook component — addconfig/base/iamto its paths on the infra side (datum-cloud/infra#2675). Intentionally not wired intoconfig/base, which forcesinventory-systemand feeds the dev overlay against a kind cluster with no IAM CRDs.Verification
kubectl kustomizebuilds clean forconfig/base/iam,protected-resources/,roles/, the example, and the unchangedconfig/base+ dev overlay.base/iamand a binding exists for the loader principal:Also extends the CLAUDE.md "Adding a new kind" checklist with the IAM step so this gap doesn't recur.
🤖 Generated with Claude Code