Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Documentation
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
jobs:
documentation:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24
- name: Lint Markdown
run: npx --yes markdownlint-cli2@0.23.2 --config .markdownlint.json '**/*.md'
- name: Check local document and asset links
run: |
node --input-type=module <<'JS'
import fs from 'node:fs';
import path from 'node:path';
function check(directory) {
for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
if (entry.name === '.git') continue;
const file = path.join(directory, entry.name);
if (entry.isDirectory()) { check(file); continue; }
if (!file.endsWith('.md')) continue;
const text = fs.readFileSync(file, 'utf8');
for (const match of text.matchAll(/\]\(([^)]+)\)|src="([^"]+)"/g)) {
const link = match[1] ?? match[2];
if (link.includes('://') || link.startsWith('#')) continue;
const target = path.resolve(path.dirname(file), link.split('#')[0]);
if (!fs.existsSync(target)) throw new Error(`${file}: missing ${link}`);
}
}
}
check('.');
JS
10 changes: 10 additions & 0 deletions .markdownlint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"default": true,
"MD013": {
"line_length": 120,
"tables": false,
"code_blocks": false
},
"MD033": false,
"MD041": false
}
15 changes: 15 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Organization repository guidelines

Treetop is in early release. Across every project repository, prioritize
correctness, explicit ownership, and strict uniform contracts over compatibility.
Remove obsolete aliases and defaults deliberately; document breaking changes and
concrete consumer migrations in the repository changelog and organization guide.

Keep the full project catalog, planned versions, PR links, and release order in
sync. Distinguish unpublished candidates from available releases. Use immutable
source/action pins for coordinated verification and never claim unrun checks pass.

This repository owns organization documentation and branding. Preserve unrelated
assets. Lint Markdown and check relative links. Prefer primary project sources for
claims. Do not send external announcements, merge, tag, or publish without explicit
user approval. Signed commits and squash merges are required for project changes.
11 changes: 11 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Changelog

## 2026-09-06

- Announce the coordinated breaking release with declared tuple ownership,
format 2 bundles, strict current consumer contracts, and explicit release order.
- Establish correctness over compatibility as the policy across every early-release
repository. Add the Go client to the complete project catalog.
- Link the merged implementation PRs and published releases. Record verified
registry dependencies, immutable REST pins, and the released Bundle Action v2.
- Enforce Markdown and local document/asset links in a minimal read-only CI job.
105 changes: 105 additions & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Coordinated breaking release: declared label targets

Released 2026-09-06 after coordinated review and verification. This document is
the organization announcement, breaking migration guide, and upgrade order.

Early Treetop releases prioritize correctness over compatibility across every
repository. Breaking changes must be intentional, tested, announced, and supplied
with concrete migration steps. Remove obsolete aliases and defaults instead of
preserving ambiguous behavior behind compatibility layers.

## One owner per declared tuple

Label ownership is `(fully qualified Cedar resource type, attribute name)`.
`App::Host.labels` and `Other::Host.labels` are independent. Two rules cannot own
`App::Host.labels`; combine their patterns under one declaration or rename an
output. A root type such as `Host` is exact, not a wildcard or an alias for every
namespaced Host.

```json
{
"target": {"resource_type": "App::Host", "attribute": "labels"},
"field": "name",
"patterns": [{"name": "prod", "regex": "^prod"}]
}
```

Replace old `kind` and `output` fields with this target. Labelers declare a
validated `LabelTarget` and implement read-only `derive`; `applies_to` and `output`
are removed. Receiver-style `LabelerApply::apply` owns mutation. Core freezes
ownership at registration, rejects duplicate tuples and reserved `id`, matches
exact resource types, and clears every owned attribute on that type before any
rule derives its output. Repeated applications replace or remove owned values.

Scoping includes sanitation. An `App::Host` owner does not clear attributes on
`Other::Host`. Policies must constrain the actual resource type before trusting a
derived attribute. Bundle delegates runtime application to Core; clients and the
workbench consume the server contract and do not implement policy evaluation.

## Required consumer updates

