spicedb

package
v0.14.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 11, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package spicedb provides SpiceDB-based authorization for SystemForge.

Index

Constants

View Source
const (
	// TypePrincipal represents a principal (user, service, agent).
	TypePrincipal = "principal"

	// TypeOrganization represents an organization.
	TypeOrganization = "organization"

	// TypeUser represents a user.
	TypeUser = "user"
)

Common resource type constants.

View Source
const (
	// PermView allows viewing a resource.
	PermView = "view"

	// PermList lets a principal see that an organization exists: every
	// membership grants it, collaborators included.
	PermList = "list"

	// PermEdit allows editing a resource.
	PermEdit = "edit"

	// PermManage allows managing a resource (admin operations).
	PermManage = "manage"

	// PermDelete allows deleting a resource.
	PermDelete = "delete"

	// PermCreate allows creating resources.
	PermCreate = "create"
)

Common permission constants.

View Source
const (
	// RelOwner represents the owner relation.
	RelOwner = "owner"

	// RelAdmin represents the admin relation.
	RelAdmin = "admin"

	// RelMember represents the member relation.
	RelMember = "member"

	// RelCollaborator represents the organization collaborator relation: a
	// principal with access to individual resources only (ADR-008).
	RelCollaborator = "collaborator"
)

Common relation constants.

View Source
const (
	// RelViewer reads the resource.
	RelViewer = "viewer"

	// RelContributor also changes the resource and creates items in it.
	RelContributor = "contributor"

	// RelMaintainer also manages the resource's settings and collaborators.
	RelMaintainer = "maintainer"
)

Resource-role relations of a collaborator-able resource definition (ADR-008), lowest first.

View Source
const BaseSchema = authz.BaseSpiceDBSchema

BaseSchema is the SystemForge base SpiceDB schema.

Deprecated: use authz.BaseSpiceDBSchema, or compose a deployment schema with authz.VocabularyRegistry.ComposeSpiceDBSchema. BaseSchema is the same schema; it previously diverged (no editor role, and members held edit), so the providers disagreed.

Variables

View Source
var ErrNoResourceGrants = errors.New("spicedb: resource grants are not configured (use WithResourceGrants)")

ErrNoResourceGrants is returned by the grant operations of a Provider built without WithResourceGrants.

Functions

func ResourceSchema

func ResourceSchema(resourceType string) string

ResourceSchema returns a SpiceDB schema definition for a custom resource type that accepts collaborators (ADR-008). It declares the resource-role ladder (viewer, contributor, maintainer) and attaches the resource to its organization, so members keep their organization-wide access and a collaborator has only the direct grant. An optional owner relation holds the resource's creator. Applications prefix resourceType with their identifier ("myapp_project") and write the fragment into their vocabulary.

Types

type CheckRequest

type CheckRequest struct {
	// ResourceType is the type of the resource (e.g., "organization", "project")
	ResourceType string
	// ResourceID is the ID of the resource
	ResourceID string
	// Permission is the permission to check (e.g., "view", "edit", "manage")
	Permission string
	// SubjectType is the type of the subject (e.g., "principal", "user")
	SubjectType string
	// SubjectID is the ID of the subject
	SubjectID string
}

CheckRequest represents a permission check request.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client provides authorization operations backed by SpiceDB.

func NewClient

func NewClient(ctx context.Context, cfg Config, logger *slog.Logger) (*Client, error)

NewClient creates a new SpiceDB client based on configuration.

func (*Client) Check

func (c *Client) Check(ctx context.Context, req *CheckRequest) (bool, error)

Check checks if a subject has a permission on a resource.

func (*Client) Close

func (c *Client) Close() error

Close closes the client connection.

func (*Client) DeleteRelationship

func (c *Client) DeleteRelationship(ctx context.Context, rel *Relationship) error

DeleteRelationship deletes a relationship tuple.

func (*Client) DeleteRelationships

func (c *Client) DeleteRelationships(ctx context.Context, filter *RelationshipFilter) error

DeleteRelationships deletes every stored relationship matching filter in one atomic request. Deleting nothing is not an error.

