spicedb-embedded 0.1.0

Embedded SpiceDB for Rust - in-memory authorization using the standard gRPC API
# spicedb-embedded (Rust)

Embedded [SpiceDB](https://authzed.com/spicedb) for Rust — authorization server for tests and development. Uses the shared/c C library via FFI and connects over gRPC via Unix sockets or TCP. Supports memory (default), postgres, cockroachdb, spanner, and mysql datastores.

## Installation

Add to your `Cargo.toml`:

```toml
[dependencies]
spicedb-embedded = { path = "../spicedb-embedded/rust" }
# Or from crates.io when published:
# spicedb-embedded = "0.1"
```

**Prerequisites:** Go 1.23+ with CGO enabled (to build the shared library). The Rust build script compiles the C library from Go source at build time; the crate does not ship prebuilt `.so`/`.dll`/`.dylib` binaries, so it stays portable across platforms.

## Usage

```rust
use spicedb_embedded::{v1, EmbeddedSpiceDB};

let schema = r#"
definition user {}
definition document {
    relation reader: user
    permission read = reader
}
"#;

let relationships = vec![v1::Relationship {
    resource: Some(v1::ObjectReference {
        object_type: "document".into(),
        object_id: "readme".into(),
    }),
    relation: "reader".into(),
    subject: Some(v1::SubjectReference {
        object: Some(v1::ObjectReference {
            object_type: "user".into(),
            object_id: "alice".into(),
        }),
        optional_relation: String::new(),
    }),
    optional_caveat: None,
}];

let spicedb = EmbeddedSpiceDB::new(schema, &relationships).await?;

// Check permission
let response = spicedb
    .permissions()
    .check_permission(tonic::Request::new(v1::CheckPermissionRequest {
        consistency: Some(v1::Consistency {
            requirement: Some(v1::consistency::Requirement::FullyConsistent(true)),
        }),
        resource: Some(v1::ObjectReference {
            object_type: "document".into(),
            object_id: "readme".into(),
        }),
        permission: "read".into(),
        subject: Some(v1::SubjectReference {
            object: Some(v1::ObjectReference {
                object_type: "user".into(),
                object_id: "alice".into(),
            }),
            optional_relation: String::new(),
        }),
        context: None,
        with_tracing: false,
    }))
    .await?;

let allowed = response.into_inner().permissionship
    == v1::check_permission_response::Permissionship::HasPermission as i32;
```

## API

- **`EmbeddedSpiceDB::new(schema, relationships)`** — Create an instance with schema and optional initial relationships.
- **`EmbeddedSpiceDB::new_with_options(schema, relationships, options)`** — Create with `StartOptions` (datastore, `grpc_transport`, etc.). Pass `None` for defaults.
- **`permissions()`**`PermissionsServiceClient` for CheckPermission, WriteRelationships, ReadRelationships, etc.
- **`schema()`**`SchemaServiceClient` for ReadSchema, WriteSchema, ReflectSchema, etc.
- **`watch()`**`WatchServiceClient` for watching relationship changes.

All types are re-exported from `spicedb_grpc::authzed::api::v1` as `spicedb_embedded::v1`.

### StartOptions

```rust
use spicedb_embedded::{v1, EmbeddedSpiceDB, StartOptions};

let options = StartOptions {
    datastore: Some("memory".into()),           // or "postgres", "cockroachdb", "spanner", "mysql"
    grpc_transport: Some("unix".into()),        // or "tcp"; default by platform
    datastore_uri: Some("postgres://...".into()), // required for remote
    spanner_credentials_file: None,
    spanner_emulator_host: None,
    mysql_table_prefix: None,
    metrics_enabled: None, // default false; set Some(true) to enable Prometheus metrics
};

let spicedb = EmbeddedSpiceDB::new_with_options(schema, &relationships, Some(&options)).await?;
```

## Building & Testing

```bash
cd rust
cargo build
cargo test
```

Or from the repo root: `mise run check`