Skip to content

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 no infra/sprig-install.json.
  • Platform commands call the control-plane API and require a delegated sign-in (device code against the organizations authority). The token cache is partitioned per context.
  • Provisioning and teardown live on the sprig infra surface. 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.
sprig <resource> <verb> platform, implicit sprig apps publish
sprig platform <resource> <verb> platform, explicit sprig platform apps publish
sprig infra <resource> <verb> cloud substrate sprig infra operators add

The 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.

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.

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.

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

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 verify

Exit 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.

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.