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.
Quickstart · Installing · Concepts · Documentation · Contributing
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.
Alpha: do not run it against anything you care about. The
crewlet.ai/v1alpha1API changes without notice, and nothing is released yet. Status says what works today.
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
- The runtime reconciler makes the engine exist. From the
Companyand theEngineClassit names — a cluster-scoped set of platform defaults and limits, the way aStorageClassis — it creates and owns the engine's StatefulSet, storage, keyring and API tokens, Services, webhook routes and network policy. A third reconciler checks that eachEngineClassnames what exists. - The config reconciler makes its configuration match. It collects the
Unit,Seat,LLMProvider,MCPServer,IntegrationandScheduleobjects 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 withkubectl, 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.
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:devBeside 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: engineeringThe 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.
- 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 theMakefileand downloaded intobin/.
The operator is alpha, under active development, and has no release yet. It runs a company end to end today:
- It accepts each
CompanywhoseEngineClassresolves 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.
|
Start here
Core concepts
Guides
Reference
Every page is also published at docs.crewlet.ai/operator, beside the engine's documentation. |
|
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 elseCommits 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.