Security

fctl runs code-writing agents with access to your repositories and your Claude subscription. This page says what it protects, how, and what it trusts.

What it protects

Asset Where it lives Who can use it
Passwords argon2id hashes in D1 nobody can read them back
Sessions and tokens SHA-256 hashes in D1; the secret only with its holder the holder
Claude credentials encrypted (AES-256-GCM) in D1 sessions their owner starts
Project secrets encrypted in D1 that project's sessions, as environment variables
GitHub App key a Worker secret the control plane, to mint short-lived tokens
Master key a Worker secret the control plane

Encrypted values are bound to their row (the AES-GCM associated data names the owner and purpose), so a value copied between rows does not decrypt.

Access

Sandboxes

Each session runs in its own Linux VM (Apple container or Lima) or container (Docker). The agent runs Claude Code with permission prompts off, because the sandbox is the boundary: it can do anything inside its VM, and nothing outside it except through these channels:

The process driver has no isolation at all and is for development only.

Billing

fctl is built so agents only ever use Claude subscriptions:

Hosts

Hosts connect outbound to the control plane over TLS (rustls with the Mozilla root store); they open no ports. A host authenticates with a runner token that admins can rotate or revoke. Hosts receive a session's credentials only while it runs, and keep nothing secret on disk but their runner token (~/.config/fctl/host-token, mode 0600).

Reporting a vulnerability

Report it privately through GitHub: Security → Report a vulnerability on hyperstructure/fctl, with details and a way to reproduce. Please do not open a public issue. We will acknowledge within three working days and keep you updated until it is fixed.