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(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.
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.
from spicedb_embedded import EmbeddedSpiceDB
# 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
}
"""
with EmbeddedSpiceDB(schema, [], options={
"datastore": "postgres",
"datastore_uri": "postgres://user:pass@localhost:5432/spicedb",
}) 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(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(schema, relationships, options=None)— Create an instance. Pass[]for no initial relationships. Passoptionsdict for datastore/transport config. 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.).
Options
options = {
"datastore": "memory", # or "postgres", "cockroachdb", "spanner", "mysql"
"datastore_uri": "postgres://user:pass@localhost:5432/spicedb", # required for remote
"spanner_credentials_file": "/path/to/key.json", # Spanner only
"spanner_emulator_host": "localhost:9010", # Spanner emulator
"mysql_table_prefix": "spicedb_", # MySQL only (optional)
"metrics_enabled": False, # default; set True to enable Prometheus metrics
}
with EmbeddedSpiceDB(schema, [], options=options) as spicedb:
...
Building & Testing
mise run shared-c-build
cd python
pip install -e ".[dev]"
pytest
Or from the repo root: mise run python-test
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file spicedb_embedded-0.5.2.tar.gz.
File metadata
- Download URL: spicedb_embedded-0.5.2.tar.gz
- Upload date:
- Size: 8.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d7e0dd708200d9d4860dd62f6a91d90d9c339d323e07335e13929a6923d86354
|
|
| MD5 |
e39fecc8fcde2b434c675194e8b7c2f4
|
|
| BLAKE2b-256 |
dbcb10fcb9222dcdf3676b1cf24a8df78d5c117c263865ec5405c455f7048f0b
|
Provenance
The following attestation bundles were made for spicedb_embedded-0.5.2.tar.gz:
Publisher:
publish.yml on borkfork/spicedb-embedded
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
spicedb_embedded-0.5.2.tar.gz -
Subject digest:
d7e0dd708200d9d4860dd62f6a91d90d9c339d323e07335e13929a6923d86354 - Sigstore transparency entry: 978575978
- Sigstore integration time:
-
Permalink:
borkfork/spicedb-embedded@b1bcf65c2e443a9fea121d4362a543b0c445bcb3 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/borkfork
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b1bcf65c2e443a9fea121d4362a543b0c445bcb3 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file spicedb_embedded-0.5.2-py3-none-win_amd64.whl.
File metadata
- Download URL: spicedb_embedded-0.5.2-py3-none-win_amd64.whl
- Upload date:
- Size: 9.3 kB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e0320b659fa2c21f2b8eba9177264b40ffd696c96082aec43aff206bfa14352a
|
|
| MD5 |
40ea2c36c2482f53a930e83b936f1bd2
|
|
| BLAKE2b-256 |
16d32667fe2d8d60b4a5e13d5f403c7817edf2a2aacba03c22d7054ff69c81a0
|
Provenance
The following attestation bundles were made for spicedb_embedded-0.5.2-py3-none-win_amd64.whl:
Publisher:
publish.yml on borkfork/spicedb-embedded
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
spicedb_embedded-0.5.2-py3-none-win_amd64.whl -
Subject digest:
e0320b659fa2c21f2b8eba9177264b40ffd696c96082aec43aff206bfa14352a - Sigstore transparency entry: 978576142
- Sigstore integration time:
-
Permalink:
borkfork/spicedb-embedded@b1bcf65c2e443a9fea121d4362a543b0c445bcb3 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/borkfork
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b1bcf65c2e443a9fea121d4362a543b0c445bcb3 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file spicedb_embedded-0.5.2-py3-none-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: spicedb_embedded-0.5.2-py3-none-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 8.8 kB
- Tags: Python 3, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
39fc220b22248052329f185ad4c83fc23617006b195759003028c570b2be0a6c
|
|
| MD5 |
4e1945ca872ab0928c00ecdb2e6577cc
|
|
| BLAKE2b-256 |
120870e95b4a07b6c71d33c201d1fe712ec4b8671acbda416492e3169445d3ed
|
Provenance
The following attestation bundles were made for spicedb_embedded-0.5.2-py3-none-manylinux_2_28_x86_64.whl:
Publisher:
publish.yml on borkfork/spicedb-embedded
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
spicedb_embedded-0.5.2-py3-none-manylinux_2_28_x86_64.whl -
Subject digest:
39fc220b22248052329f185ad4c83fc23617006b195759003028c570b2be0a6c - Sigstore transparency entry: 978576103
- Sigstore integration time:
-
Permalink:
borkfork/spicedb-embedded@b1bcf65c2e443a9fea121d4362a543b0c445bcb3 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/borkfork
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b1bcf65c2e443a9fea121d4362a543b0c445bcb3 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file spicedb_embedded-0.5.2-py3-none-manylinux_2_28_aarch64.whl.
File metadata
- Download URL: spicedb_embedded-0.5.2-py3-none-manylinux_2_28_aarch64.whl
- Upload date:
- Size: 9.3 kB
- Tags: Python 3, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed2545fd174d90e84754dfd4d3ef253a3aba58cc76106dd7d205ecfd76a0628a
|
|
| MD5 |
b10faaa85358b699a5e0df53c6fcd1fd
|
|
| BLAKE2b-256 |
35bc5c39347c442906ee882da67fa41c0e51a584db06d203c37c30ddc30bf9dd
|
Provenance
The following attestation bundles were made for spicedb_embedded-0.5.2-py3-none-manylinux_2_28_aarch64.whl:
Publisher:
publish.yml on borkfork/spicedb-embedded
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
spicedb_embedded-0.5.2-py3-none-manylinux_2_28_aarch64.whl -
Subject digest:
ed2545fd174d90e84754dfd4d3ef253a3aba58cc76106dd7d205ecfd76a0628a - Sigstore transparency entry: 978576020
- Sigstore integration time:
-
Permalink:
borkfork/spicedb-embedded@b1bcf65c2e443a9fea121d4362a543b0c445bcb3 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/borkfork
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b1bcf65c2e443a9fea121d4362a543b0c445bcb3 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file spicedb_embedded-0.5.2-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: spicedb_embedded-0.5.2-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 25.6 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dbf39d5ac3599db5400b0465a62f95e5dc6172c9f6a862a85d6702d062018e9d
|
|
| MD5 |
ae040c8071705b972e0c2c439fd06e4a
|
|
| BLAKE2b-256 |
645be9b9b9bb51d1951f65707863281a7042e6b915da0cfee2501cc5c42e00be
|
Provenance
The following attestation bundles were made for spicedb_embedded-0.5.2-py3-none-macosx_11_0_arm64.whl:
Publisher:
publish.yml on borkfork/spicedb-embedded
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
spicedb_embedded-0.5.2-py3-none-macosx_11_0_arm64.whl -
Subject digest:
dbf39d5ac3599db5400b0465a62f95e5dc6172c9f6a862a85d6702d062018e9d - Sigstore transparency entry: 978576053
- Sigstore integration time:
-
Permalink:
borkfork/spicedb-embedded@b1bcf65c2e443a9fea121d4362a543b0c445bcb3 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/borkfork
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b1bcf65c2e443a9fea121d4362a543b0c445bcb3 -
Trigger Event:
workflow_dispatch
-
Statement type: