ork serve

15 min read

Inspect, validate, and deliver via Internal Developer Platform (Serve) configurations.

Commands

CommandDescription
validateValidate Serve configuration in a Katalog
targetsList all Serve targets in a Katalog
aliasesList serve aliases for a target or across all CRDs
schemaShow the flat schema for a Serve target or alias
fieldsList all Serve fields with their paths and types
tokensShow token permissions for a CRD or alias
responseShow the Serve response configuration for a target or alias
can-iCheck if a token can perform an operation
playRun a serve intent locally through the full gateway chain
applyApply an intent or CR to a live gateway

ork serve validate

Validate Serve configuration in a Katalog.

This runs the same serve-specific validations as ork validate, but only for Serve concerns: fields, paths, tokens, response config, and namespace rules. It does not check the full Katalog schema — only the Serve portions.

ork serve validate

Flags

FlagShortDescription
--fullShow a detailed breakdown of the Serve configuration for each serve-enabled CRD.

Examples

# Validate Serve configuration
ork serve validate

Output

✓ Serve configuration is valid

With --full

# Validate Serve configuration with detailed breakdown
ork serve validate --full

Output

Serve Configuration Summary
──────────────────────────────────────────────────────────────────────

● application
  target: smartapp  /  kind: AppRequest
  name:      "{{ repoSlug .spec.repository }}"
  namespace: "{{ teamName }}-{{ environmentName }}"
  fields:    12 total (spec: 8, labels: 2, annotations: 2)
  tokens:    4 tokens with restrictions
  aliases:   2
    · preview   (1 token, custom response)
    · internal  (1 token, custom response)
  response:  default: true, payload: 4, exclude: 0
  poll:      field

● database
  target: db  /  kind: Database
  name:      (caller must supply)
  namespace: "{{ teamName }}"
  fields:    none
  tokens:    none (all tokens allowed)
  response:  none (default CR response)

──────────────────────────────────────────────────────────────────────
✓ Serve configuration is valid
  2 Serve-enabled CRD(s)

ork serve schema

Show the flat schema for an Serve target.

This displays the fields that callers can submit for a target, including their labels, types, enums, and paths. The output is the same flat field structure returned by the gateway’s GET /api/v1/schema?target=<t> endpoint.

ork serve schema [flags]

Flags

FlagShortDescription
--target-tTarget to show schema for
--kind-kKind to show schema for
--name-nCRD name to show schema for
--alias-aAlias to show schema for

One of --target, --kind, --name, or --alias is required.

Examples

# Show schema by target
ork serve schema --target apifixture

# Show schema by alias
ork serve schema --alias preview

# Show schema by kind
ork serve schema --kind PlatformResource

# Show schema by CRD name
ork serve schema --name platRsc

Output (primary target)

Schema for: platrsc (target: apifixture)
──────────────────────────────────────────────────────────────────────
FIELD           LABEL            TYPE    PATH            REQUIRED
environment     Environment      string  environment
repoURL         Repository URL   string  repoURL
targetNamespace Target Namespace string  targetNamespace

Output (alias)

Schema for: platrsc (alias: preview → target: apifixture)
──────────────────────────────────────────────────────────────────────
FIELD           LABEL            TYPE    PATH            REQUIRED
environment     Environment      string  environment
repoURL         Repository URL   string  repoURL
targetNamespace Target Namespace string  targetNamespace

ork serve fields

List Serve fields with their paths and types.

This shows fields declared in serve.fields and serve labels/annotations across all serve-enabled CRDs. With --target, --kind, or --name, shows fields for a specific CRD.

ork serve fields

Flags

FlagShortDescription
--target-tTarget to show fields for
--kind-kKind to show fields for
--name-nCRD name to show fields for
--alias-aAlias to show fields for
--sort-bySort fields by "name" (default) or "order"

Examples

# List all fields across all CRDs
ork serve fields

# List fields for a specific target
ork serve fields --target apifixture

# List fields for a specific alias
ork serve fields --alias preview

# List fields for a specific kind
ork serve fields --kind PlatformResource

# Sort fields by order (as declared in the Katalog)
ork serve fields --target apifixture --sort-by order

Output (All fields)

