sprig CLI
The standalone sprig operator binary is the supported CLI. Run sprig help
for usage.
Status, stated plainly:
- The v2 CLI is a single downloaded binary. It needs no repository, no
az, no Node, and noinfra/sprig-install.json. - Platform commands call the control-plane API and require a delegated sign-in
(device code against the
organizationsauthority). The token cache is partitioned per context. - Provisioning and teardown live on the
sprig infrasurface. Substrate commands are always explicit, never implicit, so an operator in an outage can tell at a glance which half of the CLI still works. - Unsupported substrate verbs are rejected rather than routed through an older implementation.
Grammar
Section titled “Grammar”sprig <resource> <verb> platform, implicit sprig apps publishsprig platform <resource> <verb> platform, explicit sprig platform apps publishsprig infra <resource> <verb> cloud substrate sprig infra operators addThe control plane is the common case, so it is not hidden behind a keyword.
sprig platform ... is the explicit long form for scripts and docs that want to
be unambiguous. sprig infra ... is never implicit.
Reserved first tokens (closed set): init, context, whoami, doctor,
infra, platform, help, version. There is no login or logout verb:
sign-in is implicit, triggered by the first command run against a cold token
cache.
Setup and context
Section titled “Setup and context”| Command | Effect |
|---|---|
sprig init |
The only command that works with no context. Signs in (device code) and writes a context to ~/.sprig/contexts/<name>.json (mode 0600) after scanning every visible subscription for an existing installation. Device-code sign-in requires a public client id: set SPRIG_CLIENT_ID (or SPRIG_ALLOW_AZ_CLIENT_ID=1 to knowingly use the Azure CLI client), or the flow refuses before discovery. Zero installations offers the greenfield branch; several offer a choice; more than one in a single subscription is refused as a misconfiguration |
sprig init --subscription <id> --prefix <prefix> --resource-group <rg> |
Fully explicit targeting, used when automated discovery is denied or the installation predates it |
sprig context list |
List known contexts and mark the active one |
sprig context use <name> |
Switch the active context |
sprig context current |
Show the active context |
sprig context remove <name> |
Remove a context from this machine |
sprig whoami |
Show the signed-in identity for the active context |
sprig doctor |
Health check spanning both halves; each result is labelled infra or platform. It checks the context and Azure access, ownership and discovery tags, deployed Container App state and release digests, wildcard certificate expiry, the admin, gateway, and platform endpoints, startup migrations, the Ops claim, and app ownership. The unauthenticated admin request must redirect to sign-in with 302/303, and the unauthenticated gateway data request must be rejected with 401/403 |
sprig version |
Show the binary version |
sprig help |
Command list and grammar reference |
The gateway, admin host, and certificate checks report not checked when that
optional serving tier or apps domain is not deployed. Release digest checking
uses the same digest-pinned SPRIG_PLATFORM_IMAGE,
SPRIG_OTEL_COLLECTOR_IMAGE, SPRIG_GATEWAY_IMAGE, and SPRIG_DAB_IMAGE
inputs as install and upgrade. If the required platform and collector inputs are
not present for the doctor process, it reports the release check as not checked. For automation, set SPRIG_PLATFORM_TOKEN to a delegated token so the
Ops-only checks do not start an interactive sign-in. Without that override, the
CLI reads SPRIG_API_CLIENT_ID from the platform Container App through Azure
Resource Manager and derives the delegated scope. SPRIG_API_SCOPE remains
available as an explicit override when that ARM value cannot be read.
Platform commands
Section titled “Platform commands”Implicit form shown; each is exactly sprig platform <resource> <verb> with the
keyword elided. These require a healthy platform API and a delegated sign-in.
| Command | Effect |
|---|---|
sprig apps list |
List apps you can see, including the URL for each active app |
sprig apps status <name> |
Show an app’s current state and its URL when active |
sprig apps provision <name> --entities-file <path> |
Provision an app’s database from an entities set |
sprig apps share <name> (--group-id <id> | --group-name <name>) |
Share an app with a viewer group; pass exactly one of the two group selectors |
sprig apps publish <name> --source-dir <project> --dir <build> |
Publish the project source and built bundle as a new version, then print its URL. The source archive excludes .git, node_modules, environment files, and macOS metadata |
sprig apps rollback <name> --version <n> |
Roll back to an earlier version and print its URL |
sprig shares list |
List share requests |
sprig shares approve <request-id> |
Approve a pending share request |
sprig shares reject <request-id> [--reason <text>] |
Reject a pending share request |
sprig sources list |
List registered sources, including where each one’s access is enforced |
sprig sources describe <id> |
Show a source’s metadata, enforcement mode, and exposure |
sprig sources register <id> [flags] |
Register a source, or re-register the same id to update it. --kind <kind> selects azure-sql (the default on first registration), fabric-dw (Fabric Warehouse / lakehouse SQL analytics endpoint, read-only, gateway-enforced only), or fabric-semantic (a Power BI / Fabric semantic model); omitted, it keeps an existing source’s own kind on a repeat call. SQL-shaped kinds are addressed with --server <host> --database <db> (and optional --schema); fabric-semantic is addressed with --workspace-id <guid> --item-id <guid> instead and takes no server, database, or schema. fabric-dw registration, schema discovery and serving all work today; both Fabric kinds require the Fabric inputs (including the extra Entra app registration) supplied at install time; fabric-semantic access itself stays user-delegated, and sprig holds no data credential for it; warehouse tables need a declared primary key to be exposable, and keyless lakehouse tables are not exposable yet. fabric-semantic registration, schema discovery, exposure and serving work today when the Fabric inputs were supplied at install time (discovery runs as the signed-in Ops user through a Power BI on-behalf-of token, so the model’s Read + Build grants must be applied first - the registration response carries the runbook); exposed tables and measures serve read-only under each viewer’s own identity. --enforcement-mode <mode> records where access is enforced: azure-sql and fabric-semantic accept only db-delegated, fabric-dw only gateway-enforced, each also that kind’s default. --reader-group <name> (repeatable) names the security groups allowed to read; semantic reader groups are pinned to the Entra object ids they resolve to, and a name that later resolves to a different principal is refused until you re-register with both --rebind-reader-groups (explicit consent) and --expected-version <n> (the concurrency check). Removing or rebinding a group leaves its OLD object id holding real grants: every response repeats the mandatory revocation runbook until you confirm the steps ran with --revocations-applied --expected-version <n> |
sprig sources expose <id> --entities-file <path> --expected-version <n> |
Expose selected tables or views as read-only entities. Pass the current version from sources describe; each file entry must include as and fieldExcludes, including an empty exclusion array when no fields are hidden |
sprig sources enable <id> --expected-version <n> |
Return a disabled source to service; pass the current version (from list/describe) to satisfy the concurrency check |
sprig sources disable <id> --expected-version <n> |
Withdraw a source while retaining its metadata; pass the current version to satisfy the concurrency check |
sprig sources remove <id> --expected-version <n> |
Withdraw a source, then remove its metadata; pass the current version to satisfy the concurrency check. A semantic source with pending revocations refuses removal until they are confirmed; one removed with principals still pinned returns their final revocation runbook and records them in the audit history |
sprig builders onboard <upn> |
Add a builder |
sprig builders offboard <upn> [--reassign-to <upn>] |
Remove a builder; optionally hand their apps to someone else |
sprig reports apps |
Report on apps |
sprig reports builders |
Report on builders |
sprig reports audit [--from <date>] |
Audit report |
sprig reports lineage |
Data lineage report |
When app retirement returns Azure SQL or Fabric semantic source revocations, run
every returned SQL statement or semantic model and OneLake step first. Then
re-register each affected source with its current settings and
--revocations-applied --expected-version <n>. The flag confirms and clears the
source’s complete pending revocation backlog, so do not use it for a partial batch.
sprig sources remove refuses every source kind until that backlog is confirmed.
Substrate (infra) commands
Section titled “Substrate (infra) commands”Always explicit. These are the provisioning and teardown surface, and the break-glass commands that must keep working when the platform API is down.
| Command | Effect |
|---|---|
sprig infra install --prefix <prefix> --region <region> [--platform-vnet-cidr <cidr>] [--restart] [--force-entra-adoption] [--yes] |
Preflight, show an explicit plan, take a typed confirmation (the context name, not y) unless --yes/-y is supplied, then provision. The target and plan are still printed, and configuration drift is never auto-approved. The prefix must be 1 to 9 lowercase letters or digits (no hyphens). A new installation uses 10.240.0.0/24 unless --platform-vnet-cidr supplies a canonical, non-overlapping IPv4 CIDR. Idempotent: it decides what to do from observed Azure state, never from a stored plan, and refuses to adopt any resource it cannot prove Sprig owns. Same-named Entra groups or apps owned by another identity require an interactive confirmation or --force-entra-adoption; neither --yes nor the general install break-glass override approves them. A partial retry reuses a matching completed ARM checkpoint only when the recomputed plan needs no creates or reconfiguration; --restart forces ARM reconciliation without deleting resources. In this build the release version, pinned image references, and both pull-only release credential variables are supplied through the environment; install fails closed before contacting Azure if any required input is missing |
sprig infra upgrade --prefix <prefix> --region <region> [--platform-vnet-cidr <cidr>] [--force-entra-adoption] [--yes] |
Upgrade a complete or safely resumable partial installation using the pinned release inputs and both pull-only release credential variables supplied through the environment. A VNet-based installation reuses its live CIDR when the flag is omitted and refuses a different explicit CIDR. Same-named Entra groups or apps owned by another identity require an interactive confirmation or --force-entra-adoption; neither --yes nor the general install break-glass override approves them. Other drift and resources whose ownership cannot be proved are still refused |
sprig infra operators list |
List operators (members of the operators group) |
sprig infra operators add <upn> |
Add an operator |
sprig infra operators remove <upn> |
Remove an operator; echoes the resolved target first. Removing the last operator refuses without --force, and self-removal refuses regardless |
sprig infra release status |
Show the deployed release and digests |
sprig infra release verify |
Verify deployed digests against the release manifest |
sprig infra connector status |
Show connector state |
Automation and exit codes
Section titled “Automation and exit codes”Every command renders interactively only when stdout is a TTY and --json is
absent; otherwise it prints plain append-only lines with no ANSI redraws. The
--json envelope shape is identical across commands.
sprig apps list --json | jq -r '.data.apps[].name'CI=true sprig infra release verifyExit codes are a published contract:
| Code | Meaning |
|---|---|
0 |
ok |
1 |
failure (the command ran and the answer was no) |
2 |
usage (the invocation was rejected by the grammar) |
3 |
auth (credentials missing, expired, or refused; re-run interactively) |
No prompt ever blocks in CI: a required-but-absent answer exits 2.
Context and token cache
Section titled “Context and token cache”A context is a small pointer file (~/.sprig/contexts/<name>.json, mode 0600)
holding the cloud, tenant, subscription, prefix, and endpoint. It holds no
secret, but it is identifying and it is load-bearing: whoever can write it can
redirect the next sprig infra upgrade at another subscription using the
operator’s credentials. Hence the 0600 mode, an integrity check on load, and the
resolved target echoed before every destructive command.
Token caches are partitioned per context. A token acquired under sprig-prod is
neither readable nor usable from sprig-stage.