Krun
krun
¶
Krun (KVM-microVM) host-side provisioning: identity + runtime factory.
KrunHost is the host-side companion to
sandbox's KrunRuntime. One instance per
launch bundles the three things the orchestrator needs:
- the vault-backed
%hostkeypair materialised to tmpfs (cached, so the vault DB is opened once even whenruntimeandlaunch_argsare both called); - a production
KrunRuntimewith the TCP-over-passt SSH transport wired in; - the extra
podman runarguments terok must splice in (pubkey bind-mount, runtime-signal env var,--user rootoverride, and the pasta DNS forwarder).
Living in executor (rather than terok) keeps the rule honest: anything that owns the L0 build path also owns the trust material that makes the resulting guest reachable. Selecting krun without provisioning the key is a contradiction, so the two operations belong together.
KrunHostKeypair(private_path, public_path, public_line, fingerprint, created)
dataclass
¶
Materialised view of the %host infrastructure keypair.
Returned by ensure_krun_host_keypair.
Carries the tmpfs path to the OpenSSH-PEM private key (ready for
ssh -i) and the matching public-key file (ready to bind-mount
into the krun guest at /etc/ssh/authorized_keys.d/terok), so
callers don't have to redo the DER→PEM conversion or re-derive
the public line from raw blobs.
private_path
instance-attribute
¶
tmpfs path holding the OpenSSH-PEM private key (0600 perms).
public_path
instance-attribute
¶
Sibling .pub file (0644 perms) carrying the public line.
public_line
instance-attribute
¶
Single-line OpenSSH public key (ssh-ed25519 AAAA… comment).
fingerprint
instance-attribute
¶
Canonical SHA256:… fingerprint over the SSH wire-format blob.
created
instance-attribute
¶
True when this call minted the key; False when it was loaded.
KrunHost(*, cfg=None)
¶
Host-side krun launch context — vault keypair + runtime + launch args.
One instance per launch. The first access to
keypair opens the vault DB
and materialises the %host private/public keypair to tmpfs;
every subsequent access on the same instance reuses the cached
result, so calling both runtime
and launch_args pays
that cost only once.
Requires the vault to be unlocked — the krun runtime is gated on
experimental: true upstream and assumes the operator has the
vault open for the session. A NoPassphraseError from the
underlying vault open propagates unchanged so the orchestrator can
render its own remediation hint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cfg
|
SandboxConfig | None
|
Sandbox config used to open the credential DB. |
None
|
Bind a krun launch to cfg; the keypair is loaded on first access.
Source code in src/terok_executor/krun.py
__slots__ = ('_cfg', '_keypair')
class-attribute
instance-attribute
¶
keypair
property
¶
Vault-backed %host keypair materialised to tmpfs (cached).
First access opens the vault DB and writes the OpenSSH-PEM private + public-key line to a tmpfs cache directory; subsequent accesses on the same instance return the same object without reopening the vault.
runtime()
¶
Construct a production KrunRuntime in one call.
Wires together the three production pieces — the cached host
keypair, the TCP-over-passt SSH transport, and a fresh
PodmanRuntime for lifecycle.
The experimental-flag gate stays on the orchestrator side (this
factory is reachable only when the gate is open).
Source code in src/terok_executor/krun.py
launch_args()
¶
Extra podman run args terok must splice in for a krun launch.
Four things that all reach across the orchestrator/runtime
boundary into executor's domain — the L0 image, the host
keypair, the in-guest init-ssh-and-repo.sh, and the DNS
forwarder address — so they live here together rather than
being open-coded in terok's _project_runtime_flags:
- Bind-mount the live host pubkey over the L0's empty
placeholder at
/etc/ssh/authorized_keys.d/terok.zis the shared SELinux relabel (neverZ— the host pubkey is host-wide and concurrent containers share the source). - Set
TEROK_CONTAINER_RUNTIME=krunso the init script's krun gate fires. - Override the L0's
USER devdirective with--user rootso the in-guest sshd can start, listen on TCP 22, and drop to the authenticated user on connection.USER devis the right default under crun (AI agents that refuse uid 0); under krun the session uid comes from whichssh user@…the operator picks. --dns 169.254.1.1— kept for shield-bypass; under shield-up the bind-mounted resolv.conf overrides this anyway.
Doesn't include --runtime krun itself or krun's microVM-sizing
annotations — those are orchestrator-level decisions terok keeps.
Source code in src/terok_executor/krun.py
ensure_krun_host_keypair(*, cfg=None, runtime_dir=None)
¶
Load (or mint, first call) the %host keypair and materialise it to tmpfs.
The vault is the system of record: the keypair lives in the sandbox
credential DB under the %host infrastructure scope. This
helper opens the DB, calls
ensure_infra_keypair (which
generates the key on first call and reloads it thereafter), and
writes the OpenSSH-PEM private + the public-key line into
runtime_dir (default:
namespace_runtime_dir()).
The orchestrator bind-mounts public_path into the running
krun guest at /etc/ssh/authorized_keys.d/terok so the
guest's sshd accepts our private key. The L0 image itself ships
an empty placeholder at that path; the bind-mount overlays it.
Rotation = clear the %host scope in the vault, then re-run.
Typically called per task launch under krun (idempotent — loads
on subsequent calls). New tasks pick up the new key; in-flight
tasks keep what they had until they're stopped.
Requires the vault to be unlocked — the krun runtime is gated on
experimental: true upstream and assumes the operator has the
vault open for the session. A NoPassphraseError propagates
unchanged so the orchestrator can render its own remediation hint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cfg
|
SandboxConfig | None
|
Sandbox config used to open the credential DB. |
None
|
runtime_dir
|
Path | None
|
Override for the tmpfs cache directory. |
None
|