Serve Fields
──────────────────────────────────────────────────────────────────────

CRD: application (target: smartapp)
  FIELD           TYPE    PATH                    SOURCE
  cpu             string  app.resources.cpu       spec
  environment     string                          label
  image           string  app.image               spec
  repository      string  app.repository          spec
  team            string                          label

Total: 5 fields across 1 CRD

Output (Specific CRD)

Fields for: application (target: smartapp)
──────────────────────────────────────────────────────────────────────
FIELD           TYPE    PATH                    SOURCE      REQUIRED
cpu             string  app.resources.cpu       spec
environment     string                          label
image           string  app.image               spec        ✓
repository      string  app.repository          spec        ✓
team            string                          label       ✓

Output (Sorted by order)

Fields for: application (target: smartapp)
──────────────────────────────────────────────────────────────────────
FIELD           TYPE    PATH                    SOURCE      REQUIRED  ORDER
repository      string  app.repository          spec        ✓         1
image           string  app.image               spec        ✓         2
team            string                          label       ✓         3
cpu             string  app.resources.cpu       spec                  4
environment     string                          label                 5

ork serve tokens

Show effective token permissions for a serve-enabled CRD or alias.

This displays the serve.tokens configuration including which tokens have access, their permissions (../global/schema/resources), and namespace restrictions. With --alias, shows the effective token map for that alias — its own tokens when declared, or the inherited CRD-level tokens with a source note.

ork serve tokens [flags]

Flags

FlagShortDescription
--target-tPrimary target to show tokens for
--kind-kKind to show tokens for
--name-nCRD name to show tokens for
--alias-aAlias to show effective tokens for (can be used instead of --target)

One of --target, --kind, --name, or --alias is required.

Examples

# Show CRD-level tokens
ork serve tokens --target apifixture

# Show effective tokens for an alias (alias-own tokens or inherited)
ork serve tokens --alias preview

# Show by kind
ork serve tokens --kind PlatformResource

Output (primary target)

Token permissions for CRD: platrsc (target: apifixture)
──────────────────────────────────────────────────────────────────────
TOKEN           GLOBAL  SCHEMA  RESOURCES  NAMESPACES
control-center  *                          *
ci-pipeline             get     get,list   *

Output (alias with own tokens)

Token permissions for alias "preview" (CRD: platrsc)
Source: alias "preview" (own tokens)
──────────────────────────────────────────────────────────────────────
TOKEN           GLOBAL  SCHEMA  RESOURCES  NAMESPACES
control-center  *                          *

Output (alias inheriting CRD tokens)

Token permissions for alias "internal" (CRD: platrsc)
Source: alias "internal" (inherits CRD-level tokens)
──────────────────────────────────────────────────────────────────────
TOKEN           GLOBAL  SCHEMA  RESOURCES  NAMESPACES
control-center  *                          *
ci-pipeline             get     get,list   *

ork serve targets

List all serve-enabled primary targets in a Katalog.

This shows each primary target, its CRD kind, field count, token restrictions, and alias count. Full alias details are in ork serve aliases or ork serve validate --full.

ork serve targets

Examples

# List all primary targets
ork serve targets

Output

Serve Targets
──────────────────────────────────────────────────────────────────────
TARGET      KIND              FIELDS  TOKENS  ALIASES
apifixture  PlatformResource  12      yes     2
appgroup    AppGroup          0       no      —

2 target(s)

ork serve aliases

List serve aliases across all serve-enabled CRDs, or for a specific CRD.

Aliases are additional named entry points for a CRD. Each alias can independently override token permissions and response configuration, falling back to CRD-level defaults when not set.

ork serve aliases [flags]

Flags

FlagShortDescription
--target-tTarget to show aliases for
--kind-kKind to show aliases for
--name-nCRD name to show aliases for
--alias-aAlias name — shows all aliases for the same CRD

All flags are optional. Without any flag, lists aliases across all serve-enabled CRDs.

Examples

# List all aliases across all CRDs
ork serve aliases

# Show aliases for a specific target
ork serve aliases --target apifixture

# Show aliases for a CRD using a known alias name
ork serve aliases --alias preview

Output

