Skip to content

Changelog

A platform-wide architecture shift (ADR 0002), replacing the shape below piece by piece:

  • One always-warm gateway (Container App) replaces per-app static-site hosting and per-app Entra app registrations: every app now lives at <app>.apps.<yourdomain> behind the gateway’s own OIDC session, gated by a pair of Entra groups instead of a per-app registration lock.
  • A remote MCP connector (claude.ai) or Claude Code as a native MCP client replaces the old authentication plugin: no npm install and no device-code bootstrap. Four release-matched organization skills (sprig-publish, sprig-data, sprig-ops, and sprig-diagnostics) are downloaded from Admin > Setup > Skills and uploaded separately by a Claude tenant administrator.
  • Ops-governed source exposure (register_source/expose_entities) and a shared Data API builder instance replace direct browser-to-source access: every query, at build time and view time, streams through the gateway to the database under the caller’s own identity (on-behalf-of).
  • Group-based sharing (approve_share adds a group to an app’s viewers, no redeploy) replaces per-app Entra registration assignment.
  • App-to-source access is now a governed request: an app’s owner asks for a source (request_source_access at any time, or a sources list on provision_app), Ops decides it (list_source_access_requests, then approve_source_access or reject_source_access over a whole batch of ids, and revoke_source_access for one approved grant), and the approved request itself is the grant. Each source chooses manual or auto approval; deleting a source or retiring an app revokes its grants. The admin console includes the batch decision inbox, the per-source policy control, and each source’s approved-app inventory. Retiring and retired app groups are excluded from the source editor. Retirement persists source-owner revocations before changing source metadata, then returns typed Azure SQL or Fabric semantic runbooks on every retry until Ops confirms that the external work is complete. See App access to sources.
  • Ops can be notified when a request arrives instead of watching the inboxes. Point Sprig at a webhook (a Teams workflow trigger renders the card natively, and any HTTPS receiver can read the same facts) and toggle the two events independently. The URL is treated as a credential: stored securely, shown back masked, never logged, and accepted from a protected file rather than the command line. Receivers must resolve to public internet addresses. Delivery is best effort and at most once, with one five-second attempt, so the inboxes and the audit records remain the record. Configure it under Settings > Notifications, where Ops can replace the masked URL, toggle events, and send one explicit delivery test. See Notifications.
  • Upgrades from the initial notification-settings build clear its database-stored webhook during migration. Configure the webhook again with --webhook-url-file so Sprig stores it securely.
  • Source access is convergent and safe under concurrent administration. Requesting a pair that is already approved succeeds and re-applies the grant instead of erroring, so a failed configuration roll is repaired by simply retrying the request or re-running the provision. Re-requesting a pair whose source has since stopped serving is refused, naming the source’s state, rather than quietly re-applying it, and so is approving one: an approve batch requires every named source to still be in service, while rejecting stays available whatever the source’s state. Batch decisions report one outcome per request (applied, converged, or superseded with a detail naming the concurrent winner), and a request lost to a concurrent decision, an app retirement, or an owner offboarding no longer discards the rest of the batch. Provisioning with several sources reports the same way: one outcome per source, so a source lost to a concurrent change is named in the response while the rest of the batch is filed and applied. A retired app cannot regain data access through any concurrent operation, approvals and revocations stay correct under simultaneous admin actions, and deployed data configurations are consistent across all platform instances. Provisioning an app while it is being handed to a new owner or published keeps both results: provisioning writes only what it owns.
  • Successful publishes and rollbacks now return the canonical app URL. App lists and status checks return it whenever an active version exists.
  • publish(app, files) and POST /api/apps/{name}/publish have been removed. begin_publish, raw archive uploads (the project source and the built bundle, both required), and complete_publish are now the only publishing workflow for every bundle. Completion verifies both archives, durably retains the source per version (resumable later via get_app_source), pins verification and extraction to immutable uploads, is safe to retry across transient storage/pointer failures, and abandoned staging uploads or unactivated generated blobs become eligible for automatic cleanup after one day. Generated files are retained before their exact pointer can become active, so lifecycle cleanup excludes active and rollback artifacts.

This lands incrementally: some pieces (the gateway itself, standing it up in a real subscription end to end) are still catching up to the installer and the docs above it. The operate pages in this docs site describe the current, honest state of what’s automated versus what’s still a manual step.

Initial pilot release.

  • Governed publish: per-app Entra registrations (owner-locked), per-app static hosting in per-builder sandboxes, provenance tags, audit trail.
  • Sharing via Ops approval; Ops app role.
  • Viewer-identity data access through the original browser-direct data API, with schema introspection and pagination support in the builder skill.
  • sprig CLI: aggregated Azure install (what-if → confirm → deploy → smoke).
  • Claude plugin with three skills (publish, data, ops), TypeScript sources, minified distribution.