Security

Security, stated plainly.

Curule runs agents that execute shell commands and write code. That is the product, and it sets the posture: the agents are not trusted to stay inside a box that the software merely asks them to stay in. The box is the container, and the unit of isolation is one instance per team. This page says what is built around that, and where it ends.

What it protects

The controls on the server, the agents and the records are each pinned by tests that npm test runs, and the security document names them. The container’s settings are checked in continuous integration, by a smoke test of the built image and by linting and rendering the chart.

The security document

Reaching the server

  • It fails closed on the network.Listening on anything but loopback requires an operator token of 32 or more characters. A missing, blank or short token is a refusal at start, not a warning.
  • Sign-in is a session.The dashboard trades the token for a cookie that is HttpOnly and SameSite=Strict, and Secure over HTTPS. The token is never accepted in a URL, where logs and history would keep it.
  • Pages cannot drive it from another site.A state-changing request from a page must be same-origin or from an origin you list, and the Host header must be one the server answers to, which stops DNS rebinding. No response carries a CORS header.
  • Guessing is slowed, and bounded.Wrong credentials are counted per client address and answered with 429. A random token of 32 or more characters is the real defence. Request bodies, event-stream subscribers and the designer’s model calls are capped.

The agents, and what they write

  • Agents never hold the operator’s credentials.The operator token, the licence and the other MESH_* secrets are removed from the environment the agents’ commands run in. An agent reaches the mesh with a credential minted in memory for each turn.
  • A page an agent wrote is sandboxed.It is served in a sandboxed frame on an opaque origin, through a signed link that expires, with no cookie and no route back to the API.
  • Files stay where they belong.Paths are resolved through their real locations, so a link in a workspace cannot point out of it, and in the image the project registry is confined to one folder.
  • Only the human changes the mission.The tools that change the mission itself (its goal, criteria, seats and budgets) answer only to the human operator, not to an agent that is asked to call them.
  • Cost has a ceiling.Budgets per agent, thread and mission, and a host-wide spend ceiling that prices all four token classes. It is a backstop; the control is a spend limit at your provider.

Records and recovery

  • Everything is an event.Every change is an appended event and every view is a projection, so any past moment can be replayed and nothing is edited in place.
  • There is an audit trail, without identity.Every state-changing request that was let through is logged with how it was authorised and the client address. With one shared credential it cannot say who.
  • One writer.Each state directory has a lock with a heartbeat, and a process that loses it exits rather than interleave two writers.

The container

  • The image is restricted.An unprivileged user, a read-only root file system, every capability dropped and no-new-privileges. It holds no credentials; they are supplied at run time.
  • The chart is restricted too.One replica, a restricted pod with no service-account token, and a network policy on by default that allows egress only to DNS and public HTTPS, with private ranges and the cloud metadata address excluded.

What leaves your environment

Less than most people expect, and one thing that cannot be avoided.

  • Calls to your model provider.The agents make them, with your credentials. Prompts, files and tool output go to that provider under your agreement with it. This is inherent to running the agents.
  • Nothing else from the product.No telemetry, no analytics, no update check and no licence server. A licence is verified on the machine.
  • The Claude Code binary is Anthropic’s.Left alone it reports telemetry and errors and checks for updates, so the image sets CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1. Setting it to an empty value turns that off.
  • Whatever the agents themselves fetch.Package registries, git hosts, the web: wherever your network lets them reach.

This website holds itself to the same rule. It makes no request to any other site and sets no cookie; see the privacy section.

What it does not do

Read this section before you promise anything to your own customers.

  • No single sign-on and no per-operator identity.There is one operator token: no user accounts, no roles. The audit trail says how a request was authorised and from where, never who. Single sign-on (OIDC), per-operator identity and roles, and audit-log export with identity are planned, not included. Until then, restrict the network path and put an authenticating proxy in front if you need to know who reached the sign-in page.
  • The agents can use what the container can reach.An agent’s shell runs as an unprivileged user inside the container, with the provider credential in its environment, because it needs it. A misbehaving or prompt-injected agent can read the workspace and that credential, and send things anywhere your network allows. The container is the boundary: narrow its egress, give each instance its own provider key with a spend limit set at the provider, and keep out of the workspace any secret you would not give an engineer.
  • No isolation between projects in one instance.Projects share the container, its user and its volume. Anyone who must not see another’s work gets their own instance.
  • TLS and encryption at rest are yours.The server speaks plain HTTP and expects TLS in front of it. It does not encrypt its own files: use an encrypted volume and encrypted backups.
  • The event log holds everything the agents saw and said.That includes any secret that passed through a prompt or a command’s output. There is no redaction, so treat the volume and every backup of it as sensitive as the most sensitive thing an agent may read.
  • It has not been independently assessed.No third-party penetration test, no SOC 2, no ISO 27001. The controls are tested by the repository’s own suite and were exercised in a real browser. That is not an audit.
  • The licence check is not tamper-proof.The runtime is JavaScript, and anyone who can edit it can remove the check. A licence is how an honest customer shows what was bought; the licence terms are what bind.

What to do about it

A hardening checklist for whoever deploys it. The Helm chart sets the host, proxy and cookie settings in the first item and ships the network policy in the fourth.

  1. Put TLS in front and set the cookie, proxy and host settings that say so.
  2. Use a strong token from a secret store, rotate it on a schedule and when anyone who knew it leaves.
  3. Do not put it on the open internet. Reach it over a VPN or a private ingress.
  4. Narrow the egress to the model provider, your git host and your package mirror, and keep the network policy on.
  5. Give each instance its own provider key, with a budget and alerts at the provider.
  6. Encrypt the volume and its backups, and restrict who can read them.
  7. Ship the audit trail to a log store you retain.
  8. Pin the image by digest and verify its signature once releases are published.
  9. Watch the metrics: crashed projects, spend against the ceiling, escalations waiting for a person.
  10. Plan for the agents being wrong. Review what they merge before it ships. A gate somebody configured is the control; the agents’ good behaviour is not.

Assurance

What stands behind these statements, and what does not.

  • Tests, run on every change.The continuous integration runs the type checker, the linter and the whole test suite, and a weekly job runs a production-dependency audit and a code scan.
  • Defects are kept, not hidden.A budget key named __proto__ once polluted every object in the process. It was found, fixed, and is pinned by a test.
  • No outside assessment.Nobody independent has tested it, and this site shows no certificate, award or customer logo because there is none.
  • Nothing is published yet.There is no release tag and no container image in a registry. The release workflow is written to publish a signed image with an SBOM and build provenance, and it has not run.

Reporting a problem

Privately, please.

Please do not open a public issue for a security problem. Report it through GitHub’s private vulnerability reporting, or by email to the security address on the contact page. Say what you found, how to reproduce it, what an attacker gains, and whether you have told anyone else.

  • We acknowledge your report within 3 business days.And tell you within 10 business days whether we think it is a vulnerability and how serious.
  • A fix, or a mitigation and a date, within 30 daysfor a high or critical issue. Public disclosure follows a fix, coordinated with you, and we credit you unless you prefer not.
  • Good-faith research is welcome.Test only instances you own or have permission to test, and avoid reading or changing anyone else’s data. The policy sets out the rest.

Where to writeRead the security policy