| Repository | Release | Review | Required update |
| --- | --- | --- | --- |
| Core | [0.1.0](https://crates.io/crates/treetop-core/0.1.0) | [PR #60](https://github.com/treetop-policy-engine/treetop-core/pull/60) | Implement `target` and `derive`, use validated targets, remove deprecated listing aliases |
| Bundle | [0.1.0](https://github.com/treetop-policy-engine/treetop-bundle/releases/tag/v0.1.0) | [PR #10](https://github.com/treetop-policy-engine/treetop-bundle/pull/10) | Declare targets, adopt format 2, rebuild and re-sign archives |
| REST | [0.1.0](https://github.com/treetop-policy-engine/treetop-rest/releases/tag/v0.1.0) | [PR #73](https://github.com/treetop-policy-engine/treetop-rest/pull/73) | Deploy new configurations and archives; adopt current endpoints and metadata |
| Rust SDK | [0.1.0](https://crates.io/crates/treetop-client/0.1.0) | [PR #15](https://github.com/treetop-policy-engine/treetop-client/pull/15) | Remove deprecated constructors/health alias; use required metadata and separate schema revisions |
| CLI | [0.1.0](https://github.com/treetop-policy-engine/treetop-cli/releases/tag/v0.1.0) | [PR #9](https://github.com/treetop-policy-engine/treetop-cli/pull/9) | Upgrade the SDK/server pair and remove legacy response assumptions |
| Python | [0.1.0](https://pypi.org/project/treetop-client/0.1.0/) | [PR #13](https://github.com/treetop-policy-engine/treetop-client-python/pull/13) | Use uniform batch methods, canonical decisions, required metadata, and complete response correspondence |
| Go | [0.3.0](https://pkg.go.dev/github.com/treetop-policy-engine/treetop-client-go@v0.3.0) | [PR #4](https://github.com/treetop-policy-engine/treetop-client-go/pull/4) | Use current metadata, `Live`/`Ready`, and distinct schema revision types |
| Frontend | [0.1.0](https://github.com/treetop-policy-engine/treetop-frontend/releases/tag/v0.1.0) | [PR #4](https://github.com/treetop-policy-engine/treetop-frontend/pull/4) | Use exact target fields and strict generated/current responses; rebuild demos |
| Bundle Action | [2.0.0 / v2](https://github.com/treetop-policy-engine/treetop-bundle-action/releases/tag/v2.0.0) | [PR #8](https://github.com/treetop-policy-engine/treetop-bundle-action/pull/8) | Require CLI 0.1.0, format 2, and exact checksum asset names |
| Organization | Documentation | This announcement | Adopt the shared early-release correctness policy and rollout guidance |

Bundle and module manifests now require `format_version = 2`. Old manifests,
archives, signatures over old archives, and old label syntax are not migrated
implicitly. Update sources, rebuild, review diagnostics, and re-sign new bytes.
Failed reloads leave the previous complete authorization generation active.

Use `/livez`, `/readyz`, and `/openapi.json`; the legacy health and OpenAPI aliases
are removed. Policy versions require `hash`, `loaded_at`, nullable `label_set`, and
unsigned 64-bit `generation`. Generation is local to an engine instance. Schema
revisions are separate hash/timestamp objects. Status includes schema metadata,
request limits, and context capabilities. An explicit zero limit never means
unlimited. JavaScript rejects integers it cannot represent exactly.

Use authorization evaluation as the source of truth. Candidate policy listings
do not execute Cedar conditions and can include forbids; they are never proof of
permission. Clients reject inconsistent batch counts, positions, IDs, versions,
and decision details. Parsing errors must never become allow decisions.

## Upgrade and release order

Every consumer uses published prerequisites. Bundle requires Core 0.1.0 from
crates.io; REST requires Core and Bundle 0.1.0; CLI requires Rust SDK 0.1.0.
Temporary Cargo Git patches are removed, with registry checksums in the application
and fuzz lockfiles. Rust SDK, Python, Go, and CLI integration checks pin the REST
release image by digest; the frontend pins its exact released source commit.
Action v2 checks both the released Bundle source and the actual published CLI
assets on every native platform.

Upgrade in this order:

1. Core 0.1.0 for embedded Rust applications and custom labeler implementations.
2. Bundle 0.1.0 and its `treetop-bundle` validation CLI, updated format 2 sources,
and rebuilt/re-signed archives.
3. REST 0.1.0 with the new configuration and archive contract.
4. Rust SDK/Python 0.1.0 and Go 0.3.0 against the released REST contract.
5. `treetop-cli`/Workbench 0.1.0 and Bundle Action v2 after their prerequisites are
available.

The coordinated PRs are squash-merged in dependency order. Release tags point to
verified main commits; package archives and runtime artifacts are checked before
downstream publication. Future releases must preserve substantive migration notes,
keep immutable tags fixed, and pass performance/security checks.

## Performance considerations

Declared Cedar types are parsed and validated during construction/reload, not
on each evaluation. Core's new cold target parsing cost is reported separately
from registration and evaluation; benchmark boundaries must stay explicit.
Go's required-field validation currently adds about 4–5% to local response-parse
medians while retaining allocation counts. Python reports no CodSpeed regressions,
but earlier comparisons included an environment warning, so the reported
improvement is not treated as a controlled performance measurement. Each implementation PR
contains its verification evidence and limitations.
22 changes: 18 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Treetop is an open-source authorization stack built on
[Cedar](https://cedarpolicy.com/). It separates access-control policy from application code and
provides a consistent path from authoring and validation to deployment, evaluation, and operations.

Most applications use Treetop through the standalone REST service. Official Rust and Python
Most applications use Treetop through the standalone REST service. Official Rust, Go, and Python
clients, a command-line client, and a browser workbench cover integration and day-to-day operation.
The Rust engine powers the service and remains available for specialized deployments that require
in-process evaluation.
Expand All @@ -17,7 +17,7 @@ in-process evaluation.

- Make fine-grained authorization explicit, testable, and independent of application business
logic.
- Make centralized authorization straightforward to deploy and consume through a stable REST API
- Make centralized authorization straightforward to deploy and consume through a strict REST API
and typed clients.
- Retain an embeddable Rust engine for specialized applications that need in-process evaluation.
- Package independently owned policy modules into deterministic, verifiable release artifacts.
Expand All @@ -38,7 +38,7 @@ The wider toolchain provides:
- optional Ed25519 signing and verification of policy bundles;
- atomic bundle loading in the REST server;
- authorization, policy, schema, bundle, OpenAPI, and metrics endpoints;
- typed Rust and Python integrations;
- typed Rust, Go, and Python integrations;
- native command-line tools for authorization and bundle workflows;
- a browser workbench for requests, policies, schemas, server status, and metrics; and
- a GitHub Action for policy validation and unsigned bundle builds in CI.
Expand All @@ -58,6 +58,18 @@ Cedar policies, schemas, and labels
Specialized Rust applications can use `treetop-core` directly when a separate service is not the
right deployment model.

## Coordinated breaking release

The coordinated release adopts declared label ownership by exact Cedar resource type
and attribute. Early Treetop releases prioritize correctness over compatibility;
ambiguous ownership, deprecated aliases, and old-format defaults are removed.
Bundle/module format 2 requires rebuilt and re-signed archives.

Core, Bundle, REST, Rust/Python clients, CLI, and Workbench are released as 0.1.0;
the Go client is 0.3.0 and Bundle Action is v2. See the
[breaking migration and release set](./MIGRATION.md) for the new syntax, required consumer
updates, published artifacts, and upgrade order.

## Projects

All repositories below are maintained parts of the Treetop project. Together they provide the REST
Expand All @@ -68,6 +80,7 @@ runtime, policy engine and delivery pipeline, client integrations, and operator
| [treetop-rest](https://github.com/treetop-policy-engine/treetop-rest) | Standalone authorization server and REST API |
| [treetop-client](https://github.com/treetop-policy-engine/treetop-client) | Typed asynchronous Rust client |
| [treetop-client-python](https://github.com/treetop-policy-engine/treetop-client-python) | Typed synchronous and asynchronous Python client |
| [treetop-client-go](https://github.com/treetop-policy-engine/treetop-client-go) | Typed Go client with validated requests and responses |
| [treetop-cli](https://github.com/treetop-policy-engine/treetop-cli) | Command-line client and interactive REPL |
| [treetop-frontend](https://github.com/treetop-policy-engine/treetop-frontend) | Browser workbench for Treetop servers |
| [treetop-bundle](https://github.com/treetop-policy-engine/treetop-bundle) | Policy validation, composition, signing, and archive tooling |
Expand All @@ -85,5 +98,6 @@ This repository publishes organization-wide GitHub content:

When updating the profile, keep the project catalog aligned with the organization's public
repositories and published artifacts. Prefer durable links such as `/releases/latest`, registry
project pages, GHCR package pages, and moving major tags for GitHub Actions. Use relative asset paths
project pages, GHCR package pages, and reviewed immutable commits for GitHub Actions. Mark planned artifacts as
unreleased instead of linking to tags that do not exist. Use relative asset paths
and verify Markdown links before publishing changes.
33 changes: 21 additions & 12 deletions profile/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@ Run Treetop as a REST service, integrate through an official client, compose det
bundles, or inspect the service from the command line and browser workbench. The Rust engine can
also be embedded for specialized use cases.

## Coordinated breaking release

The coordinated release adopts declared label ownership by exact Cedar resource type
and attribute. Early Treetop releases prioritize correctness over compatibility;
ambiguous ownership, deprecated aliases, and old-format defaults are removed.
Bundle/module format 2 requires rebuilt and re-signed archives.

Core, Bundle, REST, Rust/Python clients, CLI, and Workbench are released as 0.1.0;
the Go client is 0.3.0 and Bundle Action is v2. See the
[breaking migration and release set](../MIGRATION.md) for the new syntax, required consumer
updates, published artifacts, and upgrade order.

## Projects

These repositories are all maintained parts of Treetop, covering the runtime, policy delivery,
Expand All @@ -21,10 +33,11 @@ client integrations, and operator tooling.
| [treetop-rest](https://github.com/treetop-policy-engine/treetop-rest) | REST API and standalone server | [server archives](https://github.com/treetop-policy-engine/treetop-rest/releases/latest) · [container](https://github.com/treetop-policy-engine/treetop-rest/pkgs/container/treetop-rest) |
| [treetop-client](https://github.com/treetop-policy-engine/treetop-client) | Typed asynchronous Rust client | [crate](https://crates.io/crates/treetop-client) · [docs](https://docs.rs/treetop-client) |
| [treetop-client-python](https://github.com/treetop-policy-engine/treetop-client-python) | Typed synchronous and asynchronous Python client | [PyPI](https://pypi.org/project/treetop-client/) |
| [treetop-client-go](https://github.com/treetop-policy-engine/treetop-client-go) | Typed Go client | [Go package](https://pkg.go.dev/github.com/treetop-policy-engine/treetop-client-go) |
| [treetop-cli](https://github.com/treetop-policy-engine/treetop-cli) | Command-line client and interactive REPL | [native archives and checksums](https://github.com/treetop-policy-engine/treetop-cli/releases/latest) |
| [treetop-frontend](https://github.com/treetop-policy-engine/treetop-frontend) | Browser workbench for policies, requests, and metrics | [static archive and checksum](https://github.com/treetop-policy-engine/treetop-frontend/releases/latest) · [container](https://github.com/treetop-policy-engine/treetop-frontend/pkgs/container/treetop-frontend) |
| [treetop-bundle](https://github.com/treetop-policy-engine/treetop-bundle) | Deterministic, optionally signed Cedar policy bundles | [crate](https://crates.io/crates/treetop-bundle) · [docs](https://docs.rs/treetop-bundle) · [CLI archives](https://github.com/treetop-policy-engine/treetop-bundle/releases/latest) |
| [treetop-bundle-action](https://github.com/treetop-policy-engine/treetop-bundle-action) | Policy validation and bundle builds in GitHub Actions | [`@v1` Action](https://github.com/treetop-policy-engine/treetop-bundle-action/tree/v1) · [releases](https://github.com/treetop-policy-engine/treetop-bundle-action/releases) |
| [treetop-bundle-action](https://github.com/treetop-policy-engine/treetop-bundle-action) | Policy validation and bundle builds in GitHub Actions | [v2.0.0](https://github.com/treetop-policy-engine/treetop-bundle-action/releases/tag/v2.0.0) · [releases](https://github.com/treetop-policy-engine/treetop-bundle-action/releases) |
| [treetop-core](https://github.com/treetop-policy-engine/treetop-core) | Rust engine underlying Treetop REST, also available for in-process deployments | [crate](https://crates.io/crates/treetop-core) · [docs](https://docs.rs/treetop-core) |

## Release artifacts
Expand All @@ -35,8 +48,8 @@ client integrations, and operator tooling.
| Treetop CLI | Linux x86-64 and ARM64 musl, Apple-silicon macOS, and Windows x86-64 archives with SHA-256 checksums |
| Bundle CLI | Linux x86-64 and ARM64 musl, Apple-silicon macOS, and Windows x86-64 archives with `SHA256SUMS` |
| Workbench | Versioned static-site archive with a SHA-256 checksum; Linux AMD64 and ARM64 container image |
| Libraries and clients | Rust crates on crates.io and the Python client on PyPI |
| Bundle Action | Versioned GitHub Action, available through the moving `v1` major tag |
| Libraries and clients | Rust crates, Python on PyPI, and versioned Go modules |
| Bundle Action | Versioned GitHub Action; v2.0.0 with the v2 major tag |

## Quick start

Expand All @@ -54,14 +67,10 @@ Then check process liveness:
curl http://127.0.0.1:9999/livez
```

Validate a policy bundle in GitHub Actions:

```yaml
- uses: treetop-policy-engine/treetop-bundle-action@v1
with:
manifest: treetop-bundle.toml
deny-warnings: true
```
The [action v2 migration](https://github.com/treetop-policy-engine/treetop-bundle-action/blob/v2.0.0/MIGRATION.md)
explains declared-target syntax and format 2 archives. Action v2 downloads the
published Bundle CLI 0.1.0 and verifies its checksum. Pin the reviewed immutable
action release commit in protected policy workflows.

Project-specific documentation, examples, compatibility information, and release notes live in
Project-specific documentation, examples, current contracts, and release notes live in
each repository.