Skip to content

feat: feature-flagging via Milo entitlements (#577)#695

Open
kevwilliams wants to merge 4 commits into
mainfrom
feat/577-feature-flagging-entitlements
Open

feat: feature-flagging via Milo entitlements (#577)#695
kevwilliams wants to merge 4 commits into
mainfrom
feat/577-feature-flagging-entitlements

Conversation

@kevwilliams
Copy link
Copy Markdown

Summary

Adds a provisional enhancement for org-level boolean feature flags built entirely on the existing quota.miloapis.com/v1alpha1 primitives.

What this proposes

  • Feature flag = ResourceRegistration with type=Entity
  • Grant = ResourceGrant with amount=1 targeting an org
  • Check = AllowanceBucket.status.available > 0 queried by field selector
  • v1 is zero-code: no new CRDs, no new controllers, no binary changes

Key decisions needed from reviewers

The doc marks six open questions with <<[UNRESOLVED]>> blocks. The two blocking ones:

  1. claimingResources validation — the CRD schema may enforce MinItems=1, which would break the proposed ResourceRegistration shape. Needs verification against the live CRD before this can move to implementable.
  2. Consumer check strategy — confirm AllowanceBucket (Option A) as the standard read path, or prefer querying ResourceGrant directly (Option B).

Test plan

  • Verify claimingResources: [] is accepted by the live ResourceRegistration CRD
  • Apply sample ResourceRegistration and ResourceGrant YAML to a dev cluster and confirm AllowanceBucket is auto-created
  • Confirm AllowanceBucket.status.available drops to 0 after ResourceGrant deletion
  • Confirm org admin can list AllowanceBuckets with existing organization-quota-manager role

Add provisional enhancement for org-level boolean feature flags
built on the existing quota.miloapis.com entitlement primitives.

v1 is zero-code: ResourceRegistration defines a flag, ResourceGrant
enables it for an org, AllowanceBucket is the read path for services.
No new CRDs, controllers, or binary changes required.
@kevwilliams kevwilliams requested a review from scotwells April 17, 2026 20:00
@scotwells
Copy link
Copy Markdown
Contributor

@kevwilliams the registration path looks okay, the type being Feature might make more sense. Maybe we can look at something where we can provide a check API that's compatible with https://openfeature.dev so we can leverage its client-side tooling for feature checks? Not opposed to just building a client SDK for feature checking against the quota service either if we want to roll our own.

- Resolve consumer check strategy: adopt OpenFeature-compatible provider
  (Go + TypeScript) wrapping AllowanceBucket field selector query so
  services never call the quota API directly
- Add type=Feature as a hard prerequisite: live CRD only accepts Entity
  and Allocation; spec.type is immutable so the Milo enum change must land
  before any ResourceRegistration instances are created
- Replace three-option consumer API with OpenFeature provider contract,
  usage examples, and deliverables
- Add custom SDK alternative to Alternatives section
- Resolve open question 2 (consumer check strategy); renumber remaining
@kevwilliams
Copy link
Copy Markdown
Author

@scotwells Updated it to include these things, also considered the rolling our own idea a bit, I think OpenFeature gives us quite a bit for free there so I included that in there too.

- Resolve claimingResources: minItems=1 enforced; adopt sentinel
  features.miloapis.com/FeatureGrant to satisfy constraint
- Resolve bundle vs infra: ResourceRegistrations in Milo bundle;
  ResourceGrants in datum-cloud/infra for per-cluster variation
- Resolve IAM role: dedicated feature-flag-operator, not quota-operator
- Resolve naming: features.miloapis.com/<name> confirmed
- Resolve org admin read: organization-quota-manager already sufficient
- Promote status from provisional to implementable
scotwells
scotwells previously approved these changes Apr 27, 2026
kevwilliams added a commit to milo-os/milo that referenced this pull request May 5, 2026
## Summary

- Adds `Feature` as a valid value for `spec.type` on
`ResourceRegistration`, alongside the existing `Entity` and `Allocation`
values
- `Feature` is a boolean entitlement grant for org-level feature flags —
no admission enforcement or claim machinery is used; the registration
simply signals that a feature is available to an organization
- Regenerates the CRD YAML
(`quota.miloapis.com_resourceregistrations.yaml`) so the new enum value
is enforced at the API level
- Adds a Chainsaw test step (`create-valid-feature-registration`) to
verify that `type=Feature` is accepted and the registration reaches
`Active=True`

No controller logic branches on `spec.type` — grep confirms zero usages
of `registration.Spec.Type` in `internal/quota/`. This is a
schema/validation-only change. The field is immutable after creation
(CEL rule already in place).

Closes #575
Related: datum-cloud/enhancements#695

## Test plan

- [ ] `task generate:code` runs cleanly and `Feature` appears in
`config/crd/bases/quota/quota.miloapis.com_resourceregistrations.yaml`
enum
- [ ] Chainsaw test `create-valid-feature-registration` passes: creates
a `ResourceRegistration` with `type: Feature` and waits for
`Active=True`
- [ ] Existing Chainsaw tests (`test-invalid-type-enum`, immutability
tests, etc.) continue to pass
- [ ] Attempting to create a registration with an invalid type still
returns an error mentioning `spec.type`
quota.miloapis.com-manager already covers all permissions needed to
manage feature flags — no dedicated feature-flag-operator role needed.
Also drop the iam/ subtree from the Bootstrap Configuration example
since no new role is being added.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants