skill-sidecar is a sandboxed skill execution framework for AI agents. It runs as a sidecar container alongside your agent, exposing a high-performance Rust HTTP API that executes CLI tools and scripts on the agent's behalf.
The agent never touches credentials or CLI tools directly — it just calls POST /skill/<name>.
Without a sidecar, your agent container needs every CLI tool, secret, and credential baked in. That means:
- A bloated image that's hard to update
- Credentials co-located with untrusted LLM-generated code
- No isolation between the reasoning layer and the execution layer
With skill-sidecar:
┌─────────────────────────┐ ┌──────────────────────────────────────┐
│ Agent Container │ │ Sidecar Container (Rust) │
│ │ │ │
│ ┌───────────────────┐ │ POST │ ┌────────────────────────────────┐ │
│ │ Agent Logic │──┼────────▶│ │ Rust HTTP Server (Axum/Tokio) │ │
│ │ │ │ │ └───────────────┬────────────────┘ │
│ │ curl localhost │ │ │ │ execve │
│ │ :8080/skill/ │ │ JSON │ ┌───────────────▼────────────────┐ │
│ │ <name> │◀─┼─────────│ │ /usr/local/bin/ │ │
│ └───────────────────┘ │ │ │ ├── gh │ │
│ │ │ │ ├── aws │ │
│ ✗ no credentials │ │ │ ├── my-script.sh │ │
│ ✗ no CLI tools │ │ │ └── my-binary │ │
│ │ │ │
└─────────────────────────┘ │ ┌────────────────────────────────┐ │
│ │ Credentials (env / secrets) │ │
│ │ ├── GH_TOKEN │ │
│ │ ├── AWS_* │ │
│ │ └── ... │ │
│ └────────────────────────────────┘ │
└──────────────────────────────────────┘
skill-sidecar is a base image — it ships no skill binaries. You bring your own:
┌─────────────────────────────────┐
│ skill-sidecar (base image) │
│ │
│ • Rust HTTP server │
│ • /usr/local/bin/ (empty) │
└────────────────┬────────────────┘
│ FROM skill-sidecar
▼
┌─────────────────────────────────┐
│ your-sidecar (your image) │
│ │
│ COPY gh /usr/local/bin/│
│ COPY aws /usr/local/bin/│
│ COPY my-script /usr/local/bin/│
└─────────────────────────────────┘
Any executable in /usr/local/bin/ is automatically available for dispatch.
POST /skill/<name> # execute a skill
GET /task/<id> # poll async task result
GET /healthz # health check
Request:
{
"args": ["arg1", "arg2"],
"env": { "SKILL_FOO": "bar" },
"stdin": "optional input",
"timeout": 30
}env— onlySKILL_*keys accepted; others rejected with400timeout— default 30s, max 300s; requests > 30s return atask_idfor async polling- Request body capped at 1 MB
Response (sync):
{ "status": "ok", "stdout": "...", "stderr": "...", "exit_code": 0 }Response (async):
{ "status": "pending", "task_id": "550e8400-e29b-41d4-a716-446655440000" }| Concern | Mitigation |
|---|---|
Credential hijack via env |
Only SKILL_* keys accepted |
Command injection via args |
execve directly — no shell |
| Unauthenticated callers | X-Skill-Token shared-secret header |
| Resource exhaustion | 300s timeout cap; 1 MB body limit |
| Task enumeration | Task IDs are UUID v4 |
- Rust + Axum + Tokio — async, single static binary
- Binds
127.0.0.1:8080only — not exposed outside the pod - Completed tasks expire after 1 hour; background reaper runs every 10 minutes
helm repo add skill-sidecar https://thepagent.github.io/skill-sidecar
helm repo update
helm install my-agent skill-sidecar/skill-sidecar
# Use your own image (e.g. with yt-dlp bundled)
helm install my-agent skill-sidecar/skill-sidecar \
--set image.repository=myrepo/my-sidecar \
--set image.tag=latest \
--set env.GH_TOKEN=xxx \
--set skillToken=my-secret
# Validate deployment
helm test my-agenthelm test verifies:
/healthzreturnsok- Non-
SKILL_*env keys are rejected with400
| Example | Description |
|---|---|
examples/with-yt-dlp |
Base image + yt-dlp |
examples/with-gh |
Base image + GitHub CLI |
skill-sidecar/
├── src/ # Rust HTTP server (Axum)
├── examples/ # Sample custom images
├── charts/ # Helm chart
└── Dockerfile