Repository navigation
cluster apply: allow changing policy bundle content (group membership) on existing graphs; 0.12.0 refuses it with deployment_scope #882
Description
Problem
In 0.12.0 the content of an applied policy bundle, including its groups: membership, cannot be changed once the cluster ledger has any resources. Both direct apply and apply --server refuse it with deployment_scope, and a fresh ledger cannot adopt existing graphs, so there is no supported way to admit a new actor to an existing graph. 0.11 allowed this (Update policy.<name> [Applied]).
This breaks a common deployment shape: Cedar groups whose membership tracks an identity directory. Ours has one omnigraph actor per human in a realm, and users are added over time. Under 0.12.0 a user added after a graph is created can never be granted access to it. docs/user/operations/policy.md and server.md say existing policy bindings stay fixed in the "current deployment class", but the only way to add an actor under that rule is to rebuild the graph.
Policy rules have no wildcard or "any authenticated actor" selector (PolicyActorSelector has only group), so the membership list cannot be avoided by writing the rule differently.
Reproduction (0.12.0, linux-x86_64, local scratch cluster)
- A
cluster.yamlwith one graphmemory, a cluster-scoped bundle grantingconfig_manageandgraph_list, and a graph bundlememory_ruleswithgroups: { users: [act-alice] }. omnigraph cluster apply --config . --as act-deployer, thenomnigraph cluster force-unlock <id>.- Add
act-bobtousers:in the graph bundle and run any of:omnigraph cluster apply --config . --as act-deployer(server stopped, lock released)omnigraph cluster apply --server http://127.0.0.1:18082 --config .(server running, caller holdsconfig_manage)
Both fail:
ERROR deployment_scope __cluster/state.json: policy.memory_rules changes unsupported graph removal or existing runtime bindings
The server form reports "code": "conflict" with the same message.
- Deleting
__cluster/and re-running apply to start a fresh ledger fails withgraph_already_exists ... bootstrap never adopts an unregistered graph.
On 0.11.0 the same edit after cluster refresh applies cleanly: Update policy.memory_rules [Applied].
The refusal comes from preview_deployment_scope in crates/omnigraph-cluster/src/deployment/execution.rs. A ResourceKind::Policy resource is accepted only when the ledger is empty, the policy is new, or old.digest == new.digest (only the applies_to list may grow, onto newly created graphs).
Proposed change
Permit a deployment to replace the content of an existing policy bundle, authorized by config_manage on the current applied policy, as docs/rfcs/2026-09-09-identity-credentials-and-applied-policy.md already describes ("configuration administration, including policy/group changes"). Keep the existing safeguards: a proposed policy never authorizes itself, apply revalidates the base revision and CAS, and unchanged bytes are a no-op. A --server apply would swap the policy engine for the affected graphs inside the existing transition (the same drain used for schema changes).
If full policy replacement is too large a step, a narrower change that would still solve this is allowing only the groups: membership of an existing bundle to change while rules: and applies_to stay byte-identical.
Affected areas
crates/omnigraph-cluster/src/deployment/execution.rs(preview_deployment_scope)cluster apply, direct and--serverdocs/user/operations/policy.md,server.md,clusters/index.md, which describe bindings as fixed in the "current deployment class"- RFC
2026-09-09-identity-credentials-and-applied-policy
Alternatives considered
- Pre-allocate a fixed pool of actor slots in each group at graph creation and map users to slots outside omnigraph. This works but weakens actor attribution in commit history and makes pool exhaustion a graph rebuild.
- Use one shared actor for all humans. This loses per-actor attribution and revocation at the data tier.
- Rebuild the graph (export, init, load) whenever membership changes. Not viable when membership changes daily.
- Stay on 0.11 until this is supported.
Is a change to policy replacement planned, and if not, is there a supported pattern for changing group membership on existing graphs that I missed?
Activity
feoh commentedon Oct 6, 2026
@blarghmatey for visibility.
aaltshuler commentedon Oct 7, 2026
Closing as fixed in 0.13 by #878.
Existing graph policy content and group membership can now change through cluster apply. The direct deployment regression
current_policy_authorizes_policy_edits_rebinding_and_removalcovers adding an actor while preserving graph state. The real-server journeylive_policy_grants_revocations_and_management_handoffcovers live grant/revoke, current-policy authorization, management handoff and persistence after restart.Evidence: merged implementation, deployment tests, live CLI/server journey.
Static bearer-token source reload is separate work tracked by #434.
feoh commentedon Oct 8, 2026
Thanks very much for the fix - this unblocks our upgrade. Appreciate it!
docs: spec the omnigraph 0.13 upgrade and format-14 cutover (#461)