Skip to content

About

Crewlet Kubernetes Operator

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

The Crewlet character on a stack of shipping containers, mug in hand, a ship's wheel beside it

Crewlet Operator

Run Crewlet companies on Kubernetes.

The Crewlet Operator makes a Crewlet AI agent company a native Kubernetes object. You declare the company and its org chart — units, seats, model providers, tool servers, integrations, schedules — as custom resources, and the operator runs the company's engine and keeps its live configuration equal to what the resources say.

CI License: MIT Go 1.27+ Kubernetes 1.37 API: crewlet.ai/v1alpha1 Docs

Quickstart · Installing · Concepts · Documentation · Contributing


A company is a Kubernetes object

You write a company the way you write a Deployment, and the operator keeps the engine equal to it. The same API serves a self-hoster writing YAML and a control plane provisioning a company for every tenant.


A company is a resource
Declare a Company and its units, seats, models, tool servers, integrations and schedules as crewlet.ai objects — reviewed, diffed and synced like the rest of your cluster.

The org chart is objects
A Seat points at its Unit, a Unit at its parent. Each is added, permission-scoped and deleted on its own — not edited inside one shared file.

Applied whole, or not at all
Every change renders one company document, which the engine dry-runs and applies as one revision. An object that cannot be applied safely holds the next one back — the last good revision keeps running.

Credentials by reference
No field takes a secret. Every credential is a reference to a Kubernetes Secret. Those the company document uses are pushed into the engine's encrypted store and rotated live, and no value is written into a pod template.

An engine for every company
The operator runs each company's engine: its data pod and volume, seat pools beside it, Services, webhook routes and network policy — and cleans up after it.

Built for many tenants
A namespace per tenant, EngineClasses as tiers, server-side apply from your control plane — and no admission webhooks, so no cert-manager.

Alpha: do not run it against anything you care about. The crewlet.ai/v1alpha1 API changes without notice, and nothing is released yet. Status says what works today.


How it works

flowchart LR
    PA["<b>Platform admin</b>"] -->|EngineClass| K
    U["<b>kubectl or GitOps</b><br/><i>or a tenant control plane</i>"] -->|"Company, Unit, Seat, LLMProvider,<br/>MCPServer, Integration, Schedule"| K
    U -->|Secrets| K
    K[("<b>Kubernetes API</b>")] --> O["<b>Crewlet Operator</b><br/><i>runtime, config and<br/>class reconcilers</i>"]
    O -->|"StatefulSet, Services, routes,<br/>keyring, NetworkPolicy"| E
    O -->|"company document, applied whole"| E
    O -->|"referenced secret values"| E
    E["<b>Crewlet engine</b><br/><i>one per Company</i>"]
    V["<b>Slack, GitHub, GitLab, …</b>"] -->|"/webhooks/ on the public listener"| E
    SB["<b>A remote sandbox</b>"] -->|"/otlp/ and /mcp/ on the public listener"| E
Loading
  • The runtime reconciler makes the engine exist. From the Company and the EngineClass it names — a cluster-scoped set of platform defaults and limits, the way a StorageClass is — it creates and owns the engine's StatefulSet, storage, keyring and API tokens, Services, webhook routes and network policy. A third reconciler checks that each EngineClass names what exists.
  • The config reconciler makes its configuration match. It collects the Unit, Seat, LLMProvider, MCPServer, Integration and Schedule objects that reference the company, renders them into the single company document Crewlet runs on, has the engine validate it, and applies it whole or not at all: one unresolved reference holds the next revision back and is reported on the object that caused it, while the last good revision keeps running.
  • Credentials go by reference, never by value. No field accepts a secret: every credential is a reference to a Kubernetes Secret, whose value the operator pushes into the engine's encrypted secret store and rotates live. Who put the value there — a person with kubectl, External Secrets, or a control plane after a vendor's install flow only it knows about — is invisible to the operator.

That is the glance; How the Operator Models a Company explains the kinds and how they relate, and How the Document Is Applied what happens on every change.


Quickstart

There is no engine to build: the operator is tested against Crewlet's main, which Crewlet publishes as ghcr.io/crewlet/crewlet:main, and the cluster's node pulls it when the first company starts. On a throwaway kind cluster, with the operator's image built from this checkout:

