{"id":22456361,"url":"https://github.com/Lur1an/spicedb-rust","last_synced_at":"2025-08-02T03:32:26.306Z","repository":{"id":248145339,"uuid":"827870457","full_name":"Lur1an/spicedb-rust","owner":"Lur1an","description":"Opinionated SpiceDB client in Rust","archived":false,"fork":false,"pushed_at":"2024-12-01T14:14:01.000Z","size":116,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-12-01T14:18:48.213Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Lur1an.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-12T14:58:39.000Z","updated_at":"2024-12-01T14:14:04.000Z","dependencies_parsed_at":"2024-08-05T15:29:22.085Z","dependency_job_id":null,"html_url":"https://github.com/Lur1an/spicedb-rust","commit_stats":null,"previous_names":["lur1an/spicedb-rust"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lur1an%2Fspicedb-rust","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lur1an%2Fspicedb-rust/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lur1an%2Fspicedb-rust/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lur1an%2Fspicedb-rust/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Lur1an","download_url":"https://codeload.github.com/Lur1an/spicedb-rust/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228432585,"owners_count":17918892,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-06T08:01:14.591Z","updated_at":"2024-12-06T08:02:15.177Z","avatar_url":"https://github.com/Lur1an.png","language":"Rust","funding_links":[],"categories":["Clients"],"sub_categories":["Third-party Libraries"],"readme":"# spicedb-rust\n\nAn opinionated client for SpiceDB, built on top of the official gRPC API without the suck of using gRPC in rust.\n\n## Disclaimer\nAPI not stable yet, breaking changes are possible\n\n## API\nThe API offers builder interfaces for all gRPC requests that leverage the generic trait type system to \ncut down on some request building boilerplate and potential errors/typos.\n\nSome of the most common requests are directly exposed as functions on the `Client` struct like `lookup_resources` directly into a `Vec\u003cR::Id\u003e` or a `check_permission` directly to a `bool`.\n\nAs an alternative to builder interfaces the client also exposes/will expose the methods directly with all arguments at once as parameters, if you intend to use the upcoming `mock` feature to not have to run a local `SpiceDB` instance in your tests it is recommended you do it this way.\n\nRegarding `impl Trait` parameters on the `SpiceDBClient`, those have all been removed with either generics or just `String`, `\u0026str`. This little QoL loss allows `mockall` to build a `MockSpiceDBClient`.\n\n## Type System\nThe type system of this crate allows definition of rust structs with traits that mirror the schema imported into SpiceDB. This cuts down on potential typos and other bugs that can crawl into development when typing raw strings for relationships \u0026 permissions and makes it easier to build the quite complex gRPC requests with some compile-time checks.\n\n### Pros\n- Never make an error due to passing in the wrong `String` value for a relationship or permission\n- Never try to create a relationship that does not exist for one of your entities\n- Easy way to share your permission schema across multiple services by centralizing your authz schema in a rust library crate\n- Type conversions from `String` into your chosen type of id like `u32` or `Uuid` are done automatically\n\n### Cons\n- A bit of Boilerplate\n\n### I don't like the type system, can I just use the raw gRPC API?\nYes you can. `SpiceDBClient` exposes methods to get the underlying `tonic` client, and the `spicedb` module exports all protobuf types. From personal experience, this is not fun.\n\n### Example\nLets take the following SpiceDB schema:\n```zed\ndefinition user {}\n\ndefinition document {\n    relation reader: user | user:*\n    relation writer: user\n    \n    permission read = reader + writer\n    permission write = writer\n}\n```\nWe have 2 entities, `User` and `Document`. This is the boilerplate:\n\n```rust\nstruct User;\n\nimpl Entity for User {\n    type Relations = NoRelations;\n    type Id = Uuid;\n\n    fn object_type() -\u003e \u0026'static str {\n        \"user\"\n    }\n}\n\nstruct MyActor(Uuid);\n\nimpl Actor for MyActor {\n    fn to_subject(\u0026self) -\u003e SubjectReference {\n        subject_reference_raw(self.0, User::object_type(), None::\u003cString\u003e)\n    }\n}\n\nstruct Document;\n\n#[derive(IntoStaticStr)]\n#[strum(serialize_all = \"snake_case\")]\npub enum DocumentPermission {\n    Read,\n    Write,\n}\n\nimpl Entity for Document {\n    type Relations = DocumentRelation;\n    type Id = String;\n\n    fn object_type() -\u003e \u0026'static str {\n        \"document\"\n    }\n}\n\n#[derive(IntoStaticStr)]\n#[strum(serialize_all = \"snake_case\")]\npub enum DocumentRelation {\n    Reader,\n    Writer,\n}\n\nimpl Resource for Document {\n    type Permissions = DocumentPermission;\n}\n\n```\n\u003e **_NOTE:_** The boilerplate for `Relations` and `Permissions` is gone thanks to the `IntoStaticStr` macro from the `strum` crate, this crate also re-exports it.\n\nThis type system now makes it impossible to check for a permission that doesn't exist, or create a relationship not supported for an entity. \n\n\u003e **_NOTE:_** I don't know if its possible to constrain the *Subject* part of a relationship through types, I haven't gone down this road, and I don't feel like I need to yet, I'd be curious if there is an easy way to do this.\n\nNow lets create some relationship and check some permissions!\n```rust\nlet client = SpiceDBClient::new(\"http://localhost:50051\".to_owned(), \"randomkey\")\n    .await?;\nlet user_id = Uuid::now_v7();\nlet relationships = [\n    relationship_update::\u003cUser, Document\u003e(\n        RelationshipOperation::Touch,\n        user_id,\n        None,\n        \"homework\",\n        DocumentRelation::Writer,\n    ),\n    wildcard_relationship_update::\u003cUser, Document\u003e(\n        RelationshipOperation::Touch,\n        \"manga\",\n        DocumentRelation::Reader,\n    ),\n];\nlet token = client\n    .create_relationships(relationships, [])\n    .await\n    .unwrap();\nlet actor = MyActor(user_id);\nlet authorized = client.check_permission_at::\u003c_, Document\u003e(\n    \u0026actor,\n    \"homework\",\n    DocumentPermission::Write,\n    token.clone(),\n)\n.await?;\n```\n\n## Mocking\nI haven't thought about it extensively yet. Using `mockall` won't work out of the box due to the builder pattern for the requests. Right now you can enable the integration-test feature and connect to a local SpiceDB in test mode\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLur1an%2Fspicedb-rust","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FLur1an%2Fspicedb-rust","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLur1an%2Fspicedb-rust/lists"}