Aliases for: platrsc (target: apifixture)
──────────────────────────────────────────────────────────────────────
ALIAS     TOKENS  RESPONSE
preview   yes     yes
internal  no      no

ork serve can-i

Check if a token can perform an operation.

This evaluates the same permission checks that the gateway applies to incoming Gateway API requests. It considers token existence, permissions (global/schema/resources scopes), namespace restrictions, and target existence.

ork serve can-i [flags]

Flags

FlagShortDescription
--token-TToken name to check (required)
--target-tTarget or alias name to check
--alias-aAlias to check permissions for (overrides alias resolved from --target)
--kind-kKind to check
--name-nCRD name to check
--operation-oOperation to check (required)
--namespace-NNamespace to check (default: all namespaces)
--class-cEndpoint class to check (resources, schema)

One of --target, --kind, or --name is required.

Examples

# Check primary target
ork serve can-i --token control-center --target apifixture --operation create

# Check alias — resolves alias-specific token map
ork serve can-i --token control-center --target preview --operation get

# Check alias explicitly (same as passing alias name to --target)
ork serve can-i --token ci-pipeline --target apifixture --alias preview --operation get

Output (Allowed — primary target)

✓ control-center can create on "apifixture"

Output (Allowed — alias)

✓ control-center can get on "apifixture" (alias: preview)

Output (Denied — alias token map excludes this token)

✗ ci-pipeline cannot get on "apifixture" (alias: preview)
  Reason: token "ci-pipeline" is not allowed to access "PlatformResource" — not listed in serve.tokens

ork serve response

Show the effective Serve response configuration for a target or alias.

This displays what callers will see in the Gateway API response based on serve.config.response (or serve.target[alias].config.response for aliases). It shows default: true/false, payload fields (with their template expressions), excluded paths, and poll URL configuration.

No cluster access is required — this reads the Katalog directly.

ork serve response [flags]

Flags

FlagShortDescription
--target-tPrimary target to show response for
--kind-kKind to show response for
--name-nCRD name to show response for
--alias-aAlias to show effective response config for (can be used instead of --target)
--preview-pShow a sample response preview

One of --target, --kind, --name, or --alias is required.

Examples

# Show CRD-level response config
ork serve response --target apifixture

# Show alias-specific response config (falls back to CRD-level when none declared)
ork serve response --alias preview

# Show with preview
ork serve response --target apifixture --preview

Output (primary target)

Response configuration for: platrsc (target: apifixture)
──────────────────────────────────────────────────────────────────────

default: true

Payload fields:
  FIELD   EXPRESSION
  phase   {{ .status.phase }}
  target  {{ getServeTarget . }}
  alias   {{ getServeAlias . }}
  source  {{ getServeSource . }}

Excluded paths: none

Poll URL:
  field: "status.phase"

Output (alias with own response config)

Response configuration for alias "preview" (CRD: platrsc)
──────────────────────────────────────────────────────────────────────

default: false

Payload fields:
  FIELD         EXPRESSION
  phase         {{ .status.phase }}
  workloadType  {{ .spec.workloadType }}
  environment   {{ .spec.environment }}
  target        {{ getServeTarget . }}
  alias         {{ getServeAlias . }}

Excluded paths: none

ork serve play

Run a serve intent locally through the full gateway chain.

Reads a flat YAML or JSON intent file with the same shape as a target-mode POST /api/v1/apply body, runs every stage of the apply chain in-process, and prints a coloured trace of each step.

No cluster connection is required. No CR is applied.

ork serve play [flags]

Stages

#StageWhat happens
1Target resolutionResolve target to a CRD and alias via the Katalog
2Token checkVerify the named token can perform the operation
3CR constructionBuild the full CR from serve field declarations
4ProvenanceStamp serve-target and serve-alias annotations
5Response payloadEvaluate serve.config.response.payload expressions

If any stage fails, the trace stops with a clear error at that stage.

Flags

FlagShortDefaultDescription
--intent-iintent.yaml or intent.jsonIntent file (YAML or JSON)
--token-tToken name to authenticate with (required)
--targetOverride the target field in the intent file
--operation-ocreateOperation to simulate (create, update, delete, get, list)
--namespace-NNamespace (for get/list/delete)
--name-nResource name (for get/delete)
--simulateHand the built CR to ork simulate; pass a path to run in assert mode

