Reference Guide

The Ringleader resource model: how the objects relate, and a field-by-field reference for each kind.

Everything in Ringleader is a resource: a Kubernetes-style object with apiVersion, kind, metadata, spec, and (for most kinds) status. You declare the spec; the control plane and the in-VM agent write status as they bring the real machine in line with it. You never edit status.

This guide covers the kinds you author most often:

  • Workstation: a single managed machine (VM, container, or cloud VM).
  • WorkstationConfig: a reusable configuration layer applied to workstations.
  • Devtools: the curated install recipes a config can declare, one page per tool.
  • Tool configuration: declarative configuration for the tools on a workstation, one page per tool.
  • LocalBinding: a device-local port/socket forward from a workstation to your machine.
  • CloudIdentity: the credential broker that lets the control plane create cloud VMs.
  • CloudAccount: the link between one organization and one cloud account, recording the cloud identity to use.
  • SSHKey: forward a local private key into workstations as an ambient ssh-agent.
  • Providers: how a workstation is placed on lima or GCP.
  • Access control: namespaces, ownership, RBAC roles, and Grants.
  • Organizations: the tenancy layer above namespaces — a company, its verified domain, and who administers it.
  • ServiceAccount: a non-human identity CI and automation sign in as, with no stored secret.

Start with the relations below to see how they fit together, then dive into a specific kind.

Relations between objects

A Workstation is the center of the model. The other kinds either shape it (configuration, credentials) or connect to it (forwards).

              ┌────────────────────┐
              │  WorkstationConfig  │  reusable config layers
              │  (selector +        │  (image, packages, devtools,
              │   priority)         │   ports, identity, …)
              └─────────┬──────────┘
                        │ applied by selector match
                        │ or explicit spec.configs[]
   ┌───────────────┐   config merge    ┌──────────────────┐
   │ CloudIdentity │ ─────────────────▶│   Workstation    │
   │ (per provider │  brokers cloud    │  spec → status   │
   │  credentials) │  credentials by   │  + conditions    │
   └───────┬───────┘  label selector   └────────┬─────────┘
           │                                     │ when Running, the daemon
           │                                     │ seeds a device-local forward
           │                                     ▼
           │                            ┌────────────────┐
           │                            │  LocalBinding   │  forwards a
           │                            │ (device-local)  │  workstation's ports
           │                            └────────────────┘  to your machine
           │ cloudAccountRef
  ┌────────────────┐
  │  CloudAccount   │  which cloud identity to use: which cloud
  │ (cluster-scoped,│  principal to become, and whose trust
  │  org-owned)     │  accepts our assertion
  └────────────────┘

How they connect

  • Workstation → WorkstationConfig. A workstation receives config either by explicit reference (spec.configs: [{name, priority}]) or by selector match: a WorkstationConfig whose spec.selector.matchLabels match the workstation’s labels attaches automatically. All matching configs plus the workstation’s inline spec are merged as config layers (lower priority applies first) into one effective spec, which rl workstation get-resolved-configuration prints on demand.

  • Workstation → CloudIdentity. When a workstation routes to a cloud provider, the control plane picks the CloudIdentity in the same namespace whose spec.provider matches and whose spec.selector.matchLabels match the workstation’s labels (highest priority wins). That identity brokers the short-lived credentials used to create the VM, and can inject provider-config defaults/overrides.

  • CloudIdentity → CloudAccount. A spec.cloudAccountRef points at a cluster-scoped CloudAccount — which cloud identity to use for the organization that owns the namespace. This selects per-organization federation, in which Ringleader presents a signed, organization-scoped assertion to your cloud’s own trust configuration and stores no credential at all.

    Alternatively, a spec.impersonation block selects the legacy shared-intermediary chain; with neither field, the control plane’s own default identity is used. cloudAccountRef and impersonation are mutually exclusive — they are the credential paths, not layers. Ringleader stores no cloud credential at rest on any of them.

  • Workstation → LocalBinding. Forwarding is not implicit. When a workstation with a spec.defaultLocalBinding template first reaches Running, the daemon seeds one device-local LocalBinding from it (once, deletion is honored). You can also author LocalBinding objects directly.

Reading status

Every kind that reports a status carries a top-level status.message: the one human headline for what is going on with that object, in a sentence. It is deliberately universal, so you can read any object’s state without first learning that kind’s sub-status keys or condition vocabulary:

rl workstation get my-box -o jsonpath='{.status.message}{"\n"}'
rl binding get -o jsonpath='{.status.message}{"\n"}'

Where a kind also has conditions, the two never disagree: they are derived from one computation. status.message is the headline; conditions[].message is the per-aspect detail, and the condition’s reason is a value from a closed set you can branch on.

Status is server-owned — a client can never write it — and it is curated: an internal failure surfaces as a generic message plus a reference id, never a raw error, so a status is always safe to paste into a ticket.

Namespace scoping

Most kinds are namespaced, and cross-references stay within a namespace: a workstation’s configs, its CloudIdentity, and a CloudIdentity’s credential Secret all live in the same namespace. Two exceptions:

  • CloudAccount is cluster-scoped and owned by an organization, not a namespace. A CloudIdentity may only reference an account belonging to the organization its own namespace belongs to.
  • LocalBinding is device-local: it never leaves the machine that materializes it and is never synced or mirrored.

Apply order

When you apply a multi-document manifest, Ringleader orders the writes so references resolve: organizations first, then namespaces, then Secrets and CloudAccounts, then CloudIdentities, then WorkstationConfigs, then Workstations, and finally LocalBindings.