KERI-governed dependency management - cryptographic source of truth for version constraints
Project description
Governed Stack
⚠️ HYPER-EXPERIMENTAL ⚠️
This package is in early development. The API may change without notice. Use at your own risk. Not recommended for production use.
KERI-governed dependency management - cryptographic source of truth for version constraints.
Problem
Version truth fragmentation across your stack:
pyproject.toml: requires-python = ">=3.10"
CI workflow: python-version: "3.12.1"
README: "Tested on Python 3.11+"
Production: Actually running 3.10.4
Team Slack: "Use 3.12, we need tomllib"
Five sources of "truth" → drift → bugs → security issues.
Solution
One cryptographic source of truth.
from governed_stack import StackManager, KERI_PRODUCTION_STACK
sm = StackManager()
stack = sm.define_stack(
name="my-project",
controller_aid="BMASTER_AID...", # WHO can modify
constraints=KERI_PRODUCTION_STACK,
rationale="Production KERI deployment",
)
# Stack SAID: EABCDxyz... (cryptographic identifier)
# Every constraint has its own SAID
# Full audit trail of changes
Architecture
┌─────────────────────────────────────────────────────────┐
│ Stack Registry │
│ Constraint SAIDs with controller AIDs and audit trail │
│ WHO approved? WHEN? WHY? → Cryptographic proof │
└──────────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ StackManager │
│ - define_stack() → creates SAIDs │
│ - check_compliance() → verifies environment │
│ - generate_pyproject() → exports with SAID refs │
│ - install_with_uv() → fast installation │
└──────────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ UV / pip │
│ Actually installs the governed versions │
└─────────────────────────────────────────────────────────┘
Key Insight: UV/pip are EXECUTION tools. Governed Stack is the GOVERNANCE layer.
Installation
# ⚠️ HYPER-EXPERIMENTAL - API may change
pip install governed-stack
# Or with UV (recommended)
uv pip install governed-stack
Quick Start
CLI Usage
# Define a governed stack
governed-stack define my-project \
--controller BMASTER_AID... \
--stack keri
# Check compliance
governed-stack check my-project
# Install dependencies
governed-stack install my-project
# Generate pyproject.toml
governed-stack generate my-project --pyproject
Python API
from governed_stack import StackManager, KERI_PRODUCTION_STACK
# Create manager
sm = StackManager()
# Define a stack
stack = sm.define_stack(
name="my-project",
controller_aid="BMASTER_AID...",
constraints={
"python": ">=3.12",
"keri": ">=1.2.0,<2.0.0",
"hio": ">=0.6.14",
},
rationale="Production KERI deployment",
)
print(f"Stack SAID: {stack.said}")
# Stack SAID: EABCDxyz...
# Check compliance
result = sm.check_compliance(stack.said)
print(f"Compliant: {result.compliant}")
# Install if needed
if not result.compliant:
success, output = sm.install_with_uv(stack.said)
# Generate pyproject.toml
toml = sm.generate_pyproject(stack.said)
print(toml)
Pre-defined Stacks
| Stack | Description |
|---|---|
MINIMAL_STACK |
Just Python + keri + hio |
KERI_PRODUCTION_STACK |
Full KERI production dependencies |
KERI_DEV_STACK |
Production + pytest, ruff, mypy |
KGQL_STACK |
KERI + lark for query language |
WITNESS_STACK |
KERI + aiohttp for witnesses |
AI_ORCHESTRATOR_STACK |
KERI + anthropic, openai |
Generated Output
# GOVERNED STACK - Do not edit manually
# Stack: my-project
# SAID: EABCDxyz...
# Controller: BMASTER_AID...
# Generated: 2026-01-24T12:00:00+00:00
[project]
requires-python = ">=3.12"
# Constraint SAID: EConstraint1...
dependencies = [
"hio>=0.6.14", # SAID: EConstraint2...
"keri>=1.2.0,<2.0.0", # SAID: EConstraint3...
]
Comparison: Traditional vs Governed
| Aspect | pyproject.toml / uv.lock | Governed Stack |
|---|---|---|
| Source of Truth | File (can drift) | Cryptographic SAID |
| Who Approved? | Git blame (mutable) | Controller AID (KEL) |
| Audit Trail | Git history | Append-only chain |
| Breaking Changes | Semver honor system | Enforced notice period |
| Cross-Project Sync | Manual | SAID reference |
| Reproducibility | Lockfile | SAID + controller chain |
Attack Scenarios (Tested)
These scenarios are implemented as tests in tests/test_attack_scenarios.py:
1. Tamper Detection
Traditional: Someone edits pyproject.toml to change a version. No cryptographic way to detect.
Governed: SAID verification fails immediately.
# Verify pyproject.toml hasn't been modified
verified, said, _ = sm.verify_pyproject(pyproject_content)
if not verified:
raise SecurityError("Dependencies have been tampered with!")
2. Silent Version Drift
Traditional: Dev has keri==1.3.0, prod has keri==1.2.0. Nobody notices.
Governed: All environments verify against the same SAID.
# All environments use same SAID
CANONICAL_SAID = "EJhnw-FDaBvlhFCRAjTjxjJKBWx7vXEOITZYxYQD9g55"
# Each environment verifies before deploy
verified, _ = sm.verify_stack(
expected_said=CANONICAL_SAID,
name="myapp",
controller_aid="BOPS_TEAM",
constraints=current_constraints,
)
3. Supply Chain Attack
Traditional: Attacker injects malicious package or downgrades to vulnerable version.
Governed: Injection or downgrade changes SAID, verification fails.
# Security team's approved constraints
approved = {"django": ">=4.2.0", "requests": ">=2.31.0"}
# Attacker tries to inject or downgrade
compromised = {"django": ">=4.2.0", "requests": ">=2.25.0", "evil-pkg": ">=1.0"}
# Different constraints = different SAID
assert compute_said(approved) != compute_said(compromised)
4. Unauthorized Modification
Traditional: Junior dev changes version, git blame shows who but not authorization.
Governed: Controller AID cryptographically bound. Unauthorized changes produce different SAID.
# Only BSENIOR_ENGINEER_AID can produce this SAID
stack = sm.define_stack(
name="company-stack",
controller_aid="BSENIOR_ENGINEER_AID",
constraints={"keri": ">=1.2.0"},
)
# Junior dev can't forge the SAID without the controller key
5. CI/CD Verification Workflow
# In CI pipeline:
APPROVED_SAID = os.environ["APPROVED_STACK_SAID"] # From secure config
# Load developer's pyproject.toml
with open("pyproject.toml") as f:
content = f.read()
# Verify before deploy
verified, _, _ = sm.verify_pyproject(content, expected_said=APPROVED_SAID)
if not verified:
sys.exit("DEPLOY BLOCKED: Dependencies don't match approved SAID")
Verification API
# Verify constraints produce expected SAID
verified, computed = sm.verify_stack(
expected_said="EABCDxyz...",
name="my-project",
controller_aid="BMASTER_AID",
constraints={"python": ">=3.12", "keri": ">=1.2.0"},
)
# Verify pyproject.toml (parses and checks embedded SAID)
verified, said, constraints = sm.verify_pyproject(pyproject_content)
# Verify requirements.txt
verified, said, constraints = sm.verify_requirements(requirements_content)
Inspired By
This project synthesizes ideas from:
KERI (Key Event Receipt Infrastructure) by Samuel M. Smith
- Self-certifying identifiers, SAIDs, TEL anchoring
- https://keri.one
Transit by Cognitect (Rich Hickey et al.)
- Handler-based type extensibility
- Ground types vs extension types
- "No opaque blobs" principle
- Self-describing prefixes
- https://github.com/cognitect/transit-format
Key Insight: Transit solved semantic type preservation across language boundaries. Governed Stack solves authorization preservation across environment boundaries. Both reject central registries as trust anchors.
Design Principles
KERI Principles
This package follows Samuel Smith's KERI design principles:
- SAIDs for Content-Addressability - Every constraint has a SAID derived from its content
- Controller AIDs for Authorization - Only the controller can modify stack constraints
- Append-Only History - Changes create new versions, never delete
- Deterministic Serialization - JSON with sorted keys ensures reproducible SAIDs
- Blake3 for Performance - Uses keripy's Diger with Blake3_256
Transit Patterns
Handler-based extensibility inspired by Transit:
- Ground Types - Built-in types with well-known verification (python, package, system, binary)
- Extension Types - User-defined types that compose on ground types
- No Opaque Blobs - Every constraint must decompose to verifiable primitives
- Self-Describing Codes - CESR-aligned type codes embedded in encoded constraints
- Forward Compatibility - Unknown types preserved for roundtrip serialization
Extension Handlers
Register custom constraint handlers for specialized verification:
from governed_stack import ConstraintHandler, register_handler, VerificationResult
class DockerImageHandler(ConstraintHandler):
@property
def code(self) -> str:
return "D" # Single-char code
@property
def type_name(self) -> str:
return "docker-image"
def serialize(self, name: str, spec: str) -> bytes:
# Deterministic serialization for SAID computation
import json
data = {"handler": self.code, "type": self.type_name, "name": name, "spec": spec}
return json.dumps(data, sort_keys=True, separators=(",", ":")).encode()
def verify(self, name: str, spec: str) -> VerificationResult:
# Check if Docker image exists with correct tag
import subprocess
result = subprocess.run(["docker", "images", "-q", f"{name}:{spec}"], capture_output=True)
found = bool(result.stdout.strip())
return VerificationResult(
verified=found,
constraint_said=self.compute_said(name, spec),
actual_value=spec if found else "",
expected_spec=spec,
message="" if found else f"Docker image {name}:{spec} not found",
handler_code=self.code,
)
# Register the handler
register_handler("docker-image", DockerImageHandler())
# Now use it in stack definitions
stack = sm.define_stack(
name="containerized-app",
controller_aid="BMASTER...",
constraints={
"python": ">=3.12",
"docker-image:myapp": "latest", # Uses DockerImageHandler
},
)
Requirements
- Python >= 3.12
- keri >= 1.2.0
- hio >= 0.6.14
- libsodium (system dependency)
Installing libsodium
# macOS
brew install libsodium
# Ubuntu/Debian
apt-get install libsodium-dev
# Fedora
dnf install libsodium-devel
License
Apache-2.0
Warning
⚠️ HYPER-EXPERIMENTAL ⚠️
This package is in early development. The API WILL change. Do not use in production without understanding the risks. This is a research project exploring KERI-governed dependency management.
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 Distribution
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 governed_stack-0.1.0.tar.gz.
File metadata
- Download URL: governed_stack-0.1.0.tar.gz
- Upload date:
- Size: 57.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
85eba9befbc039e00e923836d6a62bf3ce5041aa838bf9316daaff2858356b96
|
|
| MD5 |
e899d55508b73687baafc9e204a133d5
|
|
| BLAKE2b-256 |
782fd80687f5412619ac429a20722644408f48925bec3dfccfff3c43c16ca26f
|
File details
Details for the file governed_stack-0.1.0-py3-none-any.whl.
File metadata
- Download URL: governed_stack-0.1.0-py3-none-any.whl
- Upload date:
- Size: 44.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1190984c3c501352e9a7e71eb44378e795f09d9418069747cf0ab2e49be0ef98
|
|
| MD5 |
a5dba398d650338a752852ea089b7ee4
|
|
| BLAKE2b-256 |
fbade508742386abbae1160de2d16f976fbb3f1c66dee01048dee30ee5551c9c
|