Documentation
¶
Overview ¶
Package relation defines the Tuple entity for ReBAC (Zanzibar-style relations).
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ListFilter ¶
type ListFilter struct {
TenantID string `json:"tenant_id,omitempty"`
NamespacePath *string `json:"namespace_path,omitempty"`
NamespacePrefix string `json:"namespace_prefix,omitempty"`
ObjectType string `json:"object_type,omitempty"`
ObjectID string `json:"object_id,omitempty"`
Relation string `json:"relation,omitempty"`
SubjectType string `json:"subject_type,omitempty"`
SubjectID string `json:"subject_id,omitempty"`
SubjectRelation string `json:"subject_relation,omitempty"`
Limit int `json:"limit,omitempty"`
Offset int `json:"offset,omitempty"`
}
ListFilter contains filters for listing relation tuples.
type Store ¶
type Store interface {
// CreateRelation persists a new relation tuple.
CreateRelation(ctx context.Context, t *Tuple) error
// GetRelation returns a relation tuple by ID within a tenant. Returns
// ErrRelationNotFound when no tuple has that ID in the tenant, including
// when the ID belongs to another tenant.
GetRelation(ctx context.Context, tenantID string, relID id.RelationID) (*Tuple, error)
// DeleteRelation removes a relation tuple by ID within a tenant. Returns
// ErrRelationNotFound when the tuple is not in the tenant.
DeleteRelation(ctx context.Context, tenantID string, relID id.RelationID) error
// DeleteRelationTuple removes the relation tuple with exactly this
// composite key, subject relation included: an empty subjectRelation
// names the direct tuple (group:eng) and leaves the subject set
// (group:eng#member), and "member" names the subject set and leaves the
// direct tuple. Deleting a key that matches nothing is not an error.
DeleteRelationTuple(ctx context.Context, tenantID, namespacePath, objectType, objectID, relation, subjectType, subjectID, subjectRelation string) error
// ListRelations returns relation tuples matching the filter.
ListRelations(ctx context.Context, filter *ListFilter) ([]*Tuple, error)
// CountRelations returns the number of tuples matching the filter.
CountRelations(ctx context.Context, filter *ListFilter) (int64, error)
// ListRelationSubjects returns tuples where the given object has the
// specified relation in any of the given namespace paths. Pass the
// request namespace and its ancestors (see warden.AncestorNamespaces) to
// honor namespace inheritance, or a single-element slice for an exact
// lookup. An empty slice matches any namespace.
// limit caps the fan-out of a single hop; 0 means the backend default of
// 1000.
ListRelationSubjects(ctx context.Context, tenantID string, namespacePaths []string, objectType, objectID, relation string, limit int) ([]*Tuple, error)
// ListRelationObjects returns tuples where the given subject has the
// specified relation in the given namespace.
// limit caps the number of tuples returned; 0 means the backend default
// of 1000.
ListRelationObjects(ctx context.Context, tenantID, namespacePath, subjectType, subjectID, relation string, limit int) ([]*Tuple, error)
// CheckDirectRelation reports whether a direct relation exists between
// subject and object in any of the given namespace paths. Pass the request
// namespace and its ancestors to honor namespace inheritance, or a
// single-element slice for an exact lookup. An empty slice matches any
// namespace.
CheckDirectRelation(ctx context.Context, tenantID string, namespacePaths []string, objectType, objectID, relation, subjectType, subjectID string) (bool, error)
// DeleteRelationsByObject removes all relation tuples for an object.
DeleteRelationsByObject(ctx context.Context, tenantID, objectType, objectID string) error
// DeleteRelationsBySubject removes all relation tuples for a subject.
DeleteRelationsBySubject(ctx context.Context, tenantID, subjectType, subjectID string) error
// DeleteRelationsByTenant removes all relation tuples for a tenant.
DeleteRelationsByTenant(ctx context.Context, tenantID string) error
}
Store defines persistence operations for relation tuples (ReBAC).
type Tuple ¶
type Tuple struct {
ID id.RelationID `json:"id" db:"id"`
TenantID string `json:"tenant_id" db:"tenant_id"`
NamespacePath string `json:"namespace_path,omitempty" db:"namespace_path"`
AppID string `json:"app_id" db:"app_id"`
ObjectType string `json:"object_type" db:"object_type"`
ObjectID string `json:"object_id" db:"object_id"`
Relation string `json:"relation" db:"relation"`
SubjectType string `json:"subject_type" db:"subject_type"`
SubjectID string `json:"subject_id" db:"subject_id"`
SubjectRelation string `json:"subject_relation,omitempty" db:"subject_relation"`
Metadata map[string]any `json:"metadata,omitempty" db:"metadata"`
CreatedBy string `json:"created_by,omitempty" db:"created_by"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
}
Tuple represents a relationship between a subject and an object. Inspired by Google Zanzibar / SpiceDB / OpenFGA.
user:alice#member@group:engineering document:readme#viewer@user:bob folder:root#parent@document:readme
NamespacePath places the tuple in the namespace tree. Tuples cascade the same way roles and policies do: a tuple at namespace N is in scope for a check at N and at every namespace below N, because the engine hands AncestorNamespaces(checkNamespace) to every tuple lookup a check makes (the direct check, the expression evaluator and the graph walker). A tuple at N is never matched by a check at an ancestor of N or at a sibling. ListFilter's NamespacePath is different: it is an exact match, so listing N does not return the ancestors' tuples that also apply at N.