Ctrl K
ComunidadGuías…

SECURITY.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Security Posture

My AX is a single-operator agent. One person deploys it, one verified identity
owns it, and that identity authorizes every action. This page states the trust
model, the identity and network boundaries, what each execution place can do,
and what My AX does not do. It is written for a security reviewer.

## Trust Model

My AX is not multi-tenant. One owner runs one deployment in their own Cloudflare
account. The owner authorizes the agent to act with the owner's own authority.

My AX is not a remote-access tool. It takes no inbound connection to any machine
the owner connects. The agent acts through paths the owner configures, gates with
Cloudflare Access, and can stop.

The agent does the work. The owner approves it, steers it, and stops it. Every
action writes a receipt the owner can read.

## Identity And Authentication

Cloudflare Access verifies every request at the edge. `src/auth.ts` then
verifies the Access JWT against the JWKS: it checks the issuer, the audience, the
signature, and the expiry. It extracts the email and attaches the identity to
the request context.

Every route reads that identity and scopes its data by email. The Sandbox
container, the OAuth token store, and the D1 session rows are all keyed by email.
A request without a verified identity is rejected.

Local development can bypass Access only when three conditions all hold:
`ENVIRONMENT=dev`, the Access issuer and audience are empty, and `DEV_USER_EMAIL`
is set, together with a local-runtime signal. A deployed Worker cannot enter this
path.

## Network Posture

The machine companion connects outbound only. It opens no inbound port, exposes
no public tunnel, and accepts no bearer-token-in-a-URL. It connects to the one
Worker endpoint the owner configures.

The Worker exposes no unauthenticated surface for owner data. `workers_dev` and
preview URLs are disabled, so the Access-gated custom domain is the only route.

A shared public-URL policy screens connector and browser destinations. It rejects
private, loopback, link-local, and reserved addresses, and rejects URLs that
carry credentials. The Browser Run path validates both the requested URL and the
final URL.

## Capability Boundaries

Generated code runs in a bounded sandbox. Work Code Mode gives the Dynamic Worker
a 60-second wall-clock limit, a 32,000-byte source limit, and no ambient network
access. The sandbox has no direct database, secret, or network binding. It calls
allowlisted server-side handlers only. A handler keeps its normal authority; the
sandbox does not add or remove it.

Connector tokens are stored encrypted. `OAuthClientDO` encrypts each grant under
the deployment-wide `MASTER_KEY` with owner-bound context and refreshes it before
expiry. The model never sees a bearer token; a trusted server-side adapter
attaches it.

Tool calls through the bridge carry a scoped ticket. `src/bridge.ts` mints a
short-lived ticket, verifies its scope, attaches the upstream credential, and
writes an audit receipt to `AUDIT_KV` with a 90-day retention. Each record holds
the caller, the target, the method, and the timestamp.

The connector operator allowlists exact MCP method identifiers for Code Mode. My
AX does not prove that an allowlisted method has no side effect.

## The Machine Companion

The machine companion ([machinectl](https://github.com/acoyfellow/machinectl))
is the highest-authority place the agent can act, and it is opt-in. The owner
installs it and runs it. It is not installed or reachable by default.

Its `shell` tool is terminal-equivalent. It can read credentials, run programs,
delete files, or move data as the local user. `MACHINECTL_ALLOWED_PATHS`
constrains an explicit working directory; it does not constrain the content of a
shell command. This is a deliberate trust model, not a sandbox.

Run the companion only under these conditions:

- Run it under a dedicated, least-privilege OS account.
- Trust the model or person that sends commands.
- Trust the MCP clients your Access policy permits.
- Trust the Worker deployment the companion connects to.

Do not use the machine companion for a workload whose data policy requires
container isolation, credential-file blocking, or a read-only working directory.
Use the container workspace or a Terrarium run for those workloads.

## What My AX Does Not Do

- It does not accept an inbound connection to a connected machine.
- It does not let a third party control a machine. One verified owner authorizes
  the agent.
- It does not run without Cloudflare Access in production.
- It does not expose owner data on an unauthenticated URL.
- It does not send data outside the deployment except to the model providers,
  MCP servers, and services the owner configures. Each receives only what the
  agent sends it and retains data under its own policy.
- It does not guarantee container isolation on the machine-companion path. That
  path runs as a real OS account.
- It does not physically delete a Durable Object when the owner deletes a
  session. Deletion removes owner reachability and indexed data.

## Data Handling

Cloudflare Access identity is the owner key. D1 stores the session registry, a
projected transcript index, push subscriptions, Attention, jobs, and appended run
receipts. R2 stores upload bytes and workspace snapshots. `AUDIT_KV` stores
bridge call receipts for 90 days.

Workspace snapshots are point-in-time backups, not continuous replication. A
container failure can lose writes made after the last successful snapshot.

## Deployment Boundary

The public repository is a generic engine. Organization-specific hosts, account
resources, MCP catalogs, Access settings, and secrets belong in a private
deployment wrapper. They must not be committed to the public repository.

Each installation must own separate Worker, D1, KV, R2, Durable Object, Access,
and secret state. Installations may share a source revision. They must never
share runtime resources.

## Compliance Mapping

State the controls your organization requires against the boundaries above. Do
not treat this section as a compliance claim. It is a place for the deploying
team to record the mapping it has verified.

| Control area | Where My AX addresses it |
|---|---|
| Authentication | Cloudflare Access JWT verification (`src/auth.ts`) |
| Authorization | Owner-scoped by verified email on every route |
| Secret storage | `OAuthClientDO` encryption under `MASTER_KEY` |
| Audit | Bridge receipts in `AUDIT_KV`, 90-day retention |
| Network egress | Outbound-only companion; SSRF and destination policy (`src/public-url.ts`) |
| Isolation | Per-owner container; Code Mode sandbox; sandboxed artifact iframe |

## Reporting A Vulnerability

Report a suspected vulnerability through GitHub's **Report a vulnerability** flow
under the repository's Security tab. Do not open a public issue for a suspected
vulnerability, a credential, a private deployment detail, or user data.

Include the affected revision, the reproduction steps, the impact, and any
suggested mitigation. Do not access data that is not yours while you validate a
report. Do not publish a working exploit before a fix is available.

Relevant reports include authentication or identity confusion, cross-user or
cross-machine tool routing, escape of an explicit working-directory or session
path, a missing audit receipt, leakage of a secret beyond a documented preview,
and a child-process cleanup or lifecycle bypass.

## Supported Versions

Security fixes target the current `main` branch. Older deployed revisions and
tags are not supported unless their release notes say otherwise. My AX is
self-hosted. The deploying owner is responsible for updating dependencies,
configuring Cloudflare Access, preserving encryption secrets, and applying
migrations.