SpiceDbEmbedded 0.3.4

There is a newer version of this package available.
See the version list below for details.
dotnet add package SpiceDbEmbedded --version 0.3.4
                    
NuGet\Install-Package SpiceDbEmbedded -Version 0.3.4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SpiceDbEmbedded" Version="0.3.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SpiceDbEmbedded" Version="0.3.4" />
                    
Directory.Packages.props
<PackageReference Include="SpiceDbEmbedded" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SpiceDbEmbedded --version 0.3.4
                    
#r "nuget: SpiceDbEmbedded, 0.3.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SpiceDbEmbedded@0.3.4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SpiceDbEmbedded&version=0.3.4
                    
Install as a Cake Addin
#tool nuget:?package=SpiceDbEmbedded&version=0.3.4
                    
Install as a Cake Tool

spicedb-embedded (C# / .NET)

Sometimes you need a simple way to run access checks without spinning up a new service. This library provides an embedded version of SpiceDB in various languages. Each implementation is based on a C-shared library (compiled from the SpiceDB source code) with a very thin FFI binding on top of it. This means that it runs the native SpiceDB code within your already-running process.

using Borkfork.SpiceDb.Embedded;
using Authzed.Api.V1;

var schema = """
definition user {}

definition document {
    relation reader: user
    permission read = reader
}
""";

var rel = new Relationship
{
    Resource = new ObjectReference { ObjectType = "document", ObjectId = "readme" },
    Relation = "reader",
    Subject = new SubjectReference { Object = new ObjectReference { ObjectType = "user", ObjectId = "alice" } },
};

using var spicedb = EmbeddedSpiceDb.Create(schema, new[] { rel });

var resp = spicedb.Permissions().CheckPermission(new CheckPermissionRequest
{
    Consistency = new Consistency { FullyConsistent = true },
    Resource = new ObjectReference { ObjectType = "document", ObjectId = "readme" },
    Permission = "read",
    Subject = new SubjectReference { Object = new ObjectReference { ObjectType = "user", ObjectId = "alice" } },
});
var allowed = resp.Permissionship == CheckPermissionResponse.Types.Permissionship.HasPermission;

Who should consider using this?

If you want to spin up SpiceDB, but don't want the overhead of managing another service, this might be for you.

If you want an embedded server for your unit tests and don't have access to Docker / Testcontainers, this might be for you.

If you have a schema and set of permissions that are static / readonly, this might be for you.

Who should avoid using this?

If you live in a world of microservices that each need to perform permission checks, you should almost certainly spin up a centralized SpiceDB deployment.

If you want visibility into metrics for SpiceDB, you should avoid this.

How does storage work?

The default datastore is "memory" (memdb). If you use this datastore, keep in mind that it will reset on each app startup. This is a great option if you can easily provide your schema and relationships at runtime. This way, there are no external network calls to check relationships at runtime.

If you need a longer term storage, you can use any SpiceDB-compatible datastores.

using Borkfork.SpiceDb.Embedded;

// Run migrations first: spicedb datastore migrate head --datastore-engine postgres --datastore-conn-uri "postgres://..."
var schema = """
definition user {}

definition document {
    relation reader: user
    permission read = reader
}
""";

using var spicedb = EmbeddedSpiceDb.Create(schema, Array.Empty<Relationship>(), new StartOptions
{
    Datastore = "postgres",
    DatastoreUri = "postgres://user:pass@localhost:5432/spicedb",
});
// Use full Permissions API (WriteRelationships, CheckPermission, etc.)

Running code written in Go compiled to a C-shared library within my service sounds scary

It is scary! Using a C-shared library via FFI bindings introduces memory management in languages that don't typically have to worry about it.

That being said, the SpiceDB code still runs in a Go runtime with garbage collection, which is where the vast majority of time is spent. To help mitigate some of the risk, the FFI layer is kept as straightforward as possible. protobuf is marshalled and unmarshalled at the FFI ←-> language runtime boundary in a standardized way. After unmarshalling, requests are sent directly to the SpiceDB server, and responses are returned directly back to the language runtime (after marshalling).

Installation

dotnet add package SpiceDbEmbedded

Or from source:

cd csharp && dotnet add reference ../path/to/SpiceDbEmbedded.csproj

Prerequisites: Go 1.23+ with CGO enabled. Build the shared library first:

cd shared/c && CGO_ENABLED=1 go build -buildmode=c-shared -o libspicedb.dylib .  # macOS
cd shared/c && CGO_ENABLED=1 go build -buildmode=c-shared -o libspicedb.so .      # Linux

The library looks for libspicedb.dylib (macOS) or libspicedb.so (Linux) in SPICEDB_LIBRARY_PATH or relative to the working directory. Override with SPICEDB_LIBRARY_PATH=/path/to/shared/c or SPICEDB_LIBRARY_PATH=/path/to/libspicedb.dylib.

Note: The shared/c library builds for macOS and Linux only (Unix domain sockets). Windows is not supported for the embedded server.

Usage

using Borkfork.SpiceDb.Embedded;
using Authzed.Api.V1;

var schema = """
definition user {}

definition document {
    relation reader: user
    permission read = reader
}
""";

var rel = new Relationship
{
    Resource = new ObjectReference { ObjectType = "document", ObjectId = "readme" },
    Relation = "reader",
    Subject = new SubjectReference { Object = new ObjectReference { ObjectType = "user", ObjectId = "alice" } },
};

using var spicedb = EmbeddedSpiceDb.Create(schema, new[] { rel });

var req = new CheckPermissionRequest
{
    Consistency = new Consistency { FullyConsistent = true },
    Resource = new ObjectReference { ObjectType = "document", ObjectId = "readme" },
    Permission = "read",
    Subject = new SubjectReference { Object = new ObjectReference { ObjectType = "user", ObjectId = "alice" } },
};

var resp = spicedb.Permissions().CheckPermission(req);
var allowed = resp.Permissionship == CheckPermissionResponse.Types.Permissionship.HasPermission;

API

  • EmbeddedSpiceDb.Create(schema, relationships, options?) — Create an instance. Pass null or Array.Empty<Relationship>() for no initial relationships. Pass StartOptions for datastore/transport config. Implements IDisposable.
  • Permissions() — Permissions service client (CheckPermission, WriteRelationships, ReadRelationships, etc.).
  • Schema() — Schema service client (ReadSchema, WriteSchema, ReflectSchema, etc.).
  • Watch() — Watch service client for relationship changes.
  • Channel — Underlying gRPC channel for custom usage.
  • Dispose() — Dispose the instance and close the channel.

Use types from Authzed.Api.V1 (ObjectReference, SubjectReference, Relationship, etc.).

StartOptions

var options = new StartOptions
{
    Datastore = "memory",           // or "postgres", "cockroachdb", "spanner", "mysql"
    DatastoreUri = "postgres://...", // required for postgres, cockroachdb, spanner, mysql
    SpannerCredentialsFile = "/path/to/key.json",  // Spanner only
    SpannerEmulatorHost = "localhost:9010",       // Spanner emulator
    MySqlTablePrefix = "spicedb_",                 // MySQL only (optional)
    MetricsEnabled = false,                        // default; set true to enable Prometheus metrics
};

using var spicedb = EmbeddedSpiceDb.Create(schema, relationships, options);

Building & Testing

mise run shared-c-build
cd csharp
dotnet build
dotnet test

Or from the repo root: mise run csharp-test

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.5.2 0 2/23/2026
0.5.1 0 2/23/2026
0.5.0 0 2/23/2026
0.4.3 1 2/22/2026
0.4.2 4 2/22/2026
0.3.9 79 2/17/2026
0.3.8 85 2/16/2026
0.3.7 79 2/16/2026
0.3.6 85 2/16/2026
0.3.5 84 2/15/2026
0.3.4 84 2/15/2026
0.3.3 81 2/15/2026
0.3.2 86 2/15/2026
0.3.1 83 2/14/2026
0.3.0 89 2/14/2026
0.2.6 84 2/13/2026
0.2.5 78 2/13/2026
0.2.4 81 2/13/2026
0.2.3 85 2/13/2026
0.2.2 86 2/13/2026
Loading failed