Skip to content
Open console

Enter a topic to search documentation.

    Resource schemas

    Generated fields and validation rules for infrastructure workspace resources.

    Compatibility and access

    Generated from product commit 6f341b4e6d35 . This is a source snapshot, not a guarantee that your deployment runs this version.

    These resource schemas describe provider configuration. Check your deployed API discovery for the schema installed in your hub. Use the intended workspace context and an identity permitted to read or change the resource. Required fields below are required within their containing object; optional parent objects may be omitted.

    Download complete schemas , including nested validation rules and status definitions. This page covers Kubernetes-style resources; provider HTTP actions and runtime behavior are separate contracts. Return to API reference for those interfaces and related guides.

    Instance (v1alpha1)

    API: infrastructure.faros.sh/v1alpha1 · Resource: instances · Scope: Cluster

    Source schema

    Terminal
    kubectl explain instances.infrastructure.faros.sh --api-version=infrastructure.faros.sh/v1alpha1 --recursive

    FieldTypeRequired in parentDescription and constraints
    specobjectYesInstanceSpec is the desired state.
    spec.templatestringYesTemplate names the catalog Template this instance is provisioned from (Template.metadata.name in the provider workspace, discoverable through the read-only templates catalog). Immutable: changing the product of a live instance would strand the old backend state, so it is a delete + recreate. minLength: 1; maxLength: 253; pattern: “^[a-z0-9]([-a-z0-9]*[a-z0-9])?$”
    spec.valuesobjectNoValues is the template-shaped input — exactly the object Template.spec.schema describes, the same payload that used to be the whole spec of the retired per-template kinds. The platform-reserved fields (farosMode, farosActions*, plus controller-stamped fields like expose.fqdn, farosCluster, credentialsSecretName) live in here too, so “spec” in template schemas, RGD ${schema.spec.*} expressions, and view definitions all keep meaning this object. The apiserver preserves it verbatim; the instance controller validates it against the Template’s schema and reports violations on the Ready condition.
    statusobjectNoInstanceStatus is the observed state: a platform-guaranteed baseline plus whatever the template’s backend projects. The struct only types the baseline — backend-projected fields (url, runtimeNamespace, components, outputs, controlSecretRef, …) are preserved as unknown fields, exactly as the retired per-template CRDs did, so a template’s status contract is still authored in its RGD statusMapping and not here.
    status.conditionsarray[object]NoConditions carries both provider-owned conditions (Valid, OIDCConfigured) and conditions mirrored from the runtime kro instance (Ready, ResourcesReady, …). The shape is deliberately looser than metav1.Condition because mirrored backend conditions may omit reason.
    status.conditions[].lastTransitionTimestringNoNo description supplied by the source schema.
    status.conditions[].messagestringNoNo description supplied by the source schema.
    status.conditions[].observedGenerationintegerNoNo description supplied by the source schema.
    status.conditions[].reasonstringNoNo description supplied by the source schema.
    status.conditions[].statusstringYesNo description supplied by the source schema.
    status.conditions[].typestringYesNo description supplied by the source schema.
    status.farosNetworkPhasestringNoNetworkPhase is the controller-owned runtime network phase. It is mirrored from the runtime Instance only after the runtime reports Ready; callers must not use spec.values as an execution-readiness signal.
    status.messagestringNoMessage carries human-readable detail for the current phase.
    status.observedGenerationintegerNoObservedGeneration mirrors metadata.generation last reconciled by the instance controller.
    status.phasestringNoPhase is the coarse lifecycle summary (Pending / Ready / Failed), derived from conditions for consumers that want one word.
    status.templatestringNoTemplate echoes spec.template as resolved at last reconcile.
    status.templateVersionstringNoTemplateVersion is the Template.spec.version the instance was last reconciled against.

    Template (v1alpha1)

    API: infrastructure.faros.sh/v1alpha1 · Resource: templates · Scope: Cluster

    Source schema

    Terminal
    kubectl explain templates.infrastructure.faros.sh --api-version=infrastructure.faros.sh/v1alpha1 --recursive

    FieldTypeRequired in parentDescription and constraints
    specobjectYesTemplateSpec is the desired state.
    spec.agentobjectNoAgent is operational guidance for AI agents that discover this template via MCP — what it provisions, when to choose it, prerequisites, and where its outputs (URL, DB connection Secret, …) land. It complements the human-facing displayName/description (which target the portal UI) and is not rendered in the form.
    spec.agent.outputsarray[string]NoOutputs describe where the provisioned instance’s results land so an agent can discover and wire them — e.g. “status.url: public app URL”, “Secret <name>-db-credentials key ‘uri’: postgres:// connection string”. One output per entry.
    spec.agent.prerequisitesarray[string]NoPrerequisites the caller must satisfy BEFORE provisioning — e.g. a cloud-credentials Secret in the tenant’s default namespace carrying specific keys. One human-readable requirement per entry.
    spec.agent.usagestringNoUsage is markdown guidance for an agent: what this template provisions, when to choose it, how the result is exposed (URLs/ingress/auth), and how to operate it after provisioning. The primary, free-form field; the structured fields below call out the most actionable specifics. maxLength: 8192
    spec.backendstringYesBackend names the registered backend implementation that reconciles instances of this template. The Template controller validates the backend is registered at admission time (PR A scope: validation lives in the controller; future PR moves it to a webhook). Today only “kro” and “stub” are expected; the seam supports terraform, cloud, etc. maxLength: 64; pattern: “^[a-z][a-z0-9-]*$”
    spec.backendConfigobjectNoBackendConfig is opaque to the platform; only the named backend interprets it. For “kro” it’s a resource graph (equivalent to an RGD’s resources + statusMapping); for a hypothetical “terraform” backend it would be a module ref and variable mapping. Stored as raw JSON to keep the API surface stable as backends evolve.
    spec.categorystringNoCategory groups templates in the catalog (e.g. “Databases”, “Workloads”, “Storage”). Empty puts the template under an “Other” bucket. maxLength: 64
    spec.dataPlaneobjectNoDataPlane optionally declares the live data-plane verbs this template’s instances expose — log streaming, a service proxy, sync/restart control — and how each resolves to a runtime Service/Secret/port from the instance’s status. The infrastructure provider serves these as subresources on the instance (e.g. sandboxrunners/<name>/log) so consumers reach a workload’s data plane without holding a credential to the runtime cluster themselves. Empty means the template’s instances expose no data plane. See docs/app-studio-runtime-decoupling.md for the end-to-end design.
    spec.dataPlane.componentsobjectNoComponents maps a component name to that component’s own verb set, served as …/<resource>/<name>/components/<component>/<verb>. Used by multi-tier templates so a caller can sync the backend and restart the frontend independently. Component names should match the template’s spec.development components where both are declared. Every endpoint resolves and is namespace-confined exactly like an instance-level one.
    spec.dataPlane.endpointsobjectNoEndpoints maps an instance-level verb name — the subresource the provider serves, e.g. “log”, “proxy”, “sync”, “restart”, “status” — to how it resolves. At least one of Endpoints and Components must be non-empty when DataPlane is set.
    spec.dataPlane.runtimeNamespacePathstringNoRuntimeNamespacePath is the status dot-path to the namespace the backend owns for this instance (e.g. “status.runtimeNamespace”). Every Service and Secret a data-plane verb resolves to MUST live in this namespace; the resolver rejects refs that point elsewhere. Required when any endpoint proxies to the runtime cluster (i.e. anything but a FromStatus endpoint). maxLength: 256
    spec.dataPlane.tokenSecretPathstringNoTokenSecretPath is an optional status dot-path to a {name, namespace} object naming the Secret whose “token” key the provider injects as the X-Sandbox-Control-Token header on upstream requests (the per-instance control token). Empty means no token header is added. The named Secret is confined to RuntimeNamespacePath like every other ref. maxLength: 256
    spec.descriptionstringNoDescription is one to three sentences shown beneath the display name in catalog cards. maxLength: 2048
    spec.developmentobjectNoDevelopment optionally declares how instances of this template run in development mode: which graph components can be hot-swapped to platform-managed dev images with a hot-reload agent, where each component’s source lives in the project workspace, and how each reloads. A template with a Development block can have instances provisioned with farosMode: development (the platform-reserved instance spec field the Template controller injects); templates without one are production-only. See docs/app-studio-template-sandboxes.md for the end-to-end design.
    spec.development.buildobjectNoBuild optionally declares the repository-owned GitHub Actions workflow that builds this template’s production images. App Studio observes and dispatches this workflow; it never authors or rewrites it. Absence means the template declares no CI workflow.
    spec.development.build.workflowPathstringYesWorkflowPath is a repository-relative GitHub Actions workflow path. It must live directly under .github/workflows and end in .yml or .yaml. maxLength: 256; pattern: “^\\.github/workflows/[^/]+\\.ya?ml$”
    spec.development.componentsobjectYesComponents maps a component name to its development behavior. Each key MUST name a workload resource the template’s graph emits (by the backend’s component→resource naming convention, e.g. “frontend” names the graph resource with id “frontend”). Components not listed here run exactly as declared in production mode — a dev sandbox keeps its real database. Keys must match ^[a-z][a-z0-9-]*$. ONE NAME RULE (see TemplateDevelopmentComponent.WorkspacePath): a component’s directory must be its own name, so agents, sync routing, and data-plane verbs all address it by one word.
    spec.development.idleTimeoutSecondsintegerNoIdleTimeoutSeconds is the maximum period without an authorized data-plane request before a development instance is deleted. Zero disables the limit. Activity is recorded on the runtime CR by the provider’s runtime credential, never by the workload pod or caller. minimum: 0; maximum: 604800
    spec.development.maxLifetimeSecondsintegerNoMaxLifetimeSeconds is the hard wall-clock lifetime for a development instance. Zero disables the limit; platform sandbox templates set a finite value so abandoned runs are deleted by the Instance controller and their runtime resources pass through normal finalizer cleanup. minimum: 0; maximum: 604800
    spec.development.providerActionsbooleanNoProviderActions controls whether the development pod receives the short-lived setup token used by the optional Provider Actions bridge. It defaults to true for backwards compatibility with existing development templates. A coding-only sandbox should set it to false so none of its containers receive a projected ServiceAccount token.
    spec.development.scaffoldobjectNoScaffold optionally names starter code for a fresh project built on this template. Its layout MUST match the components’ workspacePaths and it SHOULD ship CI workflows that build each component’s production image, with the owned workflow declared by Build (see docs/app-studio-template-sandboxes.md §4.1a). Consumed by App Studio at project bootstrap; opaque to the infrastructure provider.
    spec.development.scaffold.refstringNoRef pins a branch or tag. Empty means the repository default branch. maxLength: 128
    spec.development.scaffold.repositorystringYesRepository is the git URL of the scaffold. maxLength: 2048
    spec.displayNamestringNoDisplayName is the human-readable name surfaced in the portal catalog. Empty falls back to metadata.name. maxLength: 128
    spec.exposurestringNoExposure declares whether instances of this template are reachable from outside the platform. It is a statement ABOUT the resource graph, not a switch that changes it — the graph still has to carry (or not carry) the HTTPRoute. Declaring it lets every caller stop guessing: the portal and the MCP tools can say “this has no URL” instead of surfacing an empty status field, and an agent stops polling status.url forever for an instance that will never have one. The API server defaults it to “internal”, which is the safe reading: a template that never said it publishes anything is assumed not to. Because the default is stamped at admission, readers see a concrete value and never need to interpret an empty field. default: “internal”; enum: [“internal”, “optional”, “public”]
    spec.iconURLstringNoIconURL is an optional asset URL the portal shows on catalog cards. Falls back to a generic icon when empty. maxLength: 2048
    spec.instanceCRDobjectYesInstanceCRD declares the per-template CRD the platform publishes for tenants to author instances against. Must be in group infrastructure.faros.sh; the resource (lowercase plural) and kind (CamelCase singular) are operator-chosen but must be unique across all Templates.
    spec.instanceCRD.groupstringYesGroup MUST be infrastructure.faros.sh. Pinned here so every per-template CRD lives under the same namespace and the portal can render them uniformly. pattern: “^infrastructure\\.faros\\.sh$”
    spec.instanceCRD.kindstringYesKind is the CamelCase singular tenants use in apiVersion + kind. maxLength: 64; pattern: “^[A-Z][A-Za-z0-9]*$”
    spec.instanceCRD.resourcestringYesResource is the lowercase plural the apiserver routes on (kubectl get <resource>). Must be unique across all Templates in the provider workspace. maxLength: 64; pattern: “^[a-z][a-z0-9]*$”
    spec.instanceCRD.versionstringYesVersion of the per-template CRD’s served + storage schema. Templates can ship multiple Versions (a future Template can extend a previous one’s set); the controller updates the CRD’s spec.versions list rather than overwriting on conflict. pattern: “^v[0-9]+((alpha|beta)[0-9]+)?$”
    spec.sampleValuesobjectNoSampleValues is an optional example input payload the portal pre-fills the provision form with, so a user can provision a working instance in one click and tweak from there. Keyed by the schema’s top-level property names (nested objects allowed). Opaque to the controller; surfaced to the portal as spec.sampleValues. Stored as raw JSON.
    spec.schemaobjectYesSchema is the JSON Schema applied to the per-template CRD’s spec field. Stored as raw JSON because importing apiextensions/v1.JSONSchemaProps directly trips controller-gen on the upstream type’s recursive shape; the Template controller parses this back into JSONSchemaProps when it builds the CRD’s spec.versions[].schema.openAPIV3Schema.properties.spec. Expected content is the standard subset of OpenAPI v3 (type, properties, required, enum, default, description, minimum, maximum, pattern). The controller rejects Templates whose Schema fails to parse.
    spec.versionstringYesVersion pins the Template definition’s revision. Required by the per-template CRD’s served version selection and by instance-create-time consistency checks. maxLength: 64; pattern: “^\\d+\\.\\d+\\.\\d+(-[0-9A-Za-z.-]+)?$”
    spec.viewobjectNoView is optional presentation metadata that tells the portal how to render this template’s instances — extra columns in the instance-list table and grouped, typed fields on the instance detail page — instead of the default raw-JSON dump. Authored by the template owner so each template controls its own UX. Field values are dot-paths or ${…}-interpolated strings resolved against the instance’s spec/status/meta (see the portal’s view resolver). Stored as raw JSON (preserve-unknown-fields) and surfaced to the portal as spec.view; opaque to the controller. Shape: columns: # extra instance-list columns - header: Endpoint value: “https://${spec.expose.fqdn}” type: link # text | link | badge | code detail: # detail-page field groups - title: Access fields: - label: URL value: “https://${status.url}” type: link - label: Region path: spec.region
    statusobjectNoTemplateStatus is the observed state.
    status.backendobjectNoBackend reflects what the backend reported from its SetupTemplate call. Empty until first reconcile.
    status.backend.messagestringNoMessage carries human-readable detail when Ready is false. maxLength: 2048
    status.backend.namestringNoName echoes spec.backend so consumers don’t have to cross- reference. Helpful if a Template’s backend changes mid-life.
    status.backend.readybooleanNoReady is the backend’s headline status; matches BackendTemplateStatus.Ready from the Go interface.
    status.conditionsarray[object]NoConditions follows the standard Kubernetes conditions pattern. The aggregate Ready condition is True iff schema validation and the backend both succeed.
    status.conditions[].lastTransitionTimestringYeslastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
    status.conditions[].messagestringYesmessage is a human readable message indicating details about the transition. This may be an empty string. maxLength: 32768
    status.conditions[].observedGenerationintegerNoobservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. minimum: 0
    status.conditions[].reasonstringYesreason contains a programmatic identifier indicating the reason for the condition’s last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. minLength: 1; maxLength: 1024; pattern: “^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$”
    status.conditions[].statusstringYesstatus of the condition, one of True, False, Unknown. enum: [“True”, “False”, “Unknown”]
    status.conditions[].typestringYestype of condition in CamelCase or in foo.example.com/CamelCase. maxLength: 316; pattern: “^([a-z0-9]([-a-z0-9][a-z0-9])?(\\.[a-z0-9]([-a-z0-9][a-z0-9])?)/)?(([A-Za-z0-9][-A-Za-z0-9_.])?[A-Za-z0-9])$”
    status.observedGenerationintegerNoObservedGeneration mirrors metadata.generation last reconciled. Drives the standard “is the status fresh?” check.