CI and AI agent workflows
The CLI behaves the same way on a laptop, in a CI runner, and inside an AI agent’s tool. Three things make that work:
- Environment-variable authentication so secrets never have to be written to disk on a shared runner.
- Tightly scoped API keys so a leaked credential is bounded by what it can do.
- Predictable output in non-interactive contexts (no banners, no prompts, no surprise prompts for
--help).
This page covers how to wire each of those up.
Authenticate without a file
Section titled “Authenticate without a file”Set two environment variables and skip zevcloud login entirely:
When ZEVCLOUD_API_KEY is set, the CLI:
- Uses the env-var key for every request.
- Never reads from the on-disk credential store.
- Never writes credentials to disk.
- Leaves any team configuration the user has set up locally untouched.
ZEVCLOUD_TEAM_ID is the team UUID and pairs with the API key. You can find it in the dashboard URL when viewing the team.
GitHub Actions
Section titled “GitHub Actions”A minimal deploy step in a workflow:
name: Deploy to ZevCloudon: push: branches: [main]
jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20'
- run: npm install -g @zevcloud/cli
- name: Deploy env: ZEVCLOUD_API_KEY: ${{ secrets.ZEVCLOUD_API_KEY }} ZEVCLOUD_TEAM_ID: ${{ secrets.ZEVCLOUD_TEAM_ID }} run: zevcloud deploy ${{ vars.SERVICE_ID }}A few notes on this pattern:
- Use
secrets.ZEVCLOUD_API_KEY, notvars, for the key. GitHub masks values fromsecretsin logs but does not maskvars. vars.SERVICE_IDis fine for the service id since it is not sensitive.npm install -g @zevcloud/clifinishes in seconds and installs cleanly without local file writes.
AI agents
Section titled “AI agents”For tool-using agents (Claude Code, agents wrapped around the OpenAI tool API, custom orchestrators), expose zevcloud as a tool and pass the env vars at process start.
The two most useful commands for an agent to call:
zevcloud servicesto discover what is deployed.zevcloud deploy <serviceId>to push a change.
Generate a key with the deploy scope (see below). The agent can deploy and read state but cannot create or destroy services, change billing, or rotate keys. Tighter scope means a leaked key cannot do as much.
The CLI also exposes zevcloud version for diagnostics. An agent that hits an error and includes zevcloud version output in its report gives the maintainers everything they need to reproduce.
API key scopes
Section titled “API key scopes”Pick the lowest scope that lets the workflow do its job. Scopes are fixed at key creation and cannot be promoted later.
| Scope | Use it for |
|---|---|
read | Health-check workflows, dashboards that just need to list state. |
deploy | CI pipelines, AI agents. Can deploy, restart/stop, set env vars, verify domains. The right default for non-interactive use. |
full | Equivalent to a human admin. Required for creating projects, services, environments, or running terminal commands inside containers. Use sparingly. |
The full permission table is at Authentication.
What the CLI suppresses in a non-interactive run
Section titled “What the CLI suppresses in a non-interactive run”When CI=true is set (most CI providers set this automatically) or when stdout is not a TTY:
- The postinstall welcome banner is silent.
- The “is there a newer version?” check is silent.
- Color output is auto-disabled in environments that do not support ANSI.
To disable these explicitly even outside CI, set ZEVCLOUD_DISABLE_UPDATE_CHECK=true and ZEVCLOUD_DISABLE_POSTINSTALL=true.
Rotating a key without downtime
Section titled “Rotating a key without downtime”API keys are issued and revoked from the dashboard at Settings → API Keys. To rotate:
- Generate a new key with the same scope.
- Update
ZEVCLOUD_API_KEYin your CI secrets to the new value. - Trigger a deploy to confirm the new key works.
- Revoke the old key in the dashboard.
The old key keeps working until you revoke it. There is no overlap requirement on our side.
Per-team workflows in CI
Section titled “Per-team workflows in CI”If a single repository deploys to multiple teams (a monorepo serving more than one client, for example), use one set of env vars per job:
jobs: deploy-acme: runs-on: ubuntu-latest env: ZEVCLOUD_API_KEY: ${{ secrets.ACME_KEY }} ZEVCLOUD_TEAM_ID: ${{ vars.ACME_TEAM_ID }} steps: - run: npm install -g @zevcloud/cli - run: zevcloud deploy ${{ vars.ACME_SERVICE_ID }}
deploy-beta: runs-on: ubuntu-latest env: ZEVCLOUD_API_KEY: ${{ secrets.BETA_KEY }} ZEVCLOUD_TEAM_ID: ${{ vars.BETA_TEAM_ID }} steps: - run: npm install -g @zevcloud/cli - run: zevcloud deploy ${{ vars.BETA_SERVICE_ID }}Each job uses the team’s own key. The CLI picks up whichever pair of env vars the job exports, with no per-machine state to worry about.