Skip to main content

Embedded SpiceDB for Python — embedded authorization using the standard gRPC API

Project description

spicedb-embedded (Python)

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.

from spicedb_embedded import EmbeddedSpiceDB
from authzed.api.v1 import (
    CheckPermissionRequest,
    CheckPermissionResponse,
    Consistency,
    ObjectReference,
    Relationship,
    SubjectReference,
)

schema = """
definition user {}

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

rel = Relationship(
    resource=ObjectReference(object_type="document", object_id="readme"),
    relation="reader",
    subject=SubjectReference(object=ObjectReference(object_type="user", object_id="alice")),
)

with EmbeddedSpiceDB.start(schema, [rel]) as spicedb:
    req = CheckPermissionRequest(
        consistency=Consistency(fully_consistent=True),
        resource=ObjectReference(object_type="document", object_id="readme"),
        permission="read",
        subject=SubjectReference(object=ObjectReference(object_type="user", object_id="alice")),
    )
    resp = spicedb.permissions().CheckPermission(req)
    allowed = resp.permissionship == CheckPermissionResponse.PERMISSIONSHIP_HAS_PERMISSION

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.

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.

from spicedb_embedded import EmbeddedSpiceDB, StartOptions

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

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

options = StartOptions(
    datastore="postgres",
    datastore_uri="postgres://user:pass@localhost:5432/spicedb",
)

with EmbeddedSpiceDB.start(schema, [], options=options) as spicedb:
    # Use full Permissions API (writeRelationships, checkPermission, etc.)
    pass

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

pip install spicedb-embedded

Or from source:

cd python && pip install -e .

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 (shared/c, ../shared/c, etc.). Override with SPICEDB_LIBRARY_PATH=/path/to/shared/c.

Usage

from spicedb_embedded import EmbeddedSpiceDB
from authzed.api.v1 import (
    CheckPermissionRequest,
    CheckPermissionResponse,
    Consistency,
    ObjectReference,
    Relationship,
    SubjectReference,
)

schema = """
definition user {}

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

rel = Relationship(
    resource=ObjectReference(object_type="document", object_id="readme"),
    relation="reader",
    subject=SubjectReference(object=ObjectReference(object_type="user", object_id="alice")),
)

with EmbeddedSpiceDB.start(schema, [rel]) as spicedb:
    stub = spicedb.permissions()
    req = CheckPermissionRequest(
        consistency=Consistency(fully_consistent=True),
        resource=ObjectReference(object_type="document", object_id="readme"),
        permission="read",
        subject=SubjectReference(object=ObjectReference(object_type="user", object_id="alice")),
    )
    resp = stub.CheckPermission(req)
    allowed = resp.permissionship == CheckPermissionResponse.PERMISSIONSHIP_HAS_PERMISSION

API

  • EmbeddedSpiceDB.start(options=) — Start an instance without bootstrapping schema or relationships. Supports context manager (with).
  • EmbeddedSpiceDB.start(schema, relationships, options=) — Start an instance and bootstrap it with schema and optional relationships. Supports context manager (with).
  • permissions() — Permissions service stub (CheckPermission, WriteRelationships, ReadRelationships, etc.).
  • schema() — Schema service stub (ReadSchema, WriteSchema, ReflectSchema, etc.).
  • watch() — Watch service stub for relationship changes.
  • channel() — Underlying gRPC channel for custom usage.
  • close() — Dispose the instance and close the channel.

Use types from authzed.api.v1 (ObjectReference, SubjectReference, Relationship, etc.).

StartOptions

from spicedb_embedded import EmbeddedSpiceDB, StartOptions

options = StartOptions(
    datastore="memory",  # or "postgres", "cockroachdb", "spanner", "mysql"
    datastore_uri="postgres://user:pass@localhost:5432/spicedb",  # required for remote
)

with EmbeddedSpiceDB.start(schema, [], options=options) as spicedb:
    ...

Metrics & Tracing

Metrics are disabled by default. Set metrics_enabled=True to turn them on.

Prometheus — exposes http://localhost:9090/metrics for scraping:

options = StartOptions(
    metrics_enabled=True,
    metrics_port=9090,
)

OpenTelemetry traces — pushes to an OTLP gRPC collector (insecure):

options = StartOptions(
    metrics_enabled=True,
    otlp_endpoint="localhost:4317",
)

