-
Notifications
You must be signed in to change notification settings - Fork 0
pulumi
The pulumi recipe ships the pinned CLI, opens egress to api.pulumi.com / get.pulumi.com, and
forwards the login you already have on the host instead of asking you to re-authenticate inside
the sandbox.
Pulumi keeps its state in ~/.pulumi:
| File | What it is |
|---|---|
credentials.json |
The backend URL + a long-lived Pulumi access token (plaintext) |
plugins/ |
Downloaded resource-provider plugins (hundreds of MB; slow to re-fetch) |
workspaces/, logs/
|
Per-stack bookkeeping |
The recipe declares that directory as a scope: global persist entry, so the pod bind-mounts the
real host ~/.pulumi read-write:
persist:
- scope: global
path: ~/.pulumi
init:
run: export PULUMI_HOME="$HOST_HOME/.pulumi"A scope: global mount is path-preserving — host /home/you/.pulumi appears in the pod at
/home/you/.pulumi. But the pod's $HOME is /home/harnessed, so the CLI's default lookup
($HOME/.pulumi) would miss the mount entirely. The launcher exports HOST_HOME (the host's real
home) into the attach shell alongside PROJECT_DIR / MAIN_REPO_DIR / CONTAINER_WORKSPACE_DIR /
HOST_WORKSPACE_DIR, and the recipe's init: points Pulumi at the mirrored path. Any recipe that
mounts a host dotdir this way needs the same one-liner.
The mount is default-deny: ~/.pulumi is credential-bearing, so harnessed refuses to mount it
until you say so. Launching without that opt-in fails and prints the exact line to add.
# 1. Log in on the HOST (Pulumi Cloud, or `pulumi login --local`/S3/etc — any backend).
pulumi login
# 2. Permit the mount. Use the EXPANDED path (no `~`), one path per line.
echo "$HOME/.pulumi" >> ~/.config/harnessed/persist-allowlist
# 3. Launch. `pulumi whoami` in the pod now answers as you.The allowlist lives at $XDG_CONFIG_HOME/harnessed/persist-allowlist (default
~/.config/harnessed/persist-allowlist); # starts a comment. A handful of dirs (~/.ssh,
~/.aws, ~/.gnupg, ~/.config/harnessed, and $HOME itself) are hard-denied and cannot be
allowlisted at all — ~/.pulumi deliberately is not among them, which is what makes this forwarding
possible.
This is a real credential handed to the agent, and you should choose it deliberately:
- The pod can read
credentials.json— a long-lived token with your full Pulumi Cloud rights. There is no touch-gate (unlike the 1Password SSH agent) and no short-lived exchange (unlike the AWS SSO ECS-server path, which hands the pod only temporary STS creds). Pulumi has no agent protocol; forwarding the login is forwarding the token. - The mount is read-write and shared with the host: a
pulumi plugin rminside the pod removes it from your host cache too. That sharing is also the win — no re-downloading providers per pod.
If that is more trust than you want to extend, use the secret path instead.
PULUMI_ACCESS_TOKEN takes precedence over credentials.json, so it composes with (or entirely
replaces) the mount. Wire it through varlock/1Password — see the secrets guide:
# in ~/.config/harnessed/.env.schema
PULUMI_ACCESS_TOKEN=op(op://Private/Pulumi/credential)Prefer this when:
- you're in CI / headless (no host login to forward), or
- you want a scoped, short-lived, revocable token rather than your host's, or
- you don't want the agent able to read your host credential file at all — in which case also drop
the
persist:entry by overriding the recipe in your user overlay catalog (~/.config/harnessed/catalog, which wins on clash).
Either way, nothing is ever baked into the image.
# The mount landed (path-preserving — same path as on the host):
harnessed exec <instance> -- sh -c 'echo $PULUMI_HOME; ls $PULUMI_HOME'
# The login is live inside the pod:
harnessed exec <instance> -- pulumi whoamiIf pulumi whoami says you are logged out, check that step 2's allowlist line is the expanded
path (/home/you/.pulumi, not ~/.pulumi) and that the host login actually exists
(ls ~/.pulumi/credentials.json).
- Container filesystem — persist mounts — the scope × location matrix and the allowlist gate
-
Recipe authoring —
persist:— the schema - Secrets — the varlock/1Password path
- AWS SSO — the contrasting model: a broker handing out short-lived creds
Start Here
Guides
- Recipe authoring
- Service authoring
- Stacks
- Extending stacks (proposed)
- Recipe catalog
- System prompt & rules (proposed)
- Secrets
- AWS SSO
- Pulumi (host login forwarding)
- Egress & exposing services
- Container filesystem
- Git hooks
- Troubleshooting
- Pin management (harnessed update)
Codebase Map
Planning & Roadmap
- open work: GitHub Issues
Research & Prompts
- research/ (home-folder requirements per harness, browse in-repo)
- prompts/ (reusable prompt templates, browse in-repo)