The terminal is the fastest dashboard.
One binary drives every product in your workspace. tilldev talks to the same API as the dashboard at tilldev.dev, so anything you can click you can also script — list issues, upload dSYMs on release, rotate a DSN, or ask your telemetry a question, without leaving your shell.
Install
npm i -g @tillstack/cli # or: pnpm add -g @tillstack/cli
tilldev login # sign in once
tilldev config set org my-team
tilldev config set project prj_1a2b3c # optional defaultThe tillpulse command is installed as an alias of tilldev — same binary, so tillpulse issues and tilldev pulse issues are equivalent.
Account & config
Your token, org, and a default project live at ~/.tilldev/config.json (file mode 0600). Set a default org and project and every command below drops the flags.
| Command | What it does |
|---|---|
tilldev login | Sign in by approving a code in a browser where you are signed in. No password in the terminal, so it works from an AI agent’s shell. Opens the page on a terminal; --no-open prints the link only. |
tilldev login --email <email> | Sign in with email and password instead (prompts for 2FA if enabled). |
tilldev whoami | Show the signed-in user, org, role, and the API URL in use. |
tilldev logout | Forget the stored token — leaves your api-url and org config in place. |
tilldev config get [key] | Show config: api-url · org · project · token (redacted). |
tilldev config set <key> <value> | Set api-url, org, or a default project so later commands need no flags. |
A session renews itself: the access token lasts an hour and the CLI swaps it using the stored refresh token, which lasts 30 days from its last use. Parallel commands share one renewal, so running several at once does not sign you out. Approve a sign-in at tilldev.dev/device; the page shows the computer name and IP that asked, and only a code you just started should be approved.
TillPulse — observability
Everything under tilldev pulse …. Set a default project with tilldev config set project <id> to omit --project.
| Command | What it does |
|---|---|
tilldev pulse projects | List projects in the current org. |
tilldev pulse projects create <name> --platform <ios|android|react-native|flutter|web> | Create a project and print its DSN. |
tilldev pulse project <id> | Show a project, including its DSN. |
tilldev pulse issues [--project <id>] [--limit <n>] | List issues, newest first, with level, event count, and last-seen. |
tilldev pulse issue <id> | Show one issue as JSON — stack, breadcrumbs, device, release. |
tilldev pulse metrics [--project <id>] | Fetch the project’s headline metrics (error rate, throughput, health). |
tilldev pulse alerts | List alerts that have fired, with severity and whether they were acknowledged. |
tilldev pulse alerts rules [projectId] | List the alert rules that fire them, with their trigger, whether they are on and whether their webhook is signed. |
tilldev pulse alerts rules enable|disable|delete <rule-id> | Switch a rule on or off, or delete it (owner/admin). |
tilldev pulse alerts rules secret <rule-id> [--secret <s>] | Replace a rule’s webhook signing secret; one made for you is shown once (owner/admin). |
tilldev pulse budgets rules | List budget alert rules (vendor usage and spend), whether they are on and how their webhook is signed. |
tilldev pulse budgets rules enable|disable|delete <rule-id> | Switch a budget rule on or off, or delete it (owner/admin). |
tilldev pulse budgets rules secret <rule-id> [--secret <s> | --keep-current] | Replace a budget rule’s webhook signing secret, shown once if made for you, or encrypt the one an older rule stored without changing it (owner/admin). |
tilldev pulse releases create <projectId> <version> [--build <b>] [--env <e>] [--commit <sha>] | Mark a release so crash-free-session and regression tracking have a boundary. |
tilldev pulse sourcemaps upload <projectId> --release <v> --file <path> | Upload a JS/RN source map to de-minify stack traces. |
tilldev pulse proguard upload <projectId> --release <v> --file <path> | Upload an Android ProGuard/R8 mapping file. |
tilldev pulse dsym upload <projectId> --release <v> --file <path> [--dist <d>] | Upload iOS/macOS dSYMs: a .dSYM, a folder or .xcarchive of them, or one DWARF file. Large files upload in parts. |
tilldev pulse dsn rotate <projectId> | Rotate the ingest DSN — old key stops accepting events. |
tilldev pulse ask "<question>" | Ask your telemetry in natural language; streams the answer to your terminal. |
TillAuth — authentication
| Command | What it does |
|---|---|
tilldev auth apps | List your TillAuth apps. |
tilldev auth apps create <name> | Create an auth app; prints its public id and tenant slug. |
tilldev auth app <appId> | Show one auth app as JSON. |
tilldev auth apps update <appRef> [--mfa required|optional] [--name <n>] [--allow-unverified-signin true|false] [--redirect-origins <csv>] [--default-redirect <url>] [--settings-json '<json>'] | Change app settings from a script. Partial — flags you omit keep their value. --settings-json reaches keys without a dedicated flag (allowlist, credentials). The same policy guards as the dashboard apply: a change that would strand existing users is refused with a count. |
tilldev auth apps rotate-key <appRef> [--yes] | Owner: give the app a new data key and re-encrypt its provider client secrets, authenticator secrets, linked-account tokens and webhook secrets under it. Sign-ins and webhooks keep working throughout; if it stops partway, run it again to finish. Up to 3 an hour. |
tilldev auth groups <appRef> [show|create|add|remove|rename|rm] … | Groups in an identity app: list them, see members, and make and change groups by hand. Groups from your directory are read-only here. Adding people asks for approval when your workspace requires it. |
Workspace
Team, API keys, company sign-in and approvals are org-level — they span every product you’ve enabled (see Company sign-in). Sensitive actions (revealing a secret, running a command with secrets, minting tokens) wait for your passkey, your paired phone or a confirmed authenticator code; see Approvals.
| Command | What it does |
|---|---|
tilldev team | List members of the current org with their roles. |
tilldev keys | List API keys and when each was last used. |
tilldev keys create <name> [--scopes read,ingest,admin] | Mint an API key (defaults to read). Shown once — copy it immediately. |
tilldev approvals [--pending] | Your approval requests from the last 30 days: what asked, from where, and whether it may repeat. |
tilldev approvals open [<id>] | Open one request, or the Approvals page (passkeys, authenticator, what may repeat), in the browser. |
tilldev approvals deny <id> | Refuse a waiting request, or stop one that was allowed to repeat. |
tilldev approvals wait <id> [--timeout <s>] | Wait for your answer without running anything. Exits 0 approved, 1 denied or expired, 3 still waiting. |
tilldev approvals trust [status|end] | Trust this terminal sign-in to reveal and use secrets below tier 7 without asking, for a window you choose when approving. Restricted and sealed secrets still ask. Logging out ends it. |
tilldev approvals policy [on|off] | Show or change the workspace setting. Owner or admin; turning it off needs an approval. |
tilldev sso | Company sign-in (OIDC SSO): provider, status, new-account policy and verified domains. |
tilldev sso set --issuer <url> --client-id <id> [--client-secret-stdin] | Set it up or change it. Endpoints come from discovery; flags you leave out keep their current value. A new issuer disconnects everyone and needs --yes. Owner or admin, signed in (not an API key). |
tilldev sso domains add <domain> | Prints the TXT record that proves the workspace owns the domain. Company sign-in creates new accounts only on verified domains. |
tilldev sso domains check <domain> | Looks for the record now; exits 1 until it is found. |
tilldev sso links | The company sign-ins connected to your account, and how each was connected. |
tilldev sso disconnect <id> | Disconnect one. Connecting happens in the browser: tilldev sso connect. |
tilldev approvals forget | Delete the approval claims this machine holds in ~/.tilldev/approvals.json. |
tilldev access | Your role, whether you may ask for time-boxed admin, and any request waiting or window running. |
tilldev access elevate --reason <why> [--minutes <n>] [--ticket <ref>] [--wait] | Ask for admin, up to your cap. With --wait, waits for the decision and renews this sign-in once approved. Exits 0 active, 1 rejected or lapsed, 3 still waiting. |
tilldev access refresh | Renew this sign-in to pick up an approved window, or drop an ended one. |
tilldev access end [<id>] | Withdraw your waiting request or end your window early. Owners and admins can end anyone’s by id. |
tilldev access ls [--all] [--status <s,…>] | Your requests, or everyone’s for owners and admins. |
tilldev access approve <id> [--note <text>] | Approve someone’s request: standing owner or admin, never the requester. Needs an approval. reject works the same way. |
tilldev access eligible add <email|id> [--max <minutes>] [--approval peer|self] | Let a developer or viewer ask, with a cap of 15 to 480 minutes. Self-approval is owner-only. rm stops them asking and ends anything open. |
tilldev access review [--level <l>] [--fail-on high|medium|low] | Who holds owner or admin, who has no authenticator or went quiet, and which credentials are idle, orphaned or never expire. --fail-on exits 1 at that level or worse. |
tilldev access review fix <finding-id> [--step <n>] [--yes] | Run the change that fixes a finding. Revokes and removals ask first. |
tilldev access review accept <finding-id> --reason <why> [--days <n>] | Keep a finding on purpose for up to 366 days. accepted lists them; unaccept <id> counts one again. |
tilldev access review settings [--admin-days <n>] [--member-days <n>] [--credential-days <n>] | How many quiet days make an admin stale, a member dormant or a credential unused. |
MCP servers
Give AI tools their API keys without writing them into a config file. See MCP servers.
| Command | What it does |
|---|---|
tilldev mcp add <name> --env KEY=secretref://… -- <command> | Register an MCP server with Claude Code, Claude Desktop, Cursor, VS Code or Windsurf. The config names the secret; the value reaches the server only when it starts. --client, --scope user|project|local, --from <project>/<env>, --set KEY=value, --print, --config <path>. |
tilldev mcp ls [--client <client>] | Every server in every client: which get keys from the vault, which keep them in plain text (named, never printed). |
tilldev mcp import <name> --to <project>/<env> | Move a server’s plain-text keys into the vault and rewrite its entry. --keep KEY,… leaves some; --overwrite stores new versions. |
tilldev mcp rm <name> | Remove a server tilldev added (--force for one it didn’t). |
tilldev mcp run <name> --env KEY=secretref://… -- <command> | What the client starts. Resolves the references (the first start asks for your approval), then runs the server. |
SSH agent
Use an SSH key that stays in the vault, for ssh, git and AI sessions. See SSH agent.
| Command | What it does |
|---|---|
tilldev ssh keygen <project>/<env>/<KEY> | Make an SSH key in the vault and print its public half. --type ed25519|rsa, --rsa-bits, --rotate replaces an existing key, --no-add. |
tilldev ssh import <project>/<env>/<KEY> --file <path> | Move an existing key into the vault, asking for its passphrase if it has one. --remove deletes the file once the vault holds the same key; --overwrite stores a new version. |
tilldev ssh add | rm <project>/<env>/<KEY> | Offer a vault key through the agent, or stop offering it. The key stays in the vault. |
tilldev ssh ls [--public] | The keys the agent offers, with fingerprints. --public prints authorized_keys lines. |
tilldev ssh agent [--key <ref>]… [--socket <path>] | Run the agent (default socket ~/.tilldev/ssh-agent.sock). Each signature waits for your approval, or is allowed for a time you choose. |
tilldev ssh config [--host <pattern>]… [--write] | The ~/.ssh/config lines that point ssh at the agent; --write puts them at the top of the file. |
tilldev ssh git <project>/<env>/<KEY> [--global] [--sign-all] | Sign git commits and tags with the vault key through the agent. |
tilldev ssh install | uninstall | Start the agent at login, with launchd on macOS or systemd on Linux. |
Make ML-DSA, SLH-DSA, ML-KEM, X-Wing and hybrid ML-DSA-65 + Ed25519 keys in the vault. See Post-quantum keys.
| Command | What it does |
|---|---|
tilldev secrets gen <KEY> --env <env> --type ml-dsa-65 | slh-dsa | ml-kem-768 | x-wing | ml-dsa-65-ed25519 | A post-quantum key pair made in the vault. Prints the public key and its fingerprint. --format pem|raw (X-Wing is raw only); --slh-set picks the SLH-DSA parameter set (default sha2-128s). |
Encrypted delivery and host keys
Get pulls and leases encrypted to a post-quantum key, and bind a token to one host. See Encrypted delivery.
| Command | What it does |
|---|---|
tilldev secrets host-key init [--file <path>] [--force] | Make this host’s key pair (default ~/.tilldev/host-key, readable only by you) and print its fingerprint and public key. |
tilldev secrets host-key show [--file <path>] | Print the public key and fingerprint again. |
tilldev secrets tokens create … --host-key @host-key.pub | A service token that only answers encrypted to that host key. |
tilldev secrets pull | exec --env | lease … [--host-key <file>] [--no-seal] | Answers come back encrypted to the host key, or to a fresh key when there is none. --no-seal is for servers that predate it. |
Workload identities
Let CI jobs, cloud workloads and servers read secrets with the identity they already have, instead of a stored token. See Workload identity.
| Command | What it does |
|---|---|
tilldev secrets identities create --project <p> [--env <e>] --github owner/repo [--branch b | --tag t | --ref r] [--github-env e] | Let a GitHub Actions job sign in without a token. owner/* trusts every repository of that owner. |
tilldev secrets identities create … --gitlab group/project [--issuer <url>] | --bitbucket workspace/{repo-uuid} | --circleci org-id/project-id | --buildkite org/pipeline | --semaphore org/project-id | The same for GitLab CI, Bitbucket Pipelines, CircleCI, Buildkite or Semaphore; each takes --branch. |
tilldev secrets identities create … --terraform org/workspace [--issuer <url>] | --spacelift account/stack-id | An HCP Terraform (or Terraform Enterprise) workspace, or a Spacelift stack. * as the workspace trusts every workspace in the organization. |
tilldev secrets identities create … --google <email or id> | --azure tenant-id/app-client-id --principal <object-id> | --kubernetes <issuer> --service-account ns/name | --fly org/app | A Google Cloud service account, an Azure managed identity (the app registration must issue version 2 tokens), a Kubernetes service account or a Fly.io app. |
tilldev secrets identities create … --vercel team/project | --deno org[/app] | --modal workspace-id/app | --oidc <issuer> | A Vercel project (Team issuer mode), a Deno Deploy organization or app, a Modal app, or any OIDC issuer such as Jenkins. |
tilldev secrets identities create … --aws <role or user ARN> | --machine --host-key @host-key.pub | An AWS principal, or a server with no platform identity, proved by its host key. |
tilldev secrets identities create … [--claim name=pattern]… [--scope read|read_write] [--keys A,B] [--ttl 1h] [--jwks @jwks.json] | Extra conditions (* is a wildcard), what its tokens may read, how long they last (5m to 12h), and signing keys to pin for an issuer that is not public. Waits for your approval. |
tilldev secrets identities [ls] | show <id> | update <id> … | rm <id> | List them with uses and refusals; show one with its last refusal and setup steps; change it (--claim name= drops a condition); revoke it and every token it issued. |
tilldev secrets pull | exec --env | lease … --identity <id> | Sign in as the identity, or set TILLSECRETS_IDENTITY. A token (--token or TILLSECRETS_TOKEN) takes precedence. |
What encrypts your secrets
Check the suites behind your workspace's secrets and rotate its data key. See Cryptography for every product.
| Command | What it does |
|---|---|
tilldev secrets crypto [--tls] [--json] | Which suite each store is under, how many items predate suite ids, the data key, host-bound tokens and keys the vault made. --tls adds the TLS version and key exchange this machine negotiates. |
tilldev secrets crypto rotate-key [--yes] | Owners: a new data key, with values, configs, presigned calls, held drops and AI keys re-encrypted under it. Reads keep working; repeat it to finish an interrupted run. |
Sealed secrets
Seal a secret nobody should read; releasing it takes two owners. See Sealed secrets.
| Command | What it does |
|---|---|
tilldev secrets seal <secret> [--yes] | Owners: nobody can reveal it again, you included. It is still set, spent through the broker, pulled by env-pinned tokens and synced. |
tilldev secrets releases [--all] | Requests to reveal or unseal a sealed secret: open ones, or all with --all. |
tilldev secrets releases ask <secret> --reveal | --unseal --reason "…" | Ask the other owners. tilldev secrets unseal <secret> --reason "…" is the same as --unseal. |
tilldev secrets releases approve | deny <id> | Another owner decides. An approved reveal works once, for the asker, within an hour. |
tilldev secrets releases cancel | get <id> | Withdraw your request, or show one. |
Spend anomalies
Notice an agent behaving unlike itself, and route it to your on-call. See Spend anomalies.
| Command | What it does |
|---|---|
tilldev secrets anomalies [--all] [--agent <key>] | Agents spending unlike their own last 14 days (a new host or secret, a volume spike, an unusual hour, a burst of refusals), canary hits, leaks and tokens used without their host key. |
tilldev secrets anomalies baseline <agent> | What the detector compares that agent with: hosts, secrets, hours (UTC) and its busiest hour. |
tilldev secrets anomalies resolve <id> --expected | --revoked | --investigated [--note "…"] | Close one; waits for your approval. Revoke the agent first if the spend was not expected. |
tilldev secrets anomalies route --project <pulse> --slack <url> | --webhook <url> [--webhook-secret <s>] | --email <addr> | --pagerduty <key> | --teams <url> | A TillPulse alert rule for anomalies. --min-severity (default medium), --agents a,b*, --kinds canary,leak,… and --quiet-minutes narrow it. A webhook’s signing secret is printed once unless you set your own. |
Plant decoys that alert on first use. See Canaries.
| Command | What it does |
|---|---|
tilldev secrets gen <KEY> --env <env> --type canary --shape aws|postgres|stripe | A decoy that alerts when anything uses it. --aws-user names the IAM user; --pg-database and --pg-host shape the connection string. |
tilldev secrets canaries [--all | --retired] | Which secrets are canaries, how each is watched and its hits. Waits for your approval every time. |
tilldev secrets canaries rm <id> [--yes] | Retire one: stop watching, delete the decoy, remove its AWS user. Waits for your approval. |
tilldev secrets canaries settings --aws-key-id-ref <secretref> --aws-secret-key-ref <secretref> | --clear-aws [--pg-host <host> | --clear-pg-host] [--no-verify] | The AWS account canaries are made in, and a Postgres host name of yours. Waits for your approval. |
Find vault values where they shouldn't be, and rotate the ones that leak. See Leaked values.
| Command | What it does |
|---|---|
tilldev secrets scan <path…> [--json] [--label <text>] | Files holding a vault value, current or old. Only candidate strings are sent. Exit 1 unless every find is allowlisted. |
tilldev secrets scan --staged | --install-hook | Check what the next commit carries, or install a pre-commit hook that does. The hook lets a commit through if the vault can’t be reached. |
tilldev secrets update <secret> --on-leak notify|rotate|ignore | What a found value does: tell the admins, or also rotate the secret, acting as you (needs a vault-generated value). ignore marks public config as not secret, so leak checks skip it; it needs an approval. |
tilldev secrets rotate <secret> [--yes] | Make a generated secret again from its recipe and revoke the TillDev credentials old values carried. |
Ask for a value
Get a value from a person without it passing through a chat or your terminal. See Secret requests.
| Command | What it does |
|---|---|
tilldev secrets request <KEY> --env <env> [--note "…"] [--ttl <minutes>] [--no-wait] | Ask a workspace admin for a value. Prints a link and a code on stderr; once filled, prints the secretref:// on stdout. |
tilldev secrets request <KEY> --env <env> --external [--note "…"] [--ttl <minutes>] | A drop link for someone outside the workspace: works once, up to 72 hours, 12-character code. What they send is held until you accept it. |
tilldev secrets requests ls [--all] | get <id> | Open requests and drops waiting for review; get shows when a drop arrived, from where, and whether it differs from the stored value. |
tilldev secrets requests accept | reject | cancel <id> | Store a held drop as the next version, erase it, or cancel a request nobody has answered. |
Presigned calls
Let a machine make one privileged call without holding the credential. See Presigned calls.
| Command | What it does |
|---|---|
tilldev secrets presign <METHOD> <URL> --bearer secretref://… [--max-uses <n>] [--expires <hours>] [--quiet] | Approve one exact request now and get a tsc_ token that runs only that request. The credential never reaches the machine. |
tilldev secrets presign … --from <ip|cidr>… --bind-key <ssh-ed25519 …|@file> | Limit where it may run from, and bind it to a machine’s Ed25519 key (its SSH host key works). The token alone is then refused. |
tilldev secrets presign … --at <time|+2h> --dead-man <30m|2h|1d> | TillDev runs it itself at that time, or (dead-man) unless the machine checks in at least that often. Runs once; the result is emailed to you. |
tilldev secrets call [--token tsc_…] [--key <file>] | Run it. --key (or TILLSECRETS_CALL_KEY) signs each run for a bound call; an OpenSSH or PEM private key works. |
tilldev secrets call checkin | cancel | On the machine: push a dead-man deadline back, or call the whole thing off, timer and token. Same --token and --key as a run. |
tilldev secrets call keygen [--out <file>] | Make a machine key: the private half to ~/.tilldev/call-key.pem, the line to bind on stdout. |
tilldev secrets presigned ls | revoke <id> | Your presigned calls, with what each is bound to, its timer and any refused attempts; revoke one. |
Global flags & environment
These work on any command:
| Command | What it does |
|---|---|
--json | Print raw JSON instead of tables — pipe it into jq for scripting. |
--api-url <url> | Override the API base URL. Env: TILLDEV_API_URL. Defaults to https://tilldev.dev. |
--token <token> | Use a token without logging in — ideal for CI. Env: TILLDEV_TOKEN. |
--help, -h · version | Show usage for any command, or print the CLI version. |
--no-open | Print sign-in and approval links without opening a browser. |
TILLDEV_APPROVAL_WAIT=<seconds> | How long a command waits for your approval (up to 600). Defaults: 600 in a terminal, 90 under a coding agent, 300 for tilldev mcp run; a script exits 3 with the link at once. |
TILLDEV_AGENT_MODE=<name>|1|0 | The CLI spots Claude Code, Codex, Gemini CLI, Cursor and opencode and tells the agent, in plain words, to ask you to approve. Name another agent, force it on with 1, or turn it off with 0. |
TILLDEV_PROMPT_ECHO=off | Password and secret prompts show one * per character; this hides them too, so the length never shows on a shared screen. |
In CI
Skip the interactive login: mint a scoped key once with tilldev keys create ci --scopes read,ingest, store it as a secret, and export it. The CLI reads TILLDEV_TOKEN automatically — a common step is uploading source maps right after a build. An API key can’t approve anything, so actions that need a person’s approval answer 403. To read secrets in CI, use a workload identity, which needs no stored secret, or a TillSecrets service token:
export TILLDEV_TOKEN="${{ secrets.TILLDEV_TOKEN }}"
tilldev pulse releases create prj_1a2b3c "$GIT_SHA" --commit "$GIT_SHA"
tilldev pulse sourcemaps upload prj_1a2b3c --release "$GIT_SHA" --file ./dist/main.js.map