make kind kubectl                                 # the pinned kind and kubectl, in bin/
bin/kind create cluster --name crewlet
make docker-build IMG=crewlet-operator:dev
bin/kind load docker-image crewlet-operator:dev --name crewlet
make install deploy IMG=crewlet-operator:dev      # or: make helm-deploy IMG=crewlet-operator:dev

Beside the EngineClass a platform provides and the Secret holding its model key, a company with one agent can be five objects — the Company, the model provider its seats run on, a Unit, an agent Seat in it, and a Human Seat for the person who joins the company and manages the unit:

apiVersion: crewlet.ai/v1alpha1
kind: Company
metadata:
  name: acme
spec:
  engineClassName: local
  companyName: Acme
  mission: Make widgets people love.
  deletionPolicy: Delete
---
apiVersion: crewlet.ai/v1alpha1
kind: LLMProvider
metadata:
  name: anthropic
spec:
  companyRef:
    name: acme
  type: Anthropic
  model: claude-sonnet-5
  apiKeySecretRefs:
    - name: anthropic
      key: apiKey
---
apiVersion: crewlet.ai/v1alpha1
kind: Unit
metadata:
  name: engineering
spec:
  companyRef:
    name: acme
  displayName: Engineering
  type: Department
  purpose: Build the widgets.
---
apiVersion: crewlet.ai/v1alpha1
kind: Seat
metadata:
  name: lead
spec:
  companyRef:
    name: acme
  displayName: Engineering Lead
  unitRef:
    name: engineering
  goal: Decide what Acme builds next and keep the team unblocked.
  llm:
    default:
      - name: anthropic
---
apiVersion: crewlet.ai/v1alpha1
kind: Seat
metadata:
  name: founder
spec:
  companyRef:
    name: acme
  kind: Human
  displayName: Founder
  manages:
    - kind: Unit
      name: engineering

The full Quickstart walks through the rest: the EngineClass and the Secret, a second seat, what every object reports, changing the company, joining it in its dashboard and removing everything again.


Requirements

  • A Kubernetes cluster on 1.37. The operator supports one minor release of Kubernetes, the one it is tested against: a release supports the minor its tests ran on, and the operator moves to each new minor once kind and envtest, which the tests run on, ship it. The e2e suite runs on kind's default node image, Kubernetes 1.37.
  • A CNI that enforces NetworkPolicy, for the isolation the operator sets up around each engine.
  • To build and run from source: Go (the version in go.mod), Docker, make, git and curl. Every other tool is pinned in the Makefile and downloaded into bin/.

Status

The operator is alpha, under active development, and has no release yet. It runs a company end to end today:

  • It accepts each Company whose EngineClass resolves and whose objects stay within the class's limits.
  • It runs the company's engine: the StatefulSet, storage, keyring and API tokens, Services, webhook routes and network policy.
  • It applies the company document, with the Secret values it references, as the company's management policy says, and cleans up after the company as its deletion policy says.
  • It runs one data pod per company, and the seat pools a company declares as stateless pods beside it, Shared or one pod per seat, and reports on each Seat which pod the engine runs it on.

Highly available companies, with more than one data pod, come later. The e2e suite proves all of the above on kind against Crewlet's main, as Crewlet publishes it at ghcr.io/crewlet/crewlet:main; every test suite runs that engine, so a Crewlet change that breaks the operator fails the operator's next run.


Documentation

Start here

  • Quickstart — the operator and a small company on a local kind cluster
  • Installing the operator — the Helm chart, the engine image to run, the values that matter

Core concepts

Guides

Reference

  • API reference — every kind and field of crewlet.ai/v1alpha1, generated from the types

Every page is also published at docs.crewlet.ai/operator, beside the engine's documentation.


Contributing

Issues and pull requests are welcome. CONTRIBUTING.md covers the development setup, the checks, the API change policy and the commit conventions:

make check      # every gate CI runs except the e2e suite and the image build
make test       # the unit, envtest, engine and chart suites, both modules, -race
make test-e2e   # a kind cluster (Docker 28+); pulls the engine image too
make help       # everything else

Commits are signed off (git commit -s), which certifies the DCO over them — CI checks it. Releases are cut by pushing a v* tag — see RELEASING.md. Participation is governed by the Code of Conduct.

Security issues: please report them privately — see SECURITY.md, which also describes the operator's security properties.

License

MIT

About

Crewlet Kubernetes Operator

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages