SS-47 · Northflank-class app plane

PaaS app plane

Push a repo; get a governed, routable app.

61operations
9sub-capabilities
9endpoint groups
7services it composes

What it does

Push a repo; get a governed, routable app.

The unit of ownership is an App — {name, repo, branch} inside a tenant. Around it hangs everything that keeps a deploy safe: a resumable deploy saga, secure admission, revisions and rollback, autoscaling, crons, PR previews, a full CI/CD control plane, self-hosted runners, DBaaS/secret addons and a sovereign-exit export.

In-mesh base http://ss-47-skyforge.shared-services.svc.cluster.local:8047 · auth is an SS-01 bearer token + X-Tenant-Id on every /api/v1 route.

Sub-capabilities

The real building blocks.

Push-to-deploy apps

Register an app and drive one-shot or staged deploys. Duplicate names in a tenant are rejected, never replaced.

POST /api/v1/apps

Crash-safe deploy saga

A durable build → gate → admit → roll → route sequence; each step is persisted and the roll step is exactly-once, so a crash resumes at the failed step (ADR-0005).

POST /api/v1/apps/{app}/deploy/saga

Secure admission

No revision is minted unless the image is SS-04-admitted: Cosign-signed + SBOM'd + scanned. An unadmitted image halts the saga 403 with the build marked refused.

GET /api/v1/apps/{app}/builds

Rollouts & auto-rollback

The rollout tracks active vs last-good revision; an unhealthy health report compensates back to last-good and emits an SS-08 incident.

POST /api/v1/apps/{app}/rollout/health

TLS URLs & routing

A completed route step gives the revision a routable TLS URL; the deploy saga returns it on the route step.

POST /api/v1/apps/{app}/deploy/saga/{id}/advance

Self-hosted CI runners

Register linux runners you own and drain on your terms; OS-agnostic builds offload to an online runner or fall back in-cluster (ADR-0070).

POST /api/v1/runners

PR preview environments

A per-PR ephemeral deploy with a TTL lease; merge/close tears it down and erases its SS-02 claims, and a sweeper reclaims lapsed leases.

POST /api/v1/apps/{app}/previews

Addons & services

Provision a managed backing resource as an SS-02 DBaaS claim with an SS-05 Vault secret ref. Catalog-gated — embedded datastores are refused.

POST /api/v1/apps/{app}/addons

Autoscaling & quota

A min/max/target policy against cpu/memory/http_rate, applied behind a tenant replica-quota ledger so concurrent scale-ups can't both overrun.

PUT /api/v1/apps/{app}/scale

Worked example

Push a repo → build → admit → rollout → TLS URL

The governed happy path, driven over the API. Auth is an SS-01 bearer token plus X-Tenant-Id on every route.

  1. 1
    Register the appPOST/api/v1/apps

    {name, repo, branch}. Duplicate names 409.

  2. 2
    Connect the repoPOST/api/v1/apps/{app}/git

    Pick a provider from GET /providers; auto-deploy starts disabled.

  3. 3
    Start the deploy sagaPOST/api/v1/apps/{app}/deploy/saga

    Records desired state at current_step: build.

  4. 4
    Advance — build + gatePOST/api/v1/apps/{app}/deploy/saga/{id}/advance

    Build runs; the SS-32 gate verdict is evaluated.

  5. 5
    Admit the imagePOST/api/v1/apps/{app}/deploy/saga/{id}/advance

    SS-04 admission: signed + SBOM + scanned, or the saga halts 403.

  6. 6
    Roll + routePOST/api/v1/apps/{app}/deploy/saga/{id}/advance

    ?run=all mints the revision, re-points the rollout and returns the TLS url.

  7. 7
    Confirm healthPOST/api/v1/apps/{app}/rollout/health

    Healthy promotes to last_good_revision; unhealthy auto-rolls-back.

Endpoint catalog

59 documented endpoints of 61 operations.

Real method + path from services/skyforge/openapi.json. The full contract, including ops endpoints, is the 61-operation surface.

Apps

  • GET/api/v1/appsList the tenant's apps (cross-tenant rows never returned)
  • POST/api/v1/appsRegister a new app within the tenant
  • GET/api/v1/apps/{app}Fetch one app's definition
  • GET/api/v1/apps/{app}/exportSovereign-exit: portable desired state (ADR-0055)

Deploy saga

  • POST/api/v1/apps/{app}/deployidempotentOne-shot deploy: build → gate → admit → roll → route
  • POST/api/v1/apps/{app}/deploy/sagaidempotentStart the resumable staged deploy saga
  • POST/api/v1/apps/{app}/deploy/saga/{id}/advanceApply one step, or ?run=all to a terminal state
  • GET/api/v1/apps/{app}/deploy/saga/{id}Fetch one saga's persisted state
  • GET/api/v1/apps/{app}/deploy/sagasList every deploy saga for the app
  • GET/api/v1/apps/{app}/buildsList build records with gate verdict + admission status

Rollout, revisions & rollback

  • GET/api/v1/apps/{app}/revisionsList immutable, monotonically numbered revisions
  • GET/api/v1/apps/{app}/rolloutActive / last-good revision, status and history
  • POST/api/v1/apps/{app}/rollout/healthReport health; unhealthy auto-rolls-back to last-good
  • POST/api/v1/apps/{app}/rollbackRe-point to an existing revision (no new build)
  • GET/api/v1/incidentsThe tenant's auto-rollback incidents (SS-08 feed)

