--- name: zerops-setup description: Install zcli, sign in to Zerops, and select an organization and project without terminal prompts. Use before the first deployment or when CLI authentication, access, region, or saved scope needs repair. --- # Set up Zerops CLI access Use the official `zcli` from the user's app repository, locally or in a cloud sandbox. Setup and deployment use public HTTPS; no VPN, SSH, WireGuard, MCP server, or Zerops container is required. Keep the login process and subsequent commands in the same environment so they share the saved session. ## 1. Detect and install a browser-capable CLI Locate the executable before installing: use `command -v zcli` on POSIX shells or `Get-Command zcli -ErrorAction SilentlyContinue` in PowerShell. If present, run: ```sh zcli version ``` Require a verified release **v1.1.3 or newer**; v1.1.3 introduced browser/device login. Read the installed version from the `zcli version ...` line, not from the command's exit status or its additional update-check text. Treat `local` or an unrecognized development version as unverified. Check the resolved executable again after installing so an older copy earlier on PATH cannot mask the update. Read [installation routes](references/install.md) for OS/architecture detection, Linux, macOS and Windows commands, direct binaries, and source-build caveats. Prefer the official release installer or binary. As checked on 2026-10-21, npm's `@zerops/zcli` latest is 1.1.0 and cannot provide browser login; recheck publication before recommending npm. Do not infer browser support from an unrelated high historical npm version. ## 2. Check authentication and select the API region Use this small, non-prompting read to check usable authentication and discover accessible projects in one step: ```sh zcli project list ``` Success means the request authenticated; an empty table does not prove access to the desired project. A permission or network failure is not proof of logout. Avoid bare `zcli` as an exit-code-only authentication test: it also succeeds as a guest, and its account summary can contain an API error while returning success. There is no dedicated `whoami` or `status` command in v1.1.3. Never inspect the credential store (`cli.data`), token files, or environment dumps to check login. If login is needed, use the target's API region. Read the public directory at when choosing a region; its `items` contain `name`, `isDefault`, and `address`. The 2026-10-21 response listed only `prg1`. Pass the returned name to login's `--region`; the default is `prg1`, and `--region ''` uses the directory's default. Do not invent region names or a `zcli region list` command. API regions are separate from project/service locations; let `zerops-import` handle location selection. ## 3. Sign in through the user's browser Run without a PTY, with normal non-TTY stdout/stdin, and capture **both stdout and stderr**. Do not force `ZEROPS_CLI_TERMINAL_MODE=enabled`; if the runner forces terminal output, set `ZEROPS_CLI_TERMINAL_MODE=disabled` for this process. ```sh zcli login --browser --region prg1 ``` 1. Keep the command running. Relay the printed verification URL and user code to the user immediately; these are the intended device-login instructions. 2. Tell the user to open that URL in their browser, compare the displayed code, and approve the login. Non-TTY zcli does not open a browser itself; the browser can be on another machine when the agent runs in a sandbox. 3. Await the **same process** while the user approves. Do not launch another login or claim success merely because the URL appeared. Plain mode waits for server approval, denial, expiry, an error, or cancellation; do not promise a fixed expiry time or treat a runner timeout as authentication success. 4. Require normal completion with exit 0 and the `You are logged as NAME ` success message. Then run `zcli project list` to verify usable access. 5. On denial, stop this attempt. On reported expiry, start a new attempt only if the user still wants to sign in, and relay its new URL/code. The CLI stores and refreshes the browser session itself. Do not read, copy, print, or commit that storage. Browser login replaces a saved static token, but an inherited `ZEROPS_TOKEN` still wins on subsequent commands. If switching to browser authentication, remove that variable from this agent process's environment without displaying its value, then recheck access. Do not remove an unrelated CI secret or alter another process's environment. Noninteractive browser login is rejected when `CI` is truthy or unparseable. Use the headless path below in CI; do not mask a genuine CI environment to bypass the check. ## 4. Use a preprovisioned token for CI/headless operation Use this alternative when unattended authentication is required. Have the user create or select an appropriately scoped Zerops access token in the dashboard and inject **`ZEROPS_TOKEN` themselves** through their CI secret store or the agent's secure environment configuration. Never ask them to paste it into chat, put its value in a command argument, or print it. Keep shell tracing disabled. For deployment, the token must have **Full access to the target project**; read-only access can authenticate and list resources but cannot deploy. Limit the token's access to the intended work. Do not apply ZCP's exactly-one-project token restriction to zcli: this plugin does not use ZCP. After the environment variable is provisioned, run without a token argument: ```sh zcli login --region prg1 zcli project list ``` With a nonempty `ZEROPS_TOKEN`, login verifies it and saves the region without persisting that token. Without the variable, this command attempts browser login, so require provisioning first. Authentication precedence is environment token, then saved static token, then saved browser session. ## 5. Choose organization, project, and scope explicitly Read the `zcli project list` table's `id`, `name`, `org name`, and `org id` columns. Match the user's requested organization **and** project; names alone may be ambiguous. Retain the chosen IDs for subsequent calls. If the target is unclear, ask for that choice using the listed names and IDs instead of picking the first row. No organization-wide login switch is needed: selection is per operation. For an organization with no visible projects, the table cannot supply its ID. Ask the user for the organization ID from their Zerops dashboard and establish whether to create a project. Do not invent an `org list` command or equate an empty table with a nonexistent organization. Pass the chosen organization ID as `--org-id` through the `zerops-import` skill when creating/importing a project. Verify an existing project's services without opening a selector: ```sh zcli service list --project-id PROJECT_ID ``` Replace uppercase placeholders with actual IDs. Prefer explicit `--project-id` and `--service-id` on commands that support them; these are command-local flags, not universal root options. Obtain service IDs from the chosen project's list. A service ID determines its own project: supplying both flags does **not** check that they match. Use `zerops-deploy` for the deployment and its explicit setup selection, `zerops-yaml` for pipeline configuration, and `zerops-operate` for logs and runtime diagnosis. If the user wants a saved default, set or clear the global project scope with: ```sh zcli scope project PROJECT_ID zcli scope reset ``` Run only the relevant command; setting a default is optional. Never omit the ID from `scope project` in an agent session. Scope selects a target; it does not restrict the credential's permissions. Continue passing explicit IDs during automation, especially when several agents share a login. Distinguish the global default above from `zcli project scope PROJECT_ID`, which writes local `.zcli.yml`. Prefer explicit IDs over the local writer in v1.1.3: its replacement logic can fail when that file does not yet exist. `scope reset` does not remove local configuration. Legacy camelCase defaults such as `projectId` / `ZEROPS_PROJECTID` can take precedence even over `--project-id` in this version. Resolve conflicting non-secret targeting settings before acting; do not dump whole configuration or environment files to investigate. ## 6. Log out when requested ```sh zcli logout ``` Logout attempts to revoke the browser session, clears saved CLI state including global scope, and disconnects an active zcli VPN. Read any revocation warning; local cleanup alone does not prove remote revocation. Static personal tokens are not revoked, and `ZEROPS_TOKEN` continues to authenticate until removed from the environment. For token revocation, have the user revoke it in the dashboard and update their secret configuration. Avoid logging out merely as a diagnostic step when the session may be shared. ## Troubleshoot authentication and access | Evidence | Action | | --- | --- | | `unknown flag: --browser` or installed version below v1.1.3 | Install a verified release using the installation reference; check PATH for a shadowing npm/older binary. | | `unauthenticated user` | Use browser login, or require a provisioned `ZEROPS_TOKEN` in CI. | | `Your login session expired` | Start browser login again; the normal refresh path has already failed. Do not edit session storage. | | Login denied / code expired | Respect denial; for expiry, obtain a fresh URL/code for a renewed attempt. | | Browser login unavailable in CI | Use a user-provisioned `ZEROPS_TOKEN`; no token in chat or command arguments. | | Browser approval succeeds but wrong account/projects remain | An environment token may override the session. Remove that override from this process if browser auth is intended; verify account and target again. | | Wrong organization or missing project | Match both org and project IDs, check the selected API region and account, then ask the organization's administrator about membership/access. Empty results alone do not identify the cause. | | Authentication/list succeeds but deployment is forbidden | Require Full project access for the user or token. Read-only access is insufficient; organization membership alone does not prove project permissions. | | `Region '…' was not found` | Read the public region directory and pass a listed `--region` name. | | `allowed only in interactive terminal` | Supply the missing project/service/organization ID or setup for the actual command; consult its `--help`. Do not enable a TTY selector. | | 401 with a static/env token | Have the user check expiry/revocation and replace the secure environment value themselves. Do not expose the old value. | | Network/TLS error or session-save failure | Check HTTPS connectivity and writable user configuration storage; keep credentials out of diagnostics. Do not disable TLS verification or repeatedly relaunch login. | ## Source checks Checked against [zcli v1.1.3](https://github.com/zeropsio/zcli/tree/v1.1.3): `src/cmd/{login,logout,projectList,serviceList,scopeProject,scopeReset,projectScope,root,version}.go`, `src/cmdBuilder/{browserLogin,createRunFunc,scopeProject,scopeService}.go`, `src/deviceLogin/plain.go`, `src/loginSession/source.go`, `src/terminal/terminal.go`, `src/uxHelpers/project.go`, and `src/flagParams/handler.go`. Use these sources for CLI behavior where older token-first docs differ. Use [Roles & Permissions](https://docs.zerops.io/features/rbac#project-access-levels) for Full versus Read Only project access. Check `zcli --help` and the matching release source before introducing another command or flag.