Summary
Add support for running a user-provided container image as an Alcove agent, with Gate sidecar for credential isolation and audit logging, and stdout capture for transcripts.
Motivation
Some agents are distributed as complete container images with their own entrypoint, dependencies, and filesystem. Rather than extracting a binary and running it inside Skiff, Alcove should be able to launch the container directly with Gate as a sidecar.
YAML Specification
name: Splunk Log Analyzer
container:
image: ghcr.io/pulp/agent-splunk:v1.0.0
args: ["--model", "claude-opus-4-6"]
env:
SPLUNK_INSECURE_SKIP_VERIFY: "true"
proxy: true # Use Gate sidecar (default: true)
timeout: 1800
profiles:
- splunk-analyzer
Challenges
Stdout capture
Skiff-init runs the agent as a child process and captures stdout. With a custom container, the entrypoint IS the agent — there's no parent process. Options:
- Entrypoint wrapper: Override the container's entrypoint with skiff-init, which then `exec`s the original entrypoint. Requires knowing the original entrypoint (inspect image manifest or require user to specify it).
- Sidecar log reader: A sidecar reads the agent container's logs via shared volume or k8s log API.
- Log driver: Configure podman/docker log driver to forward stdout to NATS.
Gate networking
Gate needs to share a network namespace with the agent. On k8s this is natural (same pod). On podman/docker, use `--network container:gate-xxx`. The agent container might have its own network expectations.
Credential injection
The agent must use HTTP clients that respect `HTTP_PROXY`/`HTTPS_PROXY` for Gate credential swapping to work. If the agent uses custom transports that bypass the proxy, credentials won't be injected.
Health/readiness
No equivalent to skiff-init's heartbeat timeout detection unless the entrypoint wrapper approach is used.
Recommended Approach
Entrypoint wrapper is the cleanest: Bridge inspects the image manifest (`podman inspect` / `docker inspect`) to get the original entrypoint, then overrides it with skiff-init which sets up NATS, env vars, and `exec`s the original command. All existing infrastructure (stdout capture, transcript, timeout, cancellation) works.
Fallback: user specifies the original entrypoint in the YAML if image inspection is unavailable.
Relationship to Executable Support
Issue #175 adds support for pre-compiled executables running inside the standard Skiff container. This issue extends that to running entire custom container images. The executable approach is simpler and covers most use cases — container support is for agents that require specific OS packages, runtimes, or filesystem layouts that can't run inside Skiff.
Summary
Add support for running a user-provided container image as an Alcove agent, with Gate sidecar for credential isolation and audit logging, and stdout capture for transcripts.
Motivation
Some agents are distributed as complete container images with their own entrypoint, dependencies, and filesystem. Rather than extracting a binary and running it inside Skiff, Alcove should be able to launch the container directly with Gate as a sidecar.
YAML Specification
Challenges
Stdout capture
Skiff-init runs the agent as a child process and captures stdout. With a custom container, the entrypoint IS the agent — there's no parent process. Options:
Gate networking
Gate needs to share a network namespace with the agent. On k8s this is natural (same pod). On podman/docker, use `--network container:gate-xxx`. The agent container might have its own network expectations.
Credential injection
The agent must use HTTP clients that respect `HTTP_PROXY`/`HTTPS_PROXY` for Gate credential swapping to work. If the agent uses custom transports that bypass the proxy, credentials won't be injected.
Health/readiness
No equivalent to skiff-init's heartbeat timeout detection unless the entrypoint wrapper approach is used.
Recommended Approach
Entrypoint wrapper is the cleanest: Bridge inspects the image manifest (`podman inspect` / `docker inspect`) to get the original entrypoint, then overrides it with skiff-init which sets up NATS, env vars, and `exec`s the original command. All existing infrastructure (stdout capture, transcript, timeout, cancellation) works.
Fallback: user specifies the original entrypoint in the YAML if image inspection is unavailable.
Relationship to Executable Support
Issue #175 adds support for pre-compiled executables running inside the standard Skiff container. This issue extends that to running entire custom container images. The executable approach is simpler and covers most use cases — container support is for agents that require specific OS packages, runtimes, or filesystem layouts that can't run inside Skiff.