Skip to content

agent-forwarding

Recipe card from the charly-distros plugin (Images — the deployable catalog).

agent-forwarding – SSH/GPG Agent Forwarding Support

Section titled “agent-forwarding – SSH/GPG Agent Forwarding Support”

Pure composition candy. This candy carries no shell config of its own; per-tool shell init lives in each tool’s home candy and is inherited transitively via require:. Specifically:

  • direnv hook (bash/zsh/fish) → direnv candy’s shell: block.
  • SSH_AUTH_SOCK redirect to KeePassXC’s published agent socketkeepassxc-keyring candy’s shell: block (target:local only).
  • GPG_TTY=$(tty) for the pinentry-qt → libsecret → KeePassXC chainkeepassxc-keyring candy’s shell: block.

Putting any of these in agent-forwarding would scatter ownership: the direnv hook isn’t a KeePassXC concern, KeePassXC’s socket isn’t a GPG concern. The composition stays declarative; agent-forwarding pulls in gnupg + direnv + ssh-client and inherits whatever each contributes.

Property Value
Install files charly.yml (metalayer)
Composition gnupg, direnv, ssh-client
charly.yml
my-image:
candy:
base: fedora
candy: [agent-forwarding]

Included in all application boxes (27 total). Not included in base images (fedora, arch) or builder images (fedora-builder, arch-builder).

Agent forwarding is a runtime feature — sockets are bind-mounted from the host into the container at charly shell / charly start (direct mode) invocation time. This layer provides the container-side binaries (gpg, ssh, direnv) needed to use the forwarded sockets.

Host: $SSH_AUTH_SOCK (any path)
→ Container: /run/host-ssh-auth.sock
+ SSH_AUTH_SOCK=/run/host-ssh-auth.sock (env var)

The container’s ssh and git commands automatically use the host’s SSH keys. No SSH agent runs inside the container.

Verification: charly shell <image> -c 'ssh-add -l' lists host SSH keys.

Host: S.gpg-agent (detected via gpgconf --list-dirs agent-socket)
→ Container: $HOME/.gnupg/S.gpg-agent (HOME from ai.opencharly.home label)

The container’s gpg finds the forwarded socket at its standard path. Private key operations (signing, decryption) go through the host’s agent. No GPG agent or keyboxd runs inside the container.

The container has its own keyring. Public keys must be imported separately:

Terminal window
# Export from host, import into container
gpg --export --armor KEY_ID | charly shell <image> -c 'gpg --import'

Verification: charly shell <image> -c 'gpg-connect-agent --no-autostart /bye' connects to the host agent (shows “restricted mode” — this is normal for forwarded agent sockets).

Agent socket paths are session-bound — they live under $XDG_RUNTIME_DIR and change between SSH sessions, reboots, and users. Quadlet .container files are static systemd units generated once. Baking socket paths into quadlets would cause boot failures on headless servers managed via SSH.

Agent forwarding is intentionally excluded from quadlet mode. Use charly shell or charly start (direct mode) for agent access.

Setting Default Env Var Description
forward_gpg_agent true CHARLY_FORWARD_GPG_AGENT Forward host GPG agent socket
forward_ssh_agent true CHARLY_FORWARD_SSH_AGENT Forward host SSH agent socket
Terminal window
charly settings set forward_gpg_agent false # Disable GPG forwarding globally
charly settings set forward_ssh_agent false # Disable SSH forwarding globally
charly settings reset forward_gpg_agent # Re-enable (back to default: true)
~/.config/charly/charly.yml
immich:
candy:
forward_gpg_agent: false # No GPG needed for photo management
forward_ssh_agent: false # Security: no host SSH access
charly-fedora:
candy:
forward_gpg_agent: true # Explicit (same as default)

Resolution chain: charly.yml per-box > global setting > default (true).

Command Volumes (mounts) Env vars Notes
charly shell (new container) Yes Yes Full forwarding
charly shell (exec into running) No Yes Env only; sockets from start time
charly start (direct mode) Yes Yes Full forwarding
charly cmd No Yes Exec into running container
charly config / quadlet No No Intentionally excluded

charly-arch, arch-test, comfyui, charly-fedora, fedora-test, githubrunner, immich, immich-ml, jupyter, nvidia, ollama, openclaw, openclaw-full, python-ml, selkies-desktop, selkies-labwc-nvidia, sway-browser-vnc, unsloth-studio, valkey-test

charly/agent_forward.go (socket detection, mount resolution), charly/runtime_config.go (settings).

MUST be invoked when the task involves SSH or GPG agent forwarding, the .secrets + direnv workflow inside containers, or the agent-forwarding candy. Invoke this skill BEFORE reading source code.

  • /charly-image:layer — candy authoring reference (charly.yml schema, plan steps, service declarations)
  • /charly-check:check — declarative testing (check: block, charly check box, charly check live)