Authenticated Celln host issuer service¶
Historical record
This page records a Celln development milestone (September 2026). Interfaces and limits it describes may since have changed or been replaced by the Celln fleet. For current behaviour see Celln Backend and Celln Fleet Installation.
sympozium celln-tool serve-issuer --config /absolute/issuer.json runs the
managed issuer on the Celln host. The controller can request bounded provisioning
over TLS without mounting the host's profile store or provider credential files.
This is a controller-only service, not a tenant API or an execution endpoint.
It is wired into registered automatic AgentRun issuance through the
controller bridge; Helm can mount the
controller's endpoint/credential configuration. The chart does not install this
host service or automatically distribute admitted artifacts.
An administrator-managed systemd unit and installation procedure
are now provided separately. They preserve explicit host provisioning and require
runtime qualification; the command's existing process proofs do not establish
that the systemd sandbox and installed filesystem layout work on a target host.
Operator configuration¶
Supply an explicit kubeconfig with read-only access to the configured approval ConfigMaps, Agents, AgentRuns, AgentRuntimes and CellnTools. The client is uncached; tenant RBAC must deny writes to approval sources. No Kubernetes Secrets are read by the issuance protocol. Run on the host with the independently managed Celln policy/artifact root, credential mapping and Celln binary described in local issuance.
{
"apiVersion": "sympozium.ai/celln-issuer-service-v1",
"listen": "127.0.0.1:8788",
"certificateFile": "/etc/sympozium-issuer/tls.crt",
"privateKeyFile": "/etc/sympozium-issuer/tls.key",
"tokenFile": "/etc/sympozium-issuer/controller-token",
"cellnBinary": "/usr/local/bin/celln",
"policyRoot": "/var/lib/celln",
"composerPublisher": "<64-hex independently approved composer key>",
"profileLifetimeMs": 300000,
"sweepIntervalMs": 5000,
"bindings": [{
"agent": {"namespace": "team-a", "name": "assistant"},
"operatorGrants": {"namespace": "operators", "name": "team-a-operator"},
"runtimeGrants": {"namespace": "operators", "name": "team-a-runtime"},
"agentGrants": {"namespace": "operators", "name": "team-a-agent"},
"modelPolicy": {"namespace": "operators", "name": "team-a-model"}
}]
}
The composer value is a placeholder, not a test trust root. Four distinct authority sources and a distinct Agent binding are required. Configuration is strict JSON bounded to 1 MiB; paths must be absolute. Lifetime must be 1–300000 ms and sweep interval 1000–30000 ms. There is no legacy/non-expiring service mode. Changing the configuration requires a controlled service restart.
sympozium --kubeconfig /etc/sympozium-issuer/kubeconfig \
celln-tool serve-issuer --config /etc/sympozium-issuer/issuer.json
TLS 1.3 is mandatory even on loopback; there is no plaintext or skip-verification flag. Supply a certificate trusted by the controller with the correct hostname or IP SAN. Restrict host/firewall/cluster ingress to the controller. NetworkPolicy, certificate issuance/rotation and production installation remain deployment qualification work, not a guarantee supplied by this command.
The separate controller bearer credential must be an independently generated high-entropy token, 24–4096 visible ASCII bytes, in an operator-only file. It is not the Celln dispatch credential or model API key. The service rereads it per request; rotate by atomically replacing the file. Missing, malformed, duplicate or wrong credentials refuse. TLS key/certificate reload requires restart.
Protocol¶
Both endpoints require Authorization: Bearer ... over TLS, with no query
parameters. Responses carry Cache-Control: no-store.
GET /v1/issuer/status:sympozium.ai/celln-issuer-status-v1, localprovisioningGateOpen,executionAuthorized: false, andartifactReadiness: not_checked. A closed gate returns 503. An open gate is not Kubernetes availability, selection readiness or permission to dispatch.POST /v1/issuances: JSONsympozium.ai/celln-issuer-request-v1containingfrozen,approvaland actual materializedartifactsfrom catalogue planning. Unknown fields, trailing JSON, non-JSON/compressed bodies and bodies exceeding 1 MiB refuse. Host paths, tokens, authority-source configuration, runtime commands and certificate/readiness assertions are not accepted request fields.
The host revalidates every observation against its own configured live sources,
authenticates signed artifacts, performs KVM sealed member verification and
creates the bounded profile/grant through the managed lifecycle gate. A caller
cannot authorize a different Agent or substitute approval sources through the
request. The response is sympozium.ai/celln-issuer-response-v1, with issued,
executed: false and artifactReadiness: not_checked. Model credentials and host
credential paths do not appear in the result. Errors are deliberately generic.
At most two authenticated handlers proceed concurrently; excess work returns 429. Managed issuance itself serializes with reconciliation. Request work has a 90-second context budget, with bounded HTTP header/body/idle/write timeouts. Signals close the listener/gate and cancel in-flight issuance before joining the service and reconciler. Host expiry remains the admission bound after a crash.
A lost response is an ambiguous delivery of a durably journaled outcome, not permission to refresh expiry or execute again. Retry only the identical frozen request; the original profile/grant/window identity remains fixed. Never mint a new run or execution ID merely to resolve a network error. There is no upload, signing, provider-call, dispatch or automatic replay endpoint here.
Evidence and remaining integration¶
Tests exercise the actual HTTPS server, credential rotation/refusal, strict request handling, bounded concurrency and shutdown. The explicit KVM test uses real signed composition → TLS request → managed provisioning → actual sealed member verification → identical retry → approval deletion → periodic withdrawal → host refusal. Kubernetes is still a fake client and no model calls are made.
The verified client provides strict remote response
validation and an operator issue-remote command. Durable registered controller
issuance, pinned serving-process prewarm, catalogue-backed dispatch and correlated
real-model results are implemented. UI/YAML selection and the authenticated
API-pod/browser journey have separate evidence; see the
MLP installation checklist.
The live catalogue test's CELLN_LIVE_ISSUER_PROCESS=1 mode launches the actual
serve-issuer executable with its strict file configuration and explicit Kind
kubeconfig. It uses verified TLS status before submitting, then the ordinary
model-result and periodic approval-withdrawal assertions. This mode is distinct
from the original in-process server fixture. The test uses a private host state
root with fresh per-run issuer/router/backend credentials and self-signed TLS
identities pinned by the test clients. The isolated browser's UI token remains
public test data. This is not a production credential/bootstrap recipe.
The standalone-issuer/browser evidence
records a passing real-model run with that command, deployed API and fresh
browser result visit, including periodic model-policy withdrawal and host refusal.
Supported host service installation, full pod-to-host network/RBAC/TLS and durable-storage upgrade qualification, automatic artifact distribution, conversations and final release acceptance remain open. Do not treat localhost test endpoints as addresses reachable from controller Pods.