Guide

Deploy Agent Accounts in Docker & CI

An agent account has no OAuth browser flow, which is exactly why it runs cleanly in a container or a CI job — there's no consent screen to click. This guide packages the CLI into a Docker image, authenticates headlessly with an API key pulled from a secret at runtime (never baked into a layer), runs the agent's account commands as the entrypoint, and shows the GitHub Actions equivalent. The result is a reproducible, headless agent identity you deploy like any other service.

Written by Caleb Geene Director, Site Reliability Engineering

VerifiedCLI 3.1.16 · Nylas managed · last tested June 8, 2026

What does deploying an agent account in a container involve?

Deploying an agent account in a container means packaging the CLI and your agent script into an image, then giving the container an API key at runtime so it can authenticate without a human. There's no browser step: an agent account authenticates with an API key, not an OAuth consent flow, so the whole thing runs headless. The container installs the CLI, configures credentials from an injected secret, and runs the agent.

That headless property is what makes agent accounts a natural fit for containers and CI. A user-mailbox integration needs an interactive OAuth grant that can't happen inside a build job; an agent account needs only a key. The three steps below — install, authenticate, run — are the whole deployment.

Container flow: install the CLI in the image, authenticate headlessly with a secret, run the agentInstall CLIinstall.sh in imageAuth headless--api-key from secretRun agentnylas agent ...

Why run an agent-account agent in Docker or CI?

Containers give an agent the same thing they give any service: a reproducible environment and a clean deploy path. Baking the CLI into the image means the agent behaves identically wherever the image runs — and you can pin a specific tagged release instead of the latest when you need strict version stability. CI adds a schedule and a trigger — a cron-driven workflow or a step in a pipeline — without standing up a server to host the agent.

The alternative, running the agent on a long-lived box you maintain, carries the same operational tax this whole product avoids. A container is built once and run anywhere; a CI job runs on infrastructure you don't patch. For an autonomous email agent, that's the right deployment shape — ephemeral, reproducible, and credentialed from a secret store.

How do I install the CLI in a Docker image?

Install the CLI in the image with the same script used on a workstation. The install script auto-detects architecture, downloads the latest release, and verifies its SHA-256 checksum. Add the install directory to PATH so later layers and the entrypoint can call nylas:

FROM debian:bookworm-slim

RUN apt-get update \
  && apt-get install -y --no-install-recommends curl ca-certificates jq \
  && rm -rf /var/lib/apt/lists/*

# Install the Nylas CLI (checksum-verified by the script)
RUN curl -fsSL https://cli.nylas.com/install.sh | bash
ENV PATH="/root/.config/nylas/bin:${PATH}"

COPY agent.sh /app/agent.sh
RUN chmod +x /app/agent.sh
ENTRYPOINT ["/app/agent.sh"]

The CLI installs to ~/.config/nylas/bin by default, which is /root/.config/nylas/bin for the root user — the path the ENV PATH line adds. Installing jq in the same layer gives the agent script its JSON tooling. For all install methods, see getting started with the CLI.

How do I authenticate headlessly?

Authenticate at runtime, not at build time, so the key never lands in an image layer. The container reads the API key from an injected environment variable and runs nylas auth config --api-key as the first thing the entrypoint does. Use nylas auth config --api-key, not nylas auth login — the latter opens a browser flow that can't complete in a container:

#!/usr/bin/env bash
set -euo pipefail

# Fail fast if the key wasn't injected
: "${NYLAS_API_KEY:?NYLAS_API_KEY is required}"

# Headless auth from the injected secret (no browser, no OAuth)
nylas auth config --api-key "$NYLAS_API_KEY" --region "${NYLAS_REGION:-us}"

# Now the agent account commands work
nylas agent status --json
nylas agent account list --json | jq -r '.[].email'

The :? guard aborts the entrypoint immediately if the key is missing, so the container fails loudly instead of running unauthenticated. Default the region to us and override with NYLAS_REGION=eu for the EU data region. Authentication completes in one call, and the agent's account commands run from there.

How do I run the agent in the container?

Pass the key at docker run time from your host's environment or a secret manager — never with --build-arg, which would bake it into the image. The entrypoint authenticates and runs the agent:

docker build -t my-email-agent .

# Inject the key at run time, not build time
docker run --rm -e NYLAS_API_KEY="$NYLAS_API_KEY" my-email-agent

Because the key arrives as a runtime environment variable, it never appears in docker history or an image layer. In production, source it from your orchestrator's secret store — Docker secrets, a Kubernetes Secret, or a cloud secret manager — rather than a plain host variable.

How do I deploy to CI with GitHub Actions?

In CI, the same three steps become workflow steps, with the API key coming from an encrypted repository secret. The job installs the CLI, adds it to the path, authenticates from secrets.NYLAS_API_KEY, and runs the agent on a schedule:

name: agent-email-task
on:
  schedule:
    - cron: "*/15 * * * *"   # every 15 minutes
jobs:
  run:
    runs-on: ubuntu-latest
    steps:
      - run: curl -fsSL https://cli.nylas.com/install.sh | bash
      - run: echo "$HOME/.config/nylas/bin" >> "$GITHUB_PATH"
      - run: nylas auth config --api-key "$NYLAS_API_KEY"
        env:
          NYLAS_API_KEY: ${{ secrets.NYLAS_API_KEY }}
      - run: nylas agent account list --json | jq -r '.[].email'
        env:
          NYLAS_API_KEY: ${{ secrets.NYLAS_API_KEY }}

The key lives in GitHub Actions encrypted secrets and is injected per step via env, so it's never written to the workflow file or the logs. This is the same pattern as the Docker entrypoint, expressed in YAML.

How do I keep the API key safe in containers?

An agent account's API key is the credential for every account in the application, so protecting it is the security priority of the whole deployment. Three rules cover it: never bake the key into an image, never log it, and scope it to what the agent needs.

  • Runtime, not build time — inject the key with -e or a mounted secret, never ENV or --build-arg. Anything in the Dockerfile is permanent and inspectable in the image history.
  • Secret store, not plaintext — source the key from Docker secrets, a Kubernetes Secret, or a cloud secret manager, not a committed .env file.
  • Fail closed — the :? guard makes a missing key stop the container rather than run it in a broken, unauthenticated state.

Pair these with the workspace-level controls — a policy send cap, outbound rules — so even a leaked key runs into the containment described in Stop Your AI Agent From Going Rogue. The container protects the key; the workspace bounds the damage if it ever leaks.

Next steps