func (*Client) IsEmbedded

func (c *Client) IsEmbedded() bool

IsEmbedded returns true if this client is using an embedded SpiceDB instance.

func (*Client) LookupResources

func (c *Client) LookupResources(ctx context.Context, req *LookupResourcesRequest) ([]string, error)

LookupResources finds all resources a subject has permission on.

func (*Client) LookupSubjects

func (c *Client) LookupSubjects(ctx context.Context, req *LookupSubjectsRequest) ([]string, error)

LookupSubjects finds all subjects with a given permission on a resource.

func (*Client) ReadSchema

func (c *Client) ReadSchema(ctx context.Context) (string, error)

ReadSchema reads the current authorization schema.

func (*Client) ReplaceRelationships

func (c *Client) ReplaceRelationships(ctx context.Context, deletes, writes []*Relationship) error

ReplaceRelationships deletes and then writes relationship tuples in one atomic request: a reader sees either the old set or the new one. Deleting a tuple that does not exist is not an error.

func (*Client) WriteRelationship

func (c *Client) WriteRelationship(ctx context.Context, rel *Relationship) error

WriteRelationship writes a relationship tuple.

func (*Client) WriteRelationships

func (c *Client) WriteRelationships(ctx context.Context, rels []*Relationship) error

WriteRelationships writes multiple relationship tuples atomically.

func (*Client) WriteSchema

func (c *Client) WriteSchema(ctx context.Context, schema string) error

WriteSchema writes the authorization schema.

type Config

type Config = authz.SpiceDBConfig

Config holds SpiceDB client configuration. It is authz.SpiceDBConfig, the type of the `authz.spicedb` configuration key, which lives in the authz package so that loading configuration does not link the SpiceDB server.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns a default configuration for embedded mode.

type LookupResourcesRequest

type LookupResourcesRequest struct {
	// ResourceType is the type of resources to look up
	ResourceType string
	// Permission is the permission to check
	Permission string
	// SubjectType is the type of the subject
	SubjectType string
	// SubjectID is the ID of the subject
	SubjectID string
}

LookupResourcesRequest represents a request to find resources a subject can access.

type LookupSubjectsRequest

type LookupSubjectsRequest struct {
	// ResourceType is the type of the resource
	ResourceType string
	// ResourceID is the ID of the resource
	ResourceID string
	// Permission is the permission to check
	Permission string
	// SubjectType is the type of subjects to look up
	SubjectType string
}

LookupSubjectsRequest represents a request to find subjects with a permission.

type Provider

type Provider struct {
	// contains filtered or unexported fields
}

Provider implements the authz.Authorizer interface using SpiceDB.

func NewProvider

func NewProvider(client *Client, opts ...ProviderOption) *Provider

NewProvider creates a new SpiceDB authorization provider.

func (*Provider) AddOrgMember

func (p *Provider) AddOrgMember(ctx context.Context, principalID string, orgID uuid.UUID, role string) error

AddOrgMember adds a principal as a member of an organization with a specific role.

func (*Provider) AddRelationship

func (p *Provider) AddRelationship(ctx context.Context, subjectType, subjectID, relation, resourceType, resourceID string) error

AddRelationship adds a relationship between a subject and a resource.

func (*Provider) Can

func (p *Provider) Can(ctx context.Context, principal authz.Principal, action authz.Action, resource authz.Resource) (bool, error)

Can checks if a principal can perform an action on a resource.

func (*Provider) CanAll

func (p *Provider) CanAll(ctx context.Context, principal authz.Principal, actions []authz.Action, resource authz.Resource) (bool, error)

CanAll checks if a principal can perform all specified actions on a resource.

func (*Provider) CanAny

func (p *Provider) CanAny(ctx context.Context, principal authz.Principal, actions []authz.Action, resource authz.Resource) (bool, error)

CanAny checks if a principal can perform any of the specified actions on a resource.

func (*Provider) CanForOrg

func (p *Provider) CanForOrg(ctx context.Context, principal authz.Principal, orgID uuid.UUID, action authz.Action, resource authz.Resource) (bool, error)

