CipherJob 0.3 is the Phase 3 platform release. It remains an educational/portfolio security project, not an audited remote-execution product and not a claim of hostile multi-tenant isolation.
Phase 3 adds worker-authoritative enrollment and delegated grants, leased scheduling/cancellation, stable user workspaces, container-native task images, and a resumable encrypted artifact channel. Task-image manifests are descriptive only: network, mounts/workspaces, host environment/secrets, resource limits, user mapping, timeout, and authorization remain local worker policy.
- broker cannot decrypt capability menus, job inputs, or outputs;
- broker is not trusted to authorize execution;
- Ed25519 client signatures are checked against a worker-local allowlist;
- worker replies are signed and verified against a pinned worker key;
- job request IDs are consumed once in a worker-local SQLite database;
- expiry and inner/outer routing fields are checked;
- remote Pydantic models reject unknown fields, so clients cannot smuggle
command,image, mount, or Docker options into the protocol; - Docker jobs default to read-only filesystem, no network, all Linux capabilities dropped,
no-new-privileges, resource limits, PID limits, and a bounded tmpfs; - secrets may be injected only from a locally configured host environment-variable allowlist.
Protocol v2 uses RFC 9180 HPKE Base mode with DHKEM(X25519, HKDF-SHA256), HKDF-SHA256, and ChaCha20-Poly1305. Broker-visible routing metadata is authenticated as HPKE associated data, while Ed25519 separately authenticates application senders.
The selected HPKE libraries have not made CipherJob itself audited software. Application-level authorization, expiry, replay protection, manifest anti-rollback, endpoint security, and secure client delivery remain separate responsibilities.
Docker materially reduces attack surface but does not make arbitrary hostile code safe. CipherJob therefore does not let a remote client choose arbitrary images or commands. A capability image is selected by local trusted configuration.
For genuinely hostile third-party workloads, evaluate stronger isolation such as a microVM or sandbox runtime rather than extending this MVP to arbitrary code execution.
The broker sees routing identifiers, timestamps, message kinds, ciphertext sizes, source IPs, and account-level authentication metadata.
A malicious client application can read plaintext before encryption. A web deployment must treat the delivered PWA itself as trusted software and address secure distribution/update concerns.
The broker can always drop, delay, reorder, or replay messages. Cryptography protects confidentiality/integrity/authorization, not availability.
The worker records an executable request_id before launching Docker. This prevents replay execution, but if the result is lost after execution the MVP does not currently replay the cached result. Production should store an encrypted/idempotent result for retry.
Never commit .demo/, .env, private key PEM files, or OpenAI/API tokens.
For the optional Codex capability, OPENAI_API_KEY is injected directly from the worker host into the locally configured container. It is never part of a client request and never passes through the broker.
The worker now records only metadata in a signed hash-chained audit log and supports local daily execution limits for metered capabilities. Capability menus carry an authenticated monotonic manifest version, and jobs are bound to the version from which they were selected. The local broker enforces bounded TTL, message size and queue depth.
The RFC 9180 HPKE migration is complete in Phase 2A. Public deployment remains an MVP until cross-language interoperability vectors and passkey-based relay sessions are added.
The browser PWA is now a cryptographic endpoint. Treat compromise of the JavaScript origin as client compromise: malicious JavaScript can use plaintext before encryption or invoke local non-exported keys. Production deployment therefore uses a dedicated origin, no third-party analytics scripts, and an exact-origin relay policy.
The Phase 2A relay bearer token authenticates relay resource usage only. It is not execution authority. A stolen relay credential still cannot forge an Ed25519-authorized CipherJob request, but it can consume queue/request quota. Phase 2B replaces browser long-lived bearer possession with WebAuthn/passkey sessions.
The public relay is now passwordless for normal use. WebAuthn/passkeys require user verification and produce a short-lived HttpOnly, SameSite=Strict session cookie. The browser does not store the worker relay bearer token.
Initial account bootstrap uses a high-entropy one-time secret only while the AuthState Durable Object contains zero credentials. This is a deployment bootstrap mechanism, not a reusable login password.
Browser execution authority remains separate: a passkey-authenticated browser still cannot execute a worker capability until its Ed25519 key has been authorized by an encrypted, one-time worker pairing ceremony. Pairing tokens are stored locally only as SHA-256 digests and are consumed atomically.
Cloud compromise remains insufficient to forge worker execution requests, but compromise of the PWA JavaScript origin is still client compromise because malicious JavaScript can act before encryption.
WebAuthn/passkeys protect access to relay resources and require local user verification. They do not replace CipherJob's Ed25519 execution authorization. A valid Cloudflare session without an authorized CipherJob signing key cannot make the worker execute a capability. Browser/device fingerprinting is not used as an authentication factor.
Phase 3 separates the trusted worker core from persistent user state and disposable execution sandboxes. The worker daemon remains responsible for HPKE, signatures, authorization, replay protection, policy, and scheduling. User jobs do not run inside that trusted process.
A device signing key maps locally to a stable opaque user. A user may own multiple independently revocable device keys. When a capability opts into persistent state, the worker resolves that authenticated user to a local workspace and mounts only that directory into the job container. Remote requests cannot name host paths, images, Docker flags, users, resource limits, or mounts.
The Docker backend uses --pull=never, a read-only container root, --cap-drop=ALL, no-new-privileges, bounded tmpfs, configured network policy, and explicit memory/CPU/PID limits. Worker-wide ceilings cap capability-specific resource settings. cipherjob doctor checks relevant host/runtime properties; operators should run it before accepting workloads after setup or host changes.
Workspace byte quotas in the current foundation are soft accounting limits, not kernel filesystem quotas. A job may temporarily cross its workspace byte budget before the post-run check observes the excess. Do not represent that limit as hostile-tenant disk isolation.
Rootless Docker reduces daemon/host privilege exposure but is still a shared-kernel container boundary. CipherJob does not claim ordinary Docker is sufficient for mutually hostile multi-tenant arbitrary code. Stronger sandbox backends such as gVisor or microVM isolation remain a Phase 3 extension point before such a deployment model.
Local job records support deduplicated terminal-result replay. Unfinished jobs discovered after a worker restart are marked interrupted and are not automatically re-executed, because a generic job may already have produced side effects. This is not a claim of distributed exactly-once execution. Cloud queue leases, cancellation, reconnect/resume, and artifact transfer remain subsequent Phase 3 work.