Skip to content

Running Bullpen CLI headlessly (24/7 bots)

Bullpen CLI's auth flow is RFC 8628 device-auth — it requires an interactive browser on first login. For 24/7 bots that don't have a browser, the CLI supports a portable credential file workflow: log in once on a workstation, copy the encrypted credential file to your bot host, and run headless until the refresh token expires (~30 days).

This is the recommended path until a true server-side API-key auth surface is available.


What gets copied

~/.bullpen/credentials.json.enc — AES-256-GCM-encrypted. The encryption key is derived from a stable embedded secret shared across official CLI builds, the OS username, and the BULLPEN_HOME path.

For the file to decrypt on a different host, the username and home path components of the key derivation must match. Two knobs control this:

  • BULLPEN_USERNAME_OVERRIDE — overrides the OS username in the key derivation. Set this to a stable identifier (e.g. botops) on both the workstation and the bot host.
  • BULLPEN_HOME — overrides the default ~/.bullpen directory. Set this to the same path on both hosts (e.g. /var/lib/bullpen-bot).

Without these overrides, the credential file is bound to your workstation's OS user and home dir and will fail to decrypt on the bot host.


Setup

1. Workstation (interactive login)

export BULLPEN_USERNAME_OVERRIDE=botops
export BULLPEN_HOME=/tmp/bullpen-botops          # any stable path
mkdir -p "$BULLPEN_HOME"
bullpen login                                     # opens browser, completes device-auth
bullpen doctor auth                               # confirm Token + Refresh Token both Valid

2. Bot host (headless)

# Match the workstation's overrides exactly.
export BULLPEN_USERNAME_OVERRIDE=botops
export BULLPEN_HOME=/var/lib/bullpen-bot
mkdir -p "$BULLPEN_HOME"

# Copy the encrypted credential file (and the Turnkey keypair) over.
scp workstation:/tmp/bullpen-botops/credentials.json.enc "$BULLPEN_HOME/"
scp -r workstation:/tmp/bullpen-botops/keys "$BULLPEN_HOME/"

# Verify decryption + token health.
bullpen doctor auth

If doctor auth shows Token: Valid and Refresh Token: expires in N days, you're set. The bot can run indefinitely until the refresh token expires.

3. Refresh-token rotation

The bot's refresh token has a ~30-day TTL. Bullpen's CLI auto-rotates the refresh token on every /api/auth/refresh call, so a bot that runs at least one authenticated command every ~25 days stays online indefinitely without a re-login.

Check days remaining at any time:

bullpen doctor auth | grep "Refresh Token"
# → Refresh Token:     expires in 27 days

If the refresh token does expire, repeat the workstation step (run bullpen login interactively) and re-copy the new credentials.json.enc to the bot host.


Security tradeoffs

The portable credential file gives the bot host full account power — it can place trades, withdraw funds (within the existing CLI's restrictions), and access the same surface as the human operator.

  • Lock down file permissions: the credential file is 0o600 by default. Make sure BULLPEN_HOME is on a filesystem only readable by the bot's OS user.
  • Don't share BULLPEN_USERNAME_OVERRIDE-bound files between distinct bots. Each independent bot identity should run a separate bullpen login cycle with its own override identifier.
  • Don't commit the credential file to git. It's encrypted, but the embedded secret is shared across all CLI users — anyone who can also guess your username override + bullpen home can decrypt it.
  • Rotate the override + re-login if you suspect the file has leaked.

Server-side API-key auth is planned so you can mint scoped, revocable credentials from a workstation and use them headlessly without copying any files. Until then, the portable credential workflow is the recommended path.


Troubleshooting

  • Bundle: NOT decryptable — keypair mismatch detected → the BULLPEN_USERNAME_OVERRIDE or BULLPEN_HOME differs between the workstation and the bot host. Double-check both env vars.
  • Token: Expired (run: bullpen login) and Refresh Token: Expired → the refresh token TTL elapsed. Re-run the workstation login + re-copy.
  • bullpen doctor auth reports Credentials: Not found → the credential file didn't make it across, or BULLPEN_HOME is pointing somewhere else.

End.