Creating a document often means writing two things: the document itself and a relationship saying who can read it. When they live in separate systems, a failure between writes needs recovery logic. pemba lets applications keep those writes in one database transaction. pemba is an embedded authorization engine written in Rust, with Python bindings. It evaluates relationship-based policies in your process and stores relationships in the database your application already uses. You can model document sharing, groups and organization hierarchies using a strict subset of SpiceDB’s schema language. Checks, resource/subject lookups and explain traces share that model. ## Application data and permissions in one transaction The [transactional tutorial](https://joshua-fields.github.io/pemba/docs/guides/transactional-tutorial.html) contains runnable Rust and Python examples for both SQLite and Postgres. Each example first creates an app document and grants its owner relation, then commits. Assertions confirm that the app row exists, Anne can view it and Bob cannot. The second transaction inserts another document and permission, deliberately triggers a duplicate-primary-key error, and rolls the whole app transaction back. Neither that document nor its permission survives. The app owns the transaction. Rust’s `write_in` and Python’s `write(conn=...)` join it; they do not commit it for you. They return `PendingRevision`, not proof that a commit has happened. After a successful caller commit, resolve it and make the subsequent check with `AtLeast` (Python `at_least=`). Native writes, where the engine owns the transaction, return a committed `Revision`. The stores differ before commit: - **SQLite:** the pending token already knows a number, but that revision is not readable before commit. After rollback, the number is void, can be reused and cannot prove rollback. - **Postgres:** the token resolves after commit, reports `RevisionPending` while the transaction is open and `WriteRolledBack` after rollback. Portable code resolves only after successful commit. Reads use engine-owned connections, so they do not see your app transaction’s uncommitted writes. An evaluation error is distinct from a permission denial: application code must handle errors explicitly rather than silently treating them as an authorization result. ## What 0.1.0 supports pemba 0.1.0 supports Rust/CLI and Python, with memory, SQLite and synchronous Postgres stores. SQLite app and engine operations must use the same database and one SQLite library in the process; the Python engine uses the host’s `sqlite3`. Postgres foreign writes support the documented synchronous drivers. Raw async connections are not supported. The [browser playground](https://joshua-fields.github.io/pemba/) runs a memory store and lets you explore policies. It cannot demonstrate real database transactions. Its WASM build is for the playground itself; there is no supported Node binding or general WASM package. ## Scope and limitations An embedded engine fits an app or a few services sharing a database. Choose a separate authorization service such as SpiceDB when independent deployment, distributed operation or capabilities outside pemba’s subset are requirements. There is no SpiceDB wire-API compatibility. Caveats/CEL, expiration, Watch and server/distributed mode are outside the supported scope. Read the [known differences](https://github.com/Joshua-Fields/pemba/blob/v0.1.0/crates/pemba-difftest/KNOWN_DIFFERENCES.md) and [limits](https://joshua-fields.github.io/pemba/docs/guides/troubleshooting.html) before adopting a policy. Historical reads use the current schema and are bounded by garbage collection. Postgres schema-rename recovery is not implemented. ## Getting started Begin with [installation and quick starts](https://joshua-fields.github.io/pemba/docs/guides/installation.html), then run the commit/rollback tutorial against disposable databases. For Python: python -m pip install pemba==0.1.0 Rust feature selection and CLI installation are covered in the installation guide. If upgrading from an alpha, read the [migration notes](https://github.com/Joshua-Fields/pemba/blob/v0.1.0/CHANGELOG.md) first, including the Rust extensible-type construction changes and Python’s removed `int(pending)`/index conversions. Use `.revision()` after commit or pass the pending token to `at_least=`. Useful links: - [Repository](https://github.com/Joshua-Fields/pemba) - [Rust API documentation](https://docs.rs/pemba/0.1.0/pemba/) - [Transactional tutorial](https://joshua-fields.github.io/pemba/docs/guides/transactional-tutorial.html) - [Playground](https://joshua-fields.github.io/pemba/) - [API specification](https://github.com/Joshua-Fields/pemba/blob/v0.1.0/docs/06-api.md) - [Roadmap](https://github.com/Joshua-Fields/pemba/blob/main/ROADMAP.md) Python’s binding contract is also available through installed `help(pemba.Engine)`. ## Feedback and credits Feedback on the Rust API and database integration is welcome. Ordinary bugs and requests go to [Issues](https://github.com/Joshua-Fields/pemba/issues); suspected vulnerabilities should be reported privately through [SECURITY](https://github.com/Joshua-Fields/pemba/blob/v0.1.0/SECURITY.md). The roadmap separates shipped scope from candidates, without promised dates. Support is best effort, with no response SLA or guaranteed patch. The design builds on Google’s Zanzibar paper and SpiceDB’s schema and behavior as references. The implementation is original, with no SpiceDB source copied or translated. pemba is Apache-2.0; see [credits](https://github.com/Joshua-Fields/pemba/blob/v0.1.0/README.md#credits), [LICENSE](https://github.com/Joshua-Fields/pemba/blob/v0.1.0/LICENSE) and [NOTICE](https://github.com/Joshua-Fields/pemba/blob/v0.1.0/NOTICE). 

1 post - 1 participant

Read full topic