trust-core
A small, language-neutral trust plane: Biscuit public-key capability tokens + a per-request Ed25519 proof-of-possession, plus a length-prefixed wire so the issuer private key can be isolated in its own signer process.
The engine holds zero app vocabulary — the policy (Datalog) and the request-facts are data
passed in — so different services share it unchanged and each supplies its own rights/scopes and
policy strings. No novel crypto: it composes the audited Rust biscuit-auth core (via
biscuit-python) and libsodium (PyNaCl).
The model
Three tiers, assigned by the containment rule — process isolation buys containment only for a component that holds a secret:
| Tier | Holds | Isolation | trust-core |
|---|---|---|---|
| 1. Signer — mint + job-sign | issuer private key | its own process | IssuerKey, mint_biscuit, sign_job |
| 2. Verifier + authorizer | issuer public key only | in-process library | authenticate, check_policy, verify_job |
| 3. App predicates | app state | stays in the app | (the consumer's adapter) |
Only tier 1 holds a secret, so only it needs to leave. Tiers 2–3 are a library the app links.
Layers
trust_core.keys—IssuerKey(mint + job-sign) andWorkerKey(a holder's PoP key). One 32-byte Ed25519 seed each; the issuer seed doubles as the Biscuit root and the job signer.trust_core.proof—RequestParts/WorkerProof/make_proof+ the header/query parsers. The canonical string bindsmethod,path, andsha256(body), so a captured signature is valid only for the one request it was made for.trust_core.engine—mint_biscuit(bind a key + arbitrary Datalog facts + expiry),authenticate(issuer-sig → identity → revocation → freshness → proof-of-possession),check_policy(one authorizer decision),sign_job/verify_job.trust_core.wire— the signer sidecar's length-prefixed JSON framing (fail-closed: oversize cap, closed-connection, non-object body).trust_core.errors— the single fail-closedTrustError.
Why the facts are parameterized
mint_biscuit binds fact values as bound Datalog parameters (never string interpolation),
so a value can never inject Datalog — a safer primitive than a raw mint(datalog_string) helper.
Example
from trust_core import IssuerKey, WorkerKey, RequestParts, make_proof, \
mint_biscuit, authenticate, check_policy
issuer, worker = IssuerKey.generate(), WorkerKey.generate()
# Issuer mints a capability binding the worker's public key.
token = mint_biscuit(
issuer, public_hex=worker.public_hex, holder_id="gpu-1",
facts={"right": ["lease"], "lane": ["transcribe"]},
revocation_id="rev-1", expires_at=now + 3600,
)
# Worker proves possession on each request; verifier authenticates then authorizes.
proof = make_proof(worker, token, RequestParts("POST", "/lease", b"{}"),
timestamp=str(now), nonce="n1")
parsed, identity = authenticate(
issuer.public_hex, proof, RequestParts("POST", "/lease", b"{}"),
now=now, revoked_ids=frozenset(), max_skew_seconds=300,
)
check_policy(parsed, request_facts={"req_right": "lease", "req_lane": "transcribe"},
allow="allow if req_right($r), right($r), req_lane($l), lane($l)", now=now)
Status
Local package (no published release yet). Consumed by easy-podcast; designed to be reused by other services (e.g. antibody-analysis) — each writes a thin adapter that maps routes → rights, supplies the policy strings, and owns its replay + data-predicates.
Metadata
Release files for trust-core 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| trust_core-0.1.0.tar.gz | 20.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| trust_core-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 37.0 kB
Release files / trust_core-0.1.0.tar.gz
| Download URL | trust_core-0.1.0.tar.gz |
|---|---|
| Size | 20.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
30aeea15379780989a507378f46558d18db66432ae400f29baeeac95fadb3008
|
|
BLAKE2b-256 checksum How to use checksums |
750b8406589814f9b6b945b02733953fbd3edb97420f383b2a9b476c6c2cc112
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 1, 2026.
Transparency logRelease files / trust_core-0.1.0-py3-none-any.whl
| Download URL | trust_core-0.1.0-py3-none-any.whl |
|---|---|
| Size | 16.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
062564818bdf075460e39a707d44b39e0e7429771dc607d6928220f854e1e2bc
|
|
BLAKE2b-256 checksum How to use checksums |
13e6d975c32da17e4789571f668381aaebdc297284f8df1e753f9c5e8911e464
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 1, 2026.
Transparency log