Context: standard scales (rogue, hydramancer) are a plain HTTP image plus routing labels. Some scales are "special" and today their special-ness is set by hand-typed incus flags at launch. buildkit, for example, needed security.privileged, security.nesting, a custom entrypoint, and must stay off the public edge. Hand config is exactly the drift anti-pattern hydraskin exists to remove.
Goal: let a scale DECLARE its non-default needs in its deploy spec, so special scales (builders, the git-push watcher) are reproducible rather than hand-configured. hydraskin stays a generic infrastructure provider: it accepts generic knobs and never learns what a builder is.
Generic knobs to support (keep the set small):
- isolation: unprivileged (default) | nesting | vm. Prefer VM isolation over a raw privileged flag (see security).
- entrypoint: command/args override.
- internal: no public route (default). A public route requires an explicit user.hydra.domain label.
- env / secret refs: inject config and secrets at plant time, never baked into the image.
- disk: persistent state at a path (constrain the host source path).
- resources: cpu and memory caps.
Security model (learn from hcloud):
- Strong isolation beats poking holes. A privileged container is host root; a container escape owns the node and every co-located scale. hcloud never hands you host root, it gives you a VM. So special scales that need real power (buildkit) should run as Incus VMs, not privileged containers. Offer isolation: vm and avoid privileged where possible.
- Scoped, revocable tokens, never the master key. A workload like the git-push watcher must not carry the hydracluster admin token (fleet root). Mint a least-privilege, revocable token scoped to the actions it needs (launch and update scales on specific nodes). This is the same principle #207 brought to iamnim.
- Internal by default. No public route unless explicitly labelled. An unauthenticated builder port must never sit on the public edge; keep builders on the private bridge and prefer mTLS.
- Secrets injected, not baked, and auditable. Secrets via env or secret-ref at plant time, never in image layers or logs; node-exec actions auditable.
- Policy lives above hydraskin. hydraskin enforces the mechanism (the knobs). Which scales may request a VM or a scoped token is deploy-spec policy and review, not hydraskin domain knowledge.
Acceptance:
- A scale can declare isolation (unprivileged|nesting|vm), entrypoint, internal, env/secret refs, disk, and resources in its deploy spec, and hydraskin applies them reproducibly.
- buildkit runs as a declared VM scale, with no hand-typed privileged flags.
- The git-push watcher uses a scoped, revocable hydracluster token, not the admin token.
- Scales are internal by default; a public route requires an explicit domain label.
Cross-reference: #406 (hydraskin container host role), #492 (git-push-to-deploy pipeline, which needs the builder and watcher scales).