SpiceDb
No description available
Install / Use
/learn @JalexSocial/SpiceDbREADME
SpiceDb is an open-source, Zanzibar-inspired authorization system that provides a robust and scalable solution for managing fine-grained permissions across distributed systems. Its implementation closely follows the principles set out in Google's Zanzibar paper, adapting them into a practical and deployable system.
SpiceDb was created by AuthZed and documentation specifically for SpiceDb can be found on their site.
SpiceDb.net Documentation
SpiceDb.net was created by Michael Tanczos and has contributions from Pavel Akimov, Mahesh Bailwal, Vincius Gajo, Topher Davis and others. Documentation for SpiceDb.net is in progress and can be found here: https://jalexsocial.github.io/spicedb.docs/
What's New?
1.6.2
- @topherdavis discovered a memory leak when using ReadRelationshipsAsync and provided a fix
1.6.1
- updates GRPC dependencies
1.6.0
- Dropped .NET 7 dependency and introduced new targets for .NET 8 and .NET 9
1.5.3
- BREAKING CHANGE: The constructors for
SpiceDbClientnow accept a nullableschemaPrefixinstead of a required string. If not provided, it defaults to null. - @williamgraver added empty schema prefix handling for dedicated version of SpiceDb
- @dystopiandev exposed ReadSchemaAsync method
1.5.2
- BREAKING CHANGE: ReadRelationships now accepts a SubjectFilter (thanks to @epbensimpson) for the second parameter along with an optional relationship limit and cursor
- BREAKING CHANGE: DeleteRelationshipsAsync utilizes an optional SubjectFilter (thanks to @epbensimpson) instead of a RelationshipFilter
- BREAKING CHANGE: DeleteRelationshipsAsync returns a DeleteRelationshipsResponse object with the ZedToken and deletion progress instead of just the ZedToken
1.5.1
- @nexthash added caveat handling for relationship creation
- added WriteSchemaAsync method to client
- added additional unit tests
Usage
Install
Available on Nuget at https://www.nuget.org/packages/SpiceDb
Install the package using NuGet
Install-Package SpiceDb
Example Using UserSecrets
using Microsoft.Extensions.Configuration;
using SpiceDb.Example;
using SpiceDb.Example.MyObjects;
using SpiceDb.Models;
// This is just to keep the server address and token private
var builder = new ConfigurationBuilder()
.AddUserSecrets(typeof(Secrets).Assembly)
.AddEnvironmentVariables();
var configurationRoot = builder.Build();
var secrets = configurationRoot.GetSection("AuthZed").Get<Secrets>();
if (secrets is null)
throw new ArgumentException("Invalid secrets configuration");
// var serverAddress = "https://grpc.authzed.com";
// Create a new client with a prefix of "arch" for all defined objects
var client = new SpiceDbClient(secrets.ServerAddress, secrets.Token, "arch");
// Add relationship where user:bob is a reader of document:firstdoc
// Note that because the schema prefix is set in the client it is not necessary to always prefix every resource definition
client.AddRelationship("arch/document:firstdoc#reader@arch/user:bob");
// This also works
client.AddRelationship("document:firstdoc#reader@user:kevin");
// Second approach to adding relationships
client.AddRelationship(new Relationship("arch/document:firstdoc", "reader", "arch/user:jacob"));
// This approach uses a little syntactic sugar to define each of the relations
client.AddRelationship(ZedUser.WithId("carmella").CanRead(ZedDocument.WithId("firstdoc")));
// Check to see if user:bob is in fact now a reader of document:firstdoc
var bobCanRead = client.CheckPermission(new Permission("arch/document:firstdoc#reader@arch/user:bob"));
Console.WriteLine($"Can user bob read document:firstdoc? {bobCanRead.HasPermission}");
// true
// This is a similar check but without adding prefixes
var kevinCanRead = client.CheckPermission(new Permission("document:firstdoc#reader@user:bob"));
Console.WriteLine($"Can user kevin read document:firstdoc? {kevinCanRead.HasPermission}");
// true
// Check to see if user:carmella is in fact now a reader of document:firstdoc
var carmellaCanRead = client.CheckPermission(ZedUser.WithId("carmella").CanRead(ZedDocument.WithId("firstdoc")));
Console.WriteLine($"Can user carmella read document:firstdoc? {carmellaCanRead.HasPermission}");
// true
API Coverage
| authzed.api.v1 method | Implemented | | ------------- | ------------- | | ReadRelationships | Yes | | WriteRelationships | Yes | | DeleteRelationships | Yes | | CheckPermission | Yes | | ExpandPermissionTree | Yes | | LookupResources | Yes | | LookupSubjects | Yes | | ReadSchema | Yes | | WriteSchema | Yes, as Import* methods | | Watch | Yes |
API Methods
SpiceDbClient Class
The SpiceDbClient class provides a client for interacting with Authzed's SpiceDb, offering methods to manipulate permission systems efficiently.
Constructors
SpiceDbClient(string token, string? schemaPrefix = null)
Initializes a new instance of the SpiceDbClient class using the default Authzed server address.
Parameters
token- Token with admin privileges for manipulating the desired permission system.schemaPrefix- Schema prefix used for the permission system.
SpiceDbClient(string serverAddress, string token, string? schemaPrefix = null)
Initializes a new instance of the SpiceDbClient class with the specified server address, token, and schema prefix.
Parameters
serverAddress- The server address of the Authzed server.token- The token with admin privileges for manipulating the desired permission system.schemaPrefix- The schema prefix used for the permission system.
Exceptions
Exception- Thrown when the server address or token is null or empty, or if the schema prefix does not meet the required format.
Methods
ReadRelationshipsAsync
Asynchronously reads a set of relationships matching one or more filters.
Parameters
resource- The filter to apply to the resource part of the relationships.subject(optional) - An optional filter to apply to the subject part of the relationships.excludePrefix(optional) - Indicates whether the prefix should be excluded from the response.zedToken(optional) - An optional ZedToken for specifying a version of the data to read.cacheFreshness(optional) - Specifies the acceptable freshness of the data to be read from the cache.
Returns
- An async enumerable of
ReadRelationshipsResponseobjects matching the specified filters.
WriteRelationshipsAsync
Atomically writes and/or deletes a set of specified relationships, with optional preconditions.
Parameters
relationships- A list of relationship updates to apply.optionalPreconditions(optional) - An optional list of preconditions that must be satisfied for the operation to commit.
Returns
- A task representing the asynchronous operation, with a
ZedToken?indicating the version of the data after the write operation.
DeleteRelationshipsAsync
Atomically bulk deletes all relationships matching the provided filters, with optional preconditions.
Parameters
resourceFilter- The filter to apply to the resource part of the relationships. The resourceFilter.Type is required; all other fields are optional.optionalSubjectFilter(optional) - An optional additional filter for the subject part of the relationships.optionalPreconditions(optional) - An optional list of preconditions that must be satisfied for the operation to commit.allowPartialDeletions(optional) - If true and a limit is specified, will delete matching found relationships up to the count specified in limit, and no more.limit(optional) if non-zero, specifies the limit on the number of relationships to be deleted. If there are more matching relationships found to be deleted than the limit specified here, the deletion call will fail with an error to prevent partial deletion. If partial deletion is needed, specify below that partial deletion is allowed. Partial deletions can be used in a loop to delete large amounts of relationships in a non-transactional manner.</param>deadline(optional) - An optional deadline for the call. The operation will be cancelled if the deadline is reached.cancellationToken(optional) - An optional token for cancelling the call.
Returns
- DeleteRelationshipsResponse object that contains a ZedToken representing the point of deletion and an indicator of deletion progress
CheckPermissionAsync
Checks permissions for a given resource and subject, optionally considering additional context.
Parameters
permission- The permission relationship to evaluate.context(optional) - An optional dictionary providing additional context information for evaluating caveats.zedToken(optional) - An optional ZedToken for specifying a version of the data to consider.cacheFreshness(optional) - Specifies the acceptable freshness of the data to be considered from the cache.
Returns
- A task representing the asynchronous operation, with a
PermissionResponseindicating the result of the permission check.
ExpandPermissionAsync
Expands the permission tree for a resource's permission or relation, revealing the graph structure. This method may require multiple calls to fully unnest a deeply nested graph.
Parameters
resource- The resource reference for which to expand the permission tree.permission- The name of the permission or relation to expand.zedToken(optional) - An optional ZedToken for specifying a version of the data to consider.cacheFreshness(optional) - Specifies the acceptable freshness of the data to be considered from the cache.
Returns
- A task representing the asynchronous operation, with an `ExpandPermissionTreeRespon
