Omnigraph
Operations

Policy

AWS Cedar authorization. Actions, scopes, actor identity, and the tokens-but-no-policy trap.

Omnigraph integrates AWS Cedar for attribute-based access control. Policies live in a YAML file referenced by policy.file in omnigraph.yaml; the engine consults the compiled policy at the head of every mutating write.

Policy is a property of the engine, not the HTTP transport. Whether the write originates from omnigraph-server, the CLI, or an embedded SDK consumer, the same Cedar decision fires.

The eight actions

ActionScope kindUsed by
readbranch_scopeQueries, snapshots, branch/commit list
exportbranch_scopeNDJSON export
changebranch_scopeMutations
schema_applytarget_branch_scopeomnigraph schema apply
branch_createtarget_branch_scopeBranch creation
branch_deletetarget_branch_scopeBranch deletion
branch_mergetarget_branch_scope (with branch transition)omnigraph branch merge
adminReserved for future policy-management surfaces. No call site today.

Each rule must use exactly one of branch_scope or target_branch_scope. protected_branches is a named list that scope predicates can filter on (any | protected | unprotected).

Configuration

policy:
  file: ./policy.yaml          # Cedar rules + groups
  tests: ./policy.tests.yaml   # declarative test cases

cli:
  actor: act-andrew            # default actor for CLI direct-engine writes

Actor identity (signed-claim-only)

For HTTP writes, the actor used for every policy decision comes from the matched bearer token. Clients cannot supply it via request header, query parameter, or body field. The server resolves the token at the auth middleware boundary and overwrites whatever the handler may have placed in the policy request.

This is intentional. Trusting client-supplied identity for authorization is "asking the attacker if they're an admin." A regression test in the engine asserts the contract: a request with Authorization: Bearer <token-for-actor-A> plus X-Actor-Id: actor-B always evaluates as actor A.

For CLI direct-engine writes, the actor comes from the top-level --as <ACTOR> flag, then cli.actor in omnigraph.yaml. With policy configured and neither set, the engine's footgun guard denies the write rather than silently bypassing.

omnigraph --as act-alice change --uri ./graph.omni \
    --query mutations.gq \
    --name complete_task \
    --params '{"slug": "auth"}'

Remote HTTP writes ignore both knobs.

Tooling

The omnigraph policy subcommand covers the local developer loop:

  • omnigraph policy validate. Parse the policy and exit non-zero on errors.
  • omnigraph policy test. Exercise declarative cases in policy.tests.yaml.
  • omnigraph policy explain --actor … --action …. Explain a single decision.

Server runtime states

The HTTP server classifies its startup configuration into one of three states based on whether bearer tokens are configured and whether a policy file is set:

StateTokensPolicy fileBehavior
OpennonenoneEvery request permitted. Refuses to start without --unauthenticated (or OMNIGRAPH_UNAUTHENTICATED=1). The operator must explicitly opt in.
DefaultDenyyesnoneEvery authenticated request for an action other than read is rejected with HTTP 403. Closes the "tokens but forgot the policy file" trap.
PolicyEnabledanyyesCedar evaluates every request against the configured policy.

The DefaultDeny state is the safety net for the most common authorization mistake: configuring tokens and forgetting to point at a policy file. Without it, that mistake ships the illusion of protection.

Layered enforcement

There are two enforcement points:

LayerQuestionWhere it fires
Engine-layer (coarse)Can this actor invoke this action against this branch / branch-transition?Omnigraph::enforce(action, scope, actor) at the head of every _as writer. One Cedar decision per call.
Query-layer (fine)For the rows / types this action touches, which can the actor see or modify?Per-row predicates pushed into DataFusion at plan time. Not yet implemented.

The engine-layer gate keeps ResourceScope at branch granularity (Graph, Branch, TargetBranch, BranchTransition). Per-type and per-row authority will be the query layer's job.

Common patterns

Open dev, locked-down prod

Local development with no tokens runs Open (with --unauthenticated). Production sets bearer tokens and a Cedar policy:

# omnigraph.yaml (prod)
policy:
  file: ./policy.yaml

Per-team branch ownership

Model agent teams as Cedar entity groups. Rules restrict change and branch_merge against main to operators in the release-managers group, while still allowing every team to create and merge feature branches under their own namespace.

Audit trail

Every commit records the actor that wrote it (actor_id in commit show output). Combined with branch history, you get an actor-attributed audit log without any extra logging plumbing.

On this page