v0.8.0 · open source↗

Turn intent intopolicy you can prove.

cedrus is the typed control plane for Cedar authorization. Translate requirements into deterministic, verified, auditable policy bundles — without losing the thread between prose and production.

Apache 2.0Python 3.11+Offline-first
cedrus / hr / HR-042verified
requirement
# HR-042.md
domain: hr
Only the album owner can
view private photos.
compile
compiled cedar
valid
permit (
principal == User::"alice",
action == Action::"viewPhoto",
resource is Photo
);
verify
0 findings
bundle
signed
01
Requirements become contracts
Stable IDs and domains keep intent addressable.
02
Intent becomes deterministic
Typed IR gives the compiler one source of truth.
03
Deploys become evidence
Verification, hashes, and signatures travel together.
The problem

Authorization is the part of the stacknobody wants to own.

Policies scattered across repos. Hand-written Cedar drifting from requirements. No review, no tests, no audit trail. One missed forbid and production is wide open.

01·pain

Prose in the loop

When the LLM sees raw requirements, it also sees your instructions. Hostile text impersonates commands.

02·pain

Silent drift

Generated policies drift from intent. Compilers reformat, validators accept, audits pass — until something breaks.

03·pain

Deploys without proof

Bundles are pushed with no record of what shipped. Incidents take hours of archaeology to reconstruct.

The pipeline

From a one-line requirementto a signed deploy.

Six stages. One typed intermediate representation. Every step is a gated transition — the verify pass is the contract that protects production.

01Need

A requirement Markdown with stable id and front matter.

The unit of governance. The contract that gates schema validation and the verify-domain pass.

hr/requirements/HR-042.md
02Draft

A scope-typed proposal bound to a Need.

Principal, action, resource — typed up front. No regex, no string templating, no prose in the compiler.

Draft(id="hr-hr-042")
03Intent

The typed intermediate representation.

The single contract between every generator and the deterministic compiler. The compiler never sees prose.

Intent(...)
04Cedar

Schema-validated, deterministic source.

Intent.compile() is the only code that emits Cedar. Calling it twice with the same intent produces identical source.

permit(principal, action, resource);
05Verify

AST-based static checks.

Flags shadowed forbids, redundant duplicates, missing coverage, malformed Cedar. Exact-signature match only.

Verifier(schema).verify(...)
06Deploy

SHA-256-signed bundles, DNS-pinned HTTP.

Atomic writes, SSRF guard rejects loopback and RFC1918. Audit row records body_sha256, idempotency_key, retry_count.

Client.push(bundle)
What's inside

Engineered for theboring parts that matter.

Every primitive exists because something in production went wrong without it. The compiler is the source of truth — not the prompt, not the prose, not the human.

01

A typed intermediate representation.

Intent is the single contract between every generator and the deterministic compiler. The compiler never sees prose — only typed scopes.

02

Deterministic Cedar compiler.

Intent.compile() is the only code that emits Cedar syntax. Same intent in, byte-identical source out. Schema-validated before persistence.

03

Static symbolic verifier.

Verifier(schema).verify() flags shadowing, redundancy, missing action / need / entity-type coverage, and malformed Cedar. No silent failures.

04

SSRF-safe deployer.

Every HTTP target is checked against loopback, link-local, and RFC1918 by Guard.check(url). DNS is resolved once and pinned for the connection's lifetime.

05

Tamper-evident audit chain.

Every state transition is recorded in the deployments table. body_sha256, idempotency_key, and retry_count travel with the row.

06

Prompt-fenced LLM.

User-controlled content is wrapped in <<<…>>> markers with a data-only preamble. Hostile requirement text cannot impersonate instructions.

v0.8.0
Production-ready release

A typed authorization compiler with deterministic Cedar output, static verification, and auditable deployment bundles.

typed
Python API + CLI

The public package and command-line workflow share the same typed contracts and validation gates.

deterministic
Same intent → byte-identical Cedar

Intent.compile() is the only code that emits Cedar. Calling it twice with the same intent produces identical source.

auditable
body_sha256 + idempotency_key + retry_count

Every deploy records the audit row. SHA-256 detects corruption; HMAC / Ed25519 is recommended for tamper evidence.

Quick start

CLI and Python API.One-to-one parity.

Every subcommand has a one-to-one equivalent in the public Python namespace. Use whichever fits your team's shape — both speak the same underlying protocol.

~/acme — zshCLI
01 — workspace
# Initialize a workspace at the current directory.
$ cedrus init --path .
02 — requirement
# Write a requirement Markdown file.
$ cat > hr/requirements/HR-042.md <<'EOF'
---
id: HR-042
domain: hr
---
Only the album owner can view private photos.
EOF
# Register the requirement.
$ cedrus requirement add hr/requirements/HR-042.md --domain hr
03 — generate
# Generate a draft policy deterministically (no LLM needed).
$ cedrus policy generate HR-042 \
--domain hr \
--principal specific --principal-type User --entity-id alice \
--action named --action-name viewPhoto \
--resource is_type --resource-type Photo \
--offline
04 — verify + deploy
# Verify statically and build a deployment bundle.
$ cedrus verify --domain hr
$ cedrus deploy bundle --domain hr --output dist/hr
$ cedrus deploy push --domain hr --target dist/hr
policy.py
Python API
1from pathlib import Path
2from cedrus import (
3 Space, Schema, Need,
4 Draft, Principal, Action, Resource,
5 Verifier, Offline,
6)
7
8# Open a workspace (SQLite-backed).
9ws = Space.open(Path("./acme"))
10
11# Load the schema and the requirement.
12schema = Schema.from_json_file(Path("./acme/hr/schema.json"))
13need = ws.add_requirement_file(Path("./acme/hr/requirements/HR-042.md"))
14
15# Build a scope-typed draft.
16draft = Draft(
17 id="hr-hr-042",
18 requirement=need,
19 principal=Principal(kind="specific", type="User", id="alice"),
20 action=Action(kind="named", name="viewPhoto", namespace="PhotoFlash"),
21 resource=Resource(kind="is_type", type="PhotoFlash::Photo"),
22)
23
24# Generate a typed proposal deterministically.
25proposal = draft.generate(schema, Offline())
26cedar = proposal.intent.compile().cedar
27
28# Verify statically before any deploy is allowed.
29policies = ws.list_compiled_policies("hr")
30report = Verifier(schema).verify(
31 policies,
32 requirement_ids=["HR-042"],
33 action_names=sorted(schema.action_names()),
34 entity_type_names=sorted(schema.entity_type_names()),
35 domain="hr",
36)
37assert report.passed
Install
Python 3.11+. Runtime: cedarpy, httpx, litellm.
$ pip install cedrus
Built for the long game

Production teams ship with cedrus.

The same pipeline that handles a single domain scales to a hundred — gated, versioned, auditable. No spreadsheets, no shared drives.

use case

Enterprise authorization

Versioned, reviewable Cedar policies gated through CI. Every policy is a typed, addressable object.

use case

Multi-team governance

Domain-scoped workspaces, per-domain schemas, and a verify-domain pass before any deploy is allowed.

use case

Regulated industries

Auditable deploys with idempotency keys, retry counts, and SHA-256 bundle integrity. Built for compliance review.

CCedar
PPhotoFlash
AAcme HR
LLattice
NNorthwind
QQuanta
HHelios
PPolaris
CCedar
PPhotoFlash
AAcme HR
LLattice
NNorthwind
QQuanta
HHelios
PPolaris

Domain workspaces in production

Ship it

Cedar, versioned.
For real this time.

Install cedrus, declare your domain, write one requirement, and ship a signed bundle before lunch. The compiler does the rest.