CanForOrg checks permission scoped to a specific organization.

func (*Provider) Client

func (p *Provider) Client() *Client

Client returns the underlying SpiceDB client for advanced operations.

func (*Provider) Close

func (p *Provider) Close() error

Close closes the provider and underlying client.

func (*Provider) Filter

func (p *Provider) Filter(ctx context.Context, principal authz.Principal, action authz.Action, resources []authz.Resource) ([]authz.Resource, error)

Filter returns only the resources the principal can access with the given action.

func (*Provider) GetRole

func (p *Provider) GetRole(ctx context.Context, principal authz.Principal, orgID uuid.UUID) (string, error)

GetRole returns the principal's role in an organization.

func (*Provider) GrantResourceRole

func (p *Provider) GrantResourceRole(ctx context.Context, principalID uuid.UUID, resource authz.ResourceRef, role string, grantedBy uuid.UUID) error

GrantResourceRole gives the principal a role on the resource through the configured store, which writes the relationship to the graph. Granting to a principal with no membership in the resource's organization adds a collaborator membership.

func (*Provider) IsMember

func (p *Provider) IsMember(ctx context.Context, principal authz.Principal, orgID uuid.UUID) (bool, error)

IsMember checks if a principal is a member of an organization.

func (*Provider) IsPlatformAdmin

func (p *Provider) IsPlatformAdmin(ctx context.Context, principal authz.Principal) (bool, error)

IsPlatformAdmin checks if a principal has platform-wide admin access.

func (*Provider) ListResourceGrants

func (p *Provider) ListResourceGrants(ctx context.Context, resource authz.ResourceRef) ([]authz.Grant, error)

ListResourceGrants lists the grants on one resource, highest role first.

func (*Provider) ListResources

func (p *Provider) ListResources(ctx context.Context, principalID uuid.UUID, resourceType string, permission authz.Action) (authz.ResourceSet, error)

ListResources returns the resources of resourceType the principal holds permission (view, edit or manage) on, by SpiceDB's LookupResources. The lookup follows every relationship the schema expresses, so an organization member's access through the "org" relation is in IDs and OrganizationIDs is empty.

func (*Provider) RemoveOrgMember

func (p *Provider) RemoveOrgMember(ctx context.Context, principalID string, orgID uuid.UUID, role string) error

RemoveOrgMember removes a principal from an organization.

func (*Provider) RemoveRelationship

func (p *Provider) RemoveRelationship(ctx context.Context, subjectType, subjectID, relation, resourceType, resourceID string) error

RemoveRelationship removes a relationship between a subject and a resource.

func (*Provider) RevokeResourceRole

func (p *Provider) RevokeResourceRole(ctx context.Context, principalID uuid.UUID, resource authz.ResourceRef) error

RevokeResourceRole removes the principal's grant on the resource; revoking a collaborator's last grant removes the membership.

type ProviderOption

type ProviderOption func(*Provider)

ProviderOption configures a Provider.

func WithResourceGrants

func WithResourceGrants(g authz.ResourceGranter) ProviderOption

WithResourceGrants gives the provider the store of resource grants (ADR-008). The store owns what the graph cannot: the collaborator membership rows behind the "orgs" claim, the last-grant test and the access-change records; it mirrors grants and memberships into the graph through this package's Syncer (resourcegrant.WithAuthzSyncer). The provider delegates the grant operations to it and answers ListResources from the engine with LookupResources.

type Relationship

type Relationship struct {
	// ResourceType is the type of the resource
	ResourceType string
	// ResourceID is the ID of the resource
	ResourceID string
	// Relation is the relationship type (e.g., "owner", "member", "admin")
	Relation string
	// SubjectType is the type of the subject
	SubjectType string
	// SubjectID is the ID of the subject
	SubjectID string
}

Relationship represents a relationship tuple.

type RelationshipFilter

type RelationshipFilter struct {
	ResourceType string
	ResourceID   string
	Relation     string
	SubjectType  string
	SubjectID    string
}

RelationshipFilter selects stored relationships. ResourceType is required; empty fields match anything. SubjectID requires SubjectType.

type Syncer