When --intent is not given, ork serve play looks for intent.yaml first, then intent.json, in the current directory.

--simulate is only valid for create and update operations.

Intent file format

The intent file is a flat key-value document — the same payload you would send as a POST /api/v1/apply body. The target field is required unless overridden via --target.

# intent.yaml
target: apifixture
name: my-payment-service
workloadType: app
team: platform
environment: staging
repoURL: https://github.com/myorg/payments
productionApproval: JIRA-1234

JSON is also accepted:

{
  "target": "apifixture",
  "name": "my-payment-service",
  "workloadType": "app",
  "team": "platform",
  "environment": "staging",
  "repoURL": "https://github.com/myorg/payments",
  "productionApproval": "JIRA-1234"
}

Examples

# Play from the default intent.yaml with a token
ork serve play --token control-center

# Play a specific file
ork serve play --intent ./deploy/intent.yaml --token ci-pipeline

# Override the target — useful for testing against a different alias
ork serve play --token control-center --target preview

# Simulate an update instead of create
ork serve play --token control-center --operation update

# Play a JSON intent file
ork serve play --intent intent.json --token control-center

# Play and hand the built CR to simulate (op-print mode)
ork serve play --token control-center --simulate

# Play and assert against a simulate.yaml spec (assert mode)
ork serve play --token control-center --simulate simulate.yaml

# Check what a read-only surface sees (no intent file needed)
ork serve play --token ci-pipeline --target apifixture --operation get --name my-service --namespace team-payments

Output

▶  ork serve play
  intent: intent.yaml
  target: apifixture
  token:  control-center
  op:     create

→  stage 1 · Target resolution
   ✓ kind=PlatformResource  target=apifixture  alias=(none)

→  stage 2 · Token check
   ✓ token control-center can create on PlatformResource

→  stage 3 · CR construction
   ✓ name=my-payment-service  namespace=team-payments
      {
        "apiVersion": "gateway.fixture.orkestra.io/v1alpha1",
        "kind": "PlatformResource",
        "metadata": { ... },
        "spec": {
          "environment": "staging",
          "productionApproval": "JIRA-1234",
          "repoURL": "https://github.com/myorg/payments",
          "team": "platform",
          "workloadType": "app"
        }
      }

→  stage 4 · Provenance annotations
      orkestra.orkspace.io/serve-target: apifixture
   ✓ provenance stamped

→  stage 5 · Response payload
      {
        "alias": "",
        "phase": "",
        "source": "",
        "target": "apifixture"
      }
   ✓ payload evaluated

✓ Intent would be accepted
  POST /api/v1/apply  →  PlatformResource/my-payment-service in team-payments

Why play?

The gateway is an intent runner. The runtime is a CR runner. The gateway collects intentions — flat fields from a caller — and translates them into a valid Kubernetes object. The runtime takes that object and reconciles it into cluster resources. Neither needs a cluster to do its job locally. ork serve play runs the gateway’s half; ork simulate runs the runtime’s half.

ork serve play is the local equivalent of running a full GitOps webhook delivery cycle. Play lets you verify:

  • The intent file builds the CR you expect.
  • The token you plan to use is allowed for the target and operation.
  • The field routing (spec, labels, annotations) resolves correctly.
  • The serve.name and serve.namespace expressions produce the right values.
  • The response payload evaluates as expected.

Simulate handoff

With --simulate, play hands the built CR (already stamped with provenance annotations) directly to ork simulate. This covers the full local delivery loop without a cluster:

intent file  →  ork serve play  →  CR  →  ork simulate  →  child resources

--simulate without a path runs simulate in op-print mode. --simulate simulate.yaml runs simulate in assert mode — katalog, cycles, skipExternal, and expect: all come from the spec, but play’s CR is substituted for spec.cr. This lets you write intent-level tests that assert both that the intent produces the right CR and that the CR produces the right child resources.

# simulate.yaml alongside your intent file
apiVersion: orkestra.orkspace.io/v1
kind: Simulate
metadata:
  name: payment-service-intent