Scaling & quota

  • PUT/api/v1/apps/{app}/scaleInstall a scaling policy (clamped, quota-reserved)
  • GET/api/v1/apps/{app}/scalePolicy, applied replicas and event history
  • POST/api/v1/apps/{app}/scale/observeFeed an SS-06 metrics tick; apply behind quota
  • PUT/api/v1/quotaSet the tenant's total replica quota
  • GET/api/v1/quotaReport quota and current ledger usage

CI/CD control plane

  • GET/api/v1/providerspublicThe ten-provider git catalog + signature schemes
  • POST/api/v1/apps/{app}/gitConnect a repository to an app
  • GET/api/v1/apps/{app}/gitRead the repo connection + auto-deploy policy
  • POST/api/v1/apps/{app}/detectidempotentDetect deployable app types from the repo tree
  • GET/api/v1/apps/{app}/deployablesRead stored deployable-detection results
  • PUT/api/v1/apps/{app}/autodeploySet continuous-deployment policy (branch glob, gates)
  • POST/api/v1/webhooks/{provider}Inbound git-webhook listener (signature verified first)
  • POST/api/v1/apps/{app}/cicd/runRun the pipeline manually (recorded whatever the outcome)
  • GET/api/v1/apps/{app}/cicd/runsList pipeline runs, newest first
  • GET/api/v1/apps/{app}/cicd/runs/{id}One run's full stage trace
  • GET/api/v1/apps/{app}/cicd/flakyFlaky-test detection over run history
  • PUT/api/v1/apps/{app}/gatesReplace the app's quality-gate rules
  • GET/api/v1/apps/{app}/gatesRead gate rules + most recent evaluation
  • GET/api/v1/cicd/doraThe four DORA keys from the rollout spine
  • GET/api/v1/cicd/insightsPer-stage duration analytics + top-failing stage
  • PUT/api/v1/cicd/alertsRegister a pipeline alert rule
  • GET/api/v1/cicd/alertsList alert rules + fired alerts

Self-hosted runners (ADR-0070)

  • GET/api/v1/runnersList registered linux build runners
  • POST/api/v1/runnersRegister a self-hosted linux runner
  • POST/api/v1/runners/{id}/heartbeatLiveness heartbeat from the runner agent
  • POST/api/v1/runners/{id}/onlineMark a runner online / available for offload

Preview environments

  • POST/api/v1/apps/{app}/previewsCreate/renew a per-PR preview with a TTL lease
  • GET/api/v1/apps/{app}/previewsList an app's previews (lapsed reads as expired)
  • POST/api/v1/apps/{app}/previews/{pr}/closeTear down on merge/close, erase SS-02 claims
  • POST/api/v1/previews/sweepSweeper: reclaim every lease-expired preview

Addons, crons & GPU

  • POST/api/v1/apps/{app}/addonsProvision an SS-02 claim + SS-05 secret ref
  • GET/api/v1/apps/{app}/addonsList bound + erased addons (erasure retained)
  • DELETE/api/v1/apps/{app}/addons/{name}Erase the addon's claim, record the erasure
  • POST/api/v1/apps/{app}/cronsDefine a recurring job (SS-21 schedule)
  • GET/api/v1/apps/{app}/cronsList crons with applied effect counts
  • POST/api/v1/apps/{app}/crons/{name}/fireRecord a slot delivery (exactly-once effect)
  • GET/api/v1/apps/{app}/crons/{name}/firesFire records incl. deduped redeliveries
  • POST/api/v1/apps/{app}/gpugatedRequest a GPU workload (feature-gated, ADR-0060)
  • GET/api/v1/apps/{app}/gpuList GPU workload requests

Pipelines & promotion

  • POST/api/v1/apps/{app}/pipelineDefine ordered promotion stages
  • GET/api/v1/apps/{app}/pipelineRead stages + revision promoted into each
  • POST/api/v1/apps/{app}/pipeline/promotePromote a revision; gated stages park pending
  • GET/api/v1/apps/{app}/pipeline/promotionsPromotion history incl. refusals (evidence)
  • POST/api/v1/apps/{app}/pipeline/promotions/{id}/approveHuman approval; an agent is refused 403 (OPS09)

Architecture placement

Where it sits in the platform.

PaaS app plane does not reimplement the platform — it composes it. These are the services it leans on and the seams between them.

SS-01 Identity

OIDC bearer token gates every /api/v1 route; tenant binding comes from the token.

SS-31 Factory

Executes the hermetic build behind the saga's build step; the Tekton rail runners schedule onto.

SS-04 Registry

Cosign signature + SBOM + scan admission at the admit step.

SS-32 Droplet

Independent quality-gate verdict evaluated at the gate step.

SS-02 DBaaS + SS-05 Vault

Addons are DBaaS claims with Vault secret refs; SkyForge never holds credentials.

SS-06 / SS-08

Metrics ticks drive autoscale; auto-rollbacks emit incidents.

SS-60 / SS-10

vCPU-hr / GB-hr / egress metered per second, rolled into billing.