Composable control-plane configuration¶
The Python SDK does not require PostgreSQL, OIDC, KMS or Kubernetes. Those are independent
deployment choices. Settings can be constructed directly for an embedded control plane or
loaded from equivalent EDITH_* environment variables for the FastAPI service.
Minimal local control plane¶
from edith_hermes_control_plane.config import Settings
settings = Settings(
database_url="sqlite+aiosqlite:///./edith-hermes.db",
auth_mode="none",
enabled_runtime_providers=["external", "process", "container"],
require_digest_pinned_base=False,
require_image_scan=False,
require_image_signature=False,
)
This topology has one durable SQLite file, no bearer-token requirement, no KMS operation and no
cluster dependency. The container provider talks to the Docker-compatible API selected by the
normal Docker environment (DOCKER_HOST, contexts and credential helpers). The process provider
executes hermes serve and gives each instance its own HERMES_HOME.
Runtime providers¶
Set EDITH_RUNTIME_PROVIDERS to a comma-separated subset of:
| Kind | Required request fields | Lifecycle ownership |
|---|---|---|
external |
runtime.endpoint pointing to a bridge HTTP URL or native WebSocket |
Adopt only; external supervisor owns the process |
process |
Optional executable, command, hermesHome |
Starts and terminates a local child process |
container |
image or managedImageId |
Creates, starts, stops and removes a Docker-compatible container and volume |
kubernetes |
image or managedImageId; optional placement |
Reconciles a Deployment, Service, Secret and PVC |
nous_cloud |
Adapter-specific runtime.cloud values |
Delegates provision/scale/delete to EDITH_CLOUD_INVOKE_URL |
The runtime provider is stored in each instance's runtimeIdentity, so later lifecycle calls are
routed back to the same provider. Pools preserve the provider declared by their template.
State backends¶
sqlite+aiosqlite:///./file.dbis the default and is appropriate for one control-plane process.sqlite+aiosqlite:///:memory:is useful for ephemeral tests.postgresql+asyncpg://...supports durable jobs shared safely by multiple API/worker replicas.
All backends store resources, jobs, logs, ownership, leases and idempotency records through the same SQLAlchemy repository. PostgreSQL is only needed for multi-replica job claiming; it is not part of a Hermes instance.
SQLite queues access through one connection per database object and uses WAL; keep it on a local filesystem. Atomic job and lease claims are tested on both databases. This is not general multi-writer pool reconciliation or crash-recovery certification; use one controller for pool resizing/deletion.
Authentication modes¶
EDITH_AUTH_MODE |
Behavior |
|---|---|
none |
No Authorization header. Uses EDITH_ANONYMOUS_TENANT_ID and EDITH_ANONYMOUS_SUBJECT_ID, optionally overridden by X-Edith-Tenant and X-Edith-Subject. |
static |
Bearer tokens resolve through the JSON EDITH_DEV_TOKENS map. Useful for private/local services. |
oidc |
JWT signature, issuer, audience, time claims, tenant claim and subject claim are validated through JWKS. |
The Python remote client accepts token=None, so the same generated methods work in every mode.
Image policy¶
The following controls are independent:
EDITH_REQUIRE_DIGEST_PINNED_BASEEDITH_REQUIRE_IMAGE_SCANEDITH_REQUIRE_IMAGE_SIGNATURE
When signing is disabled, no Cosign key or KMS exists in the request path. When enabled,
EDITH_COSIGN_KEY may be any key URI supported by Cosign, including a local key, hardware-backed
key or cloud KMS URI. Building images is optional: container and Kubernetes requests can use a
direct runtime.image, while external and process runtimes need no image.
Local process/container environment.secretRef values resolve through
EDITH_SECRET_PROVIDER=environment (EDITH_SECRET_<NAME>_<KEY>) or
EDITH_SECRET_PROVIDER=files (EDITH_SECRET_DIRECTORY/<name>/<key>). Kubernetes secret
references remain native Kubernetes Secret references.
Hardened Kubernetes profile¶
For the 0.4.0 duplex protocol, build the bridge from this checkout and explicitly
set EDITH_RUNTIME_BRIDGE_IMAGE to that image/digest. Existing v0.3.1 image tags
in the reference deployment are older releases, not automatically updated by a
source push.
deploy/control-plane/production.yaml explicitly opts
into PostgreSQL, OIDC, Kubernetes, digest pinning, Trivy and Cosign/KMS. It is one deployment
profile, not an SDK requirement.
Native connection ownership¶
The control plane retains one authenticated RPC WebSocket per native connection descriptor; the HTTP runtime bridge retains one per application worker. Hermes owns native sessions on those sockets. Keep one bridge worker per runtime and route direct-WebSocket instances to a stable control-plane worker. PostgreSQL job locks alone do not provide distributed native session ownership or failover. After a connection loss, a new call reconnects without replaying the interrupted command; resuming the native session may still be required. Interactive server requests use the explicit duplex API, not the RPC-only connection.