spec:
  katalog: ../../katalog.yaml
  cr: ""            # cr is ignored — play supplies the CR
  cycles: 5
  skipExternal: true
  expect:
    steady: true
    steadyAt: 2
    noErrors: true
    ops:
      - cycle: 1
        verb: create
        resource: deployments

None of this requires a running gateway, cluster access, or a token secret — just a Katalog, an intent file, and optionally a simulate spec.


ork serve apply

Apply an intent or CR to a live gateway via POST /api/v1/apply.

The file may be a flat intent (target mode) or a full CR (apiVersion + kind). Both YAML and JSON are accepted. If --file is not given, ork serve apply looks for intent.yaml first, then intent.json, in the current directory.

The gateway handles everything on the other side: target resolution, token validation, admission, provenance stamping, and CR delivery. This command sends the body and prints the structured response.

ork serve apply [flags]

Flags

FlagShortDefaultDescription
--file-f(auto-detect)Intent or CR file (YAML or JSON)
--api-ahttp://localhost:8080Gateway base URL
--token-t(required)Bearer token for the gateway
--dry-runfalsePreview without applying — the CR is not written to the cluster

Examples

# Apply from the default intent.yaml in the current directory
ork serve apply --api https://gateway.myorg.io --token "$ORK_TOKEN"

# Apply an explicit file
ork serve apply -f intent.yaml --api https://gateway.myorg.io --token "$ORK_TOKEN"

# Dry run — validate at the gateway without applying
ork serve apply -f intent.yaml --api https://gateway.myorg.io --token "$ORK_TOKEN" --dry-run

# Apply a full CR directly (not target mode)
ork serve apply -f cr.yaml --api https://gateway.myorg.io --token "$ORK_TOKEN"

# Local gateway (default port)
ork serve apply --token "$ORK_TOKEN"

# Show the raw gateway response (useful when diagnosing rejections)
ork serve apply -f intent.yaml --api https://gateway.myorg.io -t "$ORK_TOKEN" --verbose

Output

Accepted:

  serve apply  intent.yaml

  ✓ PlatformResource  team-payments/my-payment-service
  poll: https://gateway.myorg.io/api/v1/resources/platformresource/team-payments/my-payment-service

accepted

Rejected:

  serve apply  cr-bad.yaml

  ✗ images must come from the internal registry (../registry.internal/)
    ↳ spec.image  images must come from the internal registry (../registry.internal/)

apply rejected

Dry run:

  serve dry-run  intent.yaml

  ✓ PlatformResource  team-payments/my-payment-service

dry-run accepted

How it works

ork serve apply reads the file, marshals it to JSON, and posts it to {api}/api/v1/apply. The gateway detects whether the body is target mode (flat fields with a target key) or full CR mode (apiVersion + kind) and handles both paths identically. The command exits with code 0 on acceptance and code 1 on rejection.

--dry-run adds ?dryRun=true to the request. The gateway runs the full admission pipeline — token check, field validation, admission webhooks — but does not write the CR to etcd. Use it to validate an intent against a live gateway before committing.

Intent file vs CR file

ShapeDetectionWhen to use
Flat fields + target:"target" key presentNormal developer workflow — same shape as the Control Center form
apiVersion + kind + metadata + specNo target keyApplying a pre-built CR directly, CI pipelines that assemble full objects

Both shapes are valid input. The gateway’s field declaration determines where fields land in the CR (spec.*, metadata.labels.*, etc.). A full CR bypasses the gateway’s field routing and is applied as-is, subject only to admission.

GitOps pattern

The gateway validates on every apply — token permissions, field constraints, admission rules. A rejected apply exits non-zero and the pipeline stops.

Use --dry-run to verify an intent against a live gateway before committing:

# Verify — gateway validates, nothing is applied
ork serve apply -f intent.yaml --api https://gateway.myorg.io --token "$ORK_TOKEN" --dry-run

# Deliver — gateway applies
ork serve apply -f intent.yaml --api https://gateway.myorg.io --token "$ORK_TOKEN"

ork serve play requires the Katalog — it is a platform team tool for testing Katalog changes before deploying. A consumer CI pipeline has only the intent file and a token; --dry-run is the right validation path for that case.

Rollback: revert the intent file in Git and re-run ork serve apply against the reverted commit.