Both can be combined. datastore_metrics_enabled and cache_metrics_enabled default to True when metrics_enabled is set; pass False to opt out of either.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

spicedb_embedded-0.7.0.tar.gz (9.7 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

spicedb_embedded-0.7.0-py3-none-win_amd64.whl (10.2 kB view details)

Uploaded Python 3Windows x86-64

spicedb_embedded-0.7.0-py3-none-manylinux_2_28_x86_64.whl (9.7 kB view details)

Uploaded Python 3manylinux: glibc 2.28+ x86-64

spicedb_embedded-0.7.0-py3-none-manylinux_2_28_aarch64.whl (9.8 kB view details)

Uploaded Python 3manylinux: glibc 2.28+ ARM64

spicedb_embedded-0.7.0-py3-none-macosx_11_0_arm64.whl (26.9 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

File details

Details for the file spicedb_embedded-0.7.0.tar.gz.

File metadata

  • Download URL: spicedb_embedded-0.7.0.tar.gz
  • Upload date:
  • Size: 9.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for spicedb_embedded-0.7.0.tar.gz
Algorithm Hash digest
SHA256 7e7a00c3db03ea1c9607841b73cb2b71ef20c1865de7753cbbb6d6b22ef0012e
MD5 f7e97c8eeabe5ef20b234f53e4cc95b2
BLAKE2b-256 2e8a9a4f46af5b112fd022263532c389a54bb26cd81994ea407be65aa4fb7cc0

See more details on using hashes here.

Provenance

The following attestation bundles were made for spicedb_embedded-0.7.0.tar.gz:

Publisher: publish.yml on borkfork/spicedb-embedded

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file spicedb_embedded-0.7.0-py3-none-win_amd64.whl.

File metadata

File hashes

Hashes for spicedb_embedded-0.7.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 1d4a81a88a1d4659396afac72a72d4bb1a1c9a2b35205e2e6b4231e553f56a49
MD5 a3aa0b1d2326605a238d0fad43ad48ca
BLAKE2b-256 c6a3da7c8768f52e33551b5a92eb37312fb76df85f671c9d812c501f65cc64a4

See more details on using hashes here.

Provenance

The following attestation bundles were made for spicedb_embedded-0.7.0-py3-none-win_amd64.whl:

Publisher: publish.yml on borkfork/spicedb-embedded

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file spicedb_embedded-0.7.0-py3-none-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for spicedb_embedded-0.7.0-py3-none-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 b1be65c592f71e5aa28a9f1862bbb95cbf3ff6e4a73c122f8f8b1b6feed36e1a
MD5 a5daab8096afc74dfdc04d7d20b9ea97
BLAKE2b-256 3ec48161772c2f4d8629dbf79e35720a979c09117a1731cae43ae8784ad4490c

See more details on using hashes here.

Provenance

The following attestation bundles were made for spicedb_embedded-0.7.0-py3-none-manylinux_2_28_x86_64.whl:

Publisher: publish.yml on borkfork/spicedb-embedded

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file spicedb_embedded-0.7.0-py3-none-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for spicedb_embedded-0.7.0-py3-none-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 8d830abb91ef70e3222cc0419a2c027f15cc83dff84d9447f7f7dab8c5bae2d5
MD5 7f1cdc1f88087b74ac84132605e17b94
BLAKE2b-256 a471974378fe2684c783eae4f65d88f91d0cc16fbb68066a6359e09090440785

See more details on using hashes here.

Provenance

The following attestation bundles were made for spicedb_embedded-0.7.0-py3-none-manylinux_2_28_aarch64.whl:

Publisher: publish.yml on borkfork/spicedb-embedded

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file spicedb_embedded-0.7.0-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for spicedb_embedded-0.7.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 37826aed123223f6bf6436a9b81aaf1b25869b844b3f396ddcd983e00472b528
MD5 201c763e96eb794e01543c8f199b194d
BLAKE2b-256 fe171f7920995ced61f078b50ae2bdb7cf9915bee1e78d07bf46c920a21b9b3f

See more details on using hashes here.

Provenance

The following attestation bundles were made for spicedb_embedded-0.7.0-py3-none-macosx_11_0_arm64.whl:

Publisher: publish.yml on borkfork/spicedb-embedded

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page