type Syncer struct {
	// contains filtered or unexported fields
}

Syncer implements RelationshipSyncer using SpiceDB as the authorization backend.

func NewSyncer

func NewSyncer(client *Client) *Syncer

NewSyncer creates a new SpiceDB-backed relationship syncer.

func (*Syncer) AddAppRole

func (s *Syncer) AddAppRole(ctx context.Context, principalID, orgID uuid.UUID, application, role string) error

AddAppRole writes the principal's role in an application as a relation on the application's organization facet, "{application}_org".

func (*Syncer) AddOrgMembership

func (s *Syncer) AddOrgMembership(ctx context.Context, principalID, orgID uuid.UUID, role string) error

AddOrgMembership adds a principal's membership in an organization.

func (*Syncer) AddPrincipalManager

func (s *Syncer) AddPrincipalManager(ctx context.Context, managedID, managerID uuid.UUID, role string) error

AddPrincipalManager writes a manager relation on the managed principal.

func (*Syncer) RegisterOrganization

func (s *Syncer) RegisterOrganization(ctx context.Context, orgID, ownerID uuid.UUID) error

RegisterOrganization creates an organization with an initial owner.

func (*Syncer) RegisterPrincipal

func (s *Syncer) RegisterPrincipal(_ context.Context, _ uuid.UUID) error

RegisterPrincipal creates a principal entity in SpiceDB. SpiceDB doesn't require explicit entity creation - entities are created implicitly when relationships are added. This is a no-op but kept for interface compliance.

func (*Syncer) RemoveAppRole

func (s *Syncer) RemoveAppRole(ctx context.Context, principalID, orgID uuid.UUID, application, role string) error

RemoveAppRole deletes the principal's role in an application.

func (*Syncer) RemoveOrgMembership

func (s *Syncer) RemoveOrgMembership(ctx context.Context, principalID, orgID uuid.UUID, role string) error

RemoveOrgMembership removes a principal's membership from an organization.

func (*Syncer) RemovePrincipalManager

func (s *Syncer) RemovePrincipalManager(ctx context.Context, managedID, managerID uuid.UUID, role string) error

RemovePrincipalManager deletes a manager relation.

func (*Syncer) RemoveResourceGrant

func (s *Syncer) RemoveResourceGrant(ctx context.Context, principalID uuid.UUID, resource authz.ResourceRef) error

RemoveResourceGrant deletes every resource role the principal holds on the resource.

func (*Syncer) SetPlatformAdmin

func (s *Syncer) SetPlatformAdmin(ctx context.Context, principalID uuid.UUID, isAdmin bool) error

SetPlatformAdmin grants or revokes platform admin privileges.

func (*Syncer) SetResourceGrant

func (s *Syncer) SetResourceGrant(ctx context.Context, principalID uuid.UUID, resource authz.ResourceRef, role string) error

SetResourceGrant writes the principal's resource role as a relationship, "{type}:{id}#{role}@principal:{principal}", and deletes the other two ladder roles it may hold on the resource in the same request, so a change of role is never seen half-applied. It writes only the grant: the resource's org relation is the application's, written when it creates the resource.

func (*Syncer) UnregisterOrganization

func (s *Syncer) UnregisterOrganization(ctx context.Context, orgID uuid.UUID) error

UnregisterOrganization removes every relationship stored on an organization. Relationships an application's own definitions hold to the organization are the application's to remove.

func (*Syncer) UnregisterPrincipal

func (s *Syncer) UnregisterPrincipal(ctx context.Context, principalID uuid.UUID) error

UnregisterPrincipal removes every base-schema relationship involving a principal: its organization memberships, its platform administration, the managers of the principal, and the principals it manages. Relationships an application's own definitions hold to the principal are the application's to remove. Every deletion is attempted, and the failures are returned together.

func (*Syncer) UpdateOrgMembership

func (s *Syncer) UpdateOrgMembership(ctx context.Context, principalID, orgID uuid.UUID, oldRole, newRole string) error

UpdateOrgMembership changes a principal's role in an organization. This is implemented as an atomic batch operation: remove old role, add new role.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL