This guide walks through configuring HashiCorp Vault as the secrets backend.
- A running Vault server with the KV v2 secrets engine enabled
- A Vault token with read/list access to the agent secrets path
- The
vaultCLI (for seeding secrets)
For local development, you can run a dev server:
vault server -dev -dev-root-token-id=my-root-token
export VAULT_ADDR=http://127.0.0.1:8200
export VAULT_TOKEN=my-root-tokenThe dev server automatically enables a KV v2 engine at secret/.
Each agent is stored as a KV v2 secret at <mount>/<base_path>/<agent-name>. With the defaults (secret mount, agents base path), the path is:
secret/agents/<agent-name>
Required fields:
| Field | Description |
|---|---|
app_id |
GitHub App ID |
installation_id |
GitHub App Installation ID |
agent_token |
RSA-SHA256 signature of the agent name, base64-encoded |
private_key |
PEM-encoded RSA private key |
identity_name |
Git commit author name |
identity_email |
Git commit author email |
# 1. Generate the agent token (sign agent name with the App's private key)
AGENT_TOKEN=$(echo -n "my-agent" | openssl dgst -sha256 -sign private-key.pem | base64 | tr -d '\n')
# 2. Write the secret to Vault (@ reads the file contents directly)
vault kv put secret/agents/my-agent \
app_id="123456" \
installation_id="78901234" \
agent_token="${AGENT_TOKEN}" \
private_key=@private-key.pem \
identity_name="My Agent" \
identity_email="my-agent@users.noreply.github.com"
# 3. Verify it was written
vault kv get secret/agents/my-agentTo add more agents, repeat for each agent name. They can share the same GitHub App (same app_id, installation_id, and private_key) but should have unique names and tokens.
If you're not using the root token, create a policy with read and list access:
# vault-policy.hcl
path "secret/data/agents/*" {
capabilities = ["read"]
}
path "secret/metadata/agents/*" {
capabilities = ["read", "list"]
}vault policy write github-auth vault-policy.hcl
vault token create -policy=github-authservices:
github-auth-service:
image: ghcr.io/youruser/github-app-auth-container:latest
environment:
- SECRETS_BACKEND=vault
- VAULT_ADDR=https://vault.example.com
- VAULT_TOKEN=${VAULT_TOKEN}
# - VAULT_TOKEN_FILE=/run/secrets/vault-token # alternative: read from file
# - VAULT_MOUNT_PATH=secret # default
# - VAULT_BASE_PATH=agents # default
networks:
- agent-networkThe service connects to Vault at startup, loads all agent secrets from the configured path, then operates entirely from memory. The Vault token is only used during startup.
If your KV v2 engine is mounted at a non-default path:
# Enable KV v2 at a custom path
vault secrets enable -path=github-apps kv-v2
# Write secrets there
vault kv put github-apps/agents/my-agent app_id=... ...
# Configure the auth service
# VAULT_MOUNT_PATH=github-apps