Skip to content

Shuttle Label Conventions

Every resource Shuttle creates carries a standard label set. Labels are selectable — they drive Informer filtering, NetworkPolicy selectors, garbage collection, and observability attribution (Fluent Bit and vmagent read them to route logs/metrics to the correct project/environment/service).

Labels are classified into two categories:

  • Load-bearing labels are required for system correctness. Something breaks if they are missing: Informer misses the resource, NetworkPolicy fails to enforce isolation, logs lose their attribution, garbage collection misses the resource. These labels have admission-policy enforcement planned (§39.2).
  • Operational labels are for debuggability, UX, and analytics. Nothing breaks if they are missing — but queries like kubectl get pods -l starform.io/tier=supernova become unavailable, and the dashboard may have to derive the value from other fields.

Billing note

Labels are not used for billing math. Starbase computes per-pod cost from the pod's resource requests (CPU, memory) in its PodSpec, which K8s stores natively — see Billing Flow (§36). Labels carry identity (who does this pod belong to) but not price. The starform.io/tier label denormalizes the Nova name for debuggability and analytics only; tier name → price is a Starbase-side lookup from resource requests at billing time.

§24.1 Starform Identity Labels — Load-Bearing

These labels are required on every resource Shuttle creates. Missing any of them is a Shuttle bug.

Load-bearing — the tenant key

The tenant identity key is project_id + environment + service_id (§24.1). workspace_id rides along as the billing-boundary label, not part of the key. There is no customer_id — it was removed in v1.9. This is the canonical home for the tenant key (CLAUDE.md §7); every metric and log line is attributed to it.

Label Applied To Purpose
starform.io/managed-by All Shuttle-created resources Always shuttle — primary Informer filter and garbage-collection key
starform.io/workspace-id All resources Workspace UUID — billing boundary, observability attribution
starform.io/project-id All resources Project UUID — scheduling unit, namespace boundary, observability attribution
starform.io/environment All service-scoped resources Customer-chosen environment name, validated RFC 1123 label, ≤30 chars (examples: production, staging, preview-pr-123 — no fixed enum) — NetworkPolicy isolation, observability attribution, HTTPRoute identity (§20.2)
starform.io/service-id Service-specific resources Service UUID — observability attribution, garbage collection
starform.io/service-name Service-specific resources Slugified service name — observability attribution, kubectl debuggability
starform.io/cluster-id All resources Cluster UUID — multi-cluster aggregation at Starbase
starform.io/var-group-id Var Group Secrets only Var Group UUID — Secret rotation and garbage collection (§38)

Enforcement — pre-launch-blocking (§39.2)

A Shuttle-created resource missing a required label is a bug. Admission-policy enforcement (rejecting unlabeled resources at the API server) is planned but pre-launch-blocking, not yet built.

§24.2 Starform Identity Labels — Operational

Denormalized convenience labels. Nothing in Starform's hot path depends on these; they exist for dashboard display, debugging, and ad-hoc analytics.

Label Applied To Purpose
starform.io/tier Pods Nova tier name (mininova, micronova, nova, supernova, hypernova, ultranova). Derived from resource requests; denormalized for kubectl debuggability and dashboard display.
starform.io/service-type Deployments, CronJobs web, worker, cron. Informs Stardeck UI which icon/controls to render.
starform.io/observability-enabled Pods true / false. Opt-out hook for future Enterprise customers who ship logs elsewhere.

§24.3 Standard Kubernetes Recommended Labels

Starform also applies the K8s-standard recommended label set so third-party tools (Lens, k9s, Headlamp, kubectl) display Starform resources correctly:

Label Value
app.kubernetes.io/name Service name (human-readable)
app.kubernetes.io/instance Service UUID (unique instance identifier)
app.kubernetes.io/component web / worker / cron / db-proxy
app.kubernetes.io/part-of Project slug (the logical parent application)
app.kubernetes.io/version Short git SHA of the deployed image
app.kubernetes.io/managed-by starform-shuttle

§24.4 Namespace Labels

The project namespace itself carries:

Namespace labels · proj-<project_slug>
labels:
  starform.io/managed-by: "shuttle"
  starform.io/workspace-id: "<uuid>"
  starform.io/project-id: "<uuid>"
  starform.io/project-slug: "<slug>"
  starform.io/plan-tier: "pro"              # hobby / pro / enterprise
  starform.io/cluster-id: "<uuid>"
  starform.io/namespace-role: "project"     # project / gateway / system — distinguishes Starform infra namespaces
  app.kubernetes.io/managed-by: "starform-shuttle"

The starform.io/namespace-role: "gateway" label is used by project-namespace NetworkPolicies to allow ingress from the Envoy Gateway namespace (§20.4).


Cross-references

Tenant key carried through desired state → §32 · HTTPRoute name encoding → §20.2 · annotations → §24B · the labels' observability consumers → Observability › Metrics. Canonical map: Canonical Sources.