Title: Security model · Codemany docs
URL: https://codemany.com/docs/security
Description: Codemany's security model in brief: what a job on a self-hosted runner can reach, public repositories, where tokens and cloud credentials are kept, the LAN dashboard, the fleet, cloud machines and signed updates.
All pages as Markdown: https://codemany.com/llms.txt

---

[Security](https://codemany.com/docs#security)

# Security model

What Codemany runs, who can touch it, and what stops things going wrong. The short version: a self-hosted runner is not a sandbox, so only run workflows you would run in your own terminal.

## What a job can reach

In the default `host` mode, every job runs as the user Codemany runs as, so it can do anything that user can:

- read and change your files, SSH keys, browser profiles and source trees;
- install login items, edit shell profiles and leave processes running after the job;
- reach every device on your network.

Runners are single-use: each job gets a fresh just-in-time registration and the work directory is wiped afterwards. That stops jobs from sharing a runner, but it doesn't isolate a job from the machine. The opt-in [isolation modes](https://codemany.com/docs/runners/isolation) do more.

## Public repositories

- **Refused by default.** Anyone can open a pull request from a fork, and on a public repo that can run their code on your machine. Codemany serves a public repo only if you opt in for that repo.
- **Checked again.** It also refuses one whose fork pull-request approval setting is too weak or whose workflows use risky triggers, and re-checks every 30 minutes, because a repo can be made public later.
- **Organizations.** Public repos are supported per repository: organization-wide runners can't be limited to public repos.

## Reduce the blast radius

- Use a fine-grained token limited to the repos Codemany serves, with an expiry ([Connect GitHub](https://codemany.com/docs/get-started/github#token)).
- Run Codemany on a dedicated machine or user that holds no personal data and no other credentials.
- Don't keep long-lived cloud credentials in that user's home: use OIDC from the workflow instead.
- Remember who can push can run code: anyone with write access can add a workflow that targets your runners.

## Where secrets live

| Secret | Where |
| --- | --- |
| GitHub token, license, device id | macOS: one Keychain item, `com.codemany.vault`, that trusts only Codemany.app and its daemon. Linux: a vault file only you can read (0600), or the desktop keyring |
| Cloud provider tokens, Google sign-ins, cloud machines' SSH keys | The Mac Keychain or the Linux keyring only, never a file |
| License token | `~/.codemany/license.token`, mode 0600, signed and bound to the machine |
| Admin token | `~/.codemany/config.json`, mode 0600 |
| A runner's registration | That runner's environment only: never on its command line, never logged |

None of these are sent to Codemany's servers. What does leave your machine is listed in the [Privacy Policy](https://codemany.com/privacy).

## The LAN dashboard

The dashboard on port 8825 is read-only from other devices: it shows runner and job status, never tokens or the license. Every change (drain, resume, recycle, settings) needs a bearer token, even from the machine itself, so a CI job can't drain the fleet. Job logs open only for the machine's owner or with the admin token. `codemany admin-token` prints the token for a browser.

## The fleet

Machines pair with a one-time code, then sign every request to each other with a key only the two of them hold; replays and stale requests are refused. Membership is trust: every member can open and control every other. See [The fleet](https://codemany.com/docs/machines#trust).

## Cloud machines

- Only SSH is open, with key-only login and a host key the app made and pins: no trust on first use.
- The dashboard is firewalled to the machine itself on every boot; setup runs over SSH.
- Codemany only touches machines carrying its tag, whatever the credentials could reach, and recommends a project or account for Codemany alone.
- Jobs run as separate users and can't read the cloud's metadata service over HTTP.
- The price is shown before you confirm; idle stop and spending caps limit cost where the provider allows.

Details: [Cloud machines › Security](https://codemany.com/docs/machines/cloud#security).

## Signed releases

- The Mac app is signed with Developer ID and notarized by Apple, and its updates are signed too. Before running its bundled daemon, the app checks the daemon's signature and refuses one that isn't Codemany's.
- On Linux, the apt repository and the checksums `install.sh` downloads are signed with Codemany's apt key: `92EA E8F4 E140 E71F E883 C291 DBC1 D871 7AE5 E521`.
- Licenses are signed by Codemany, short-lived (7 days) and bound to one machine.

## Report a problem

Send a direct message to [@arpwal on X](https://x.com/arpwal).

[Previous Licensing and seats](https://codemany.com/docs/account/billing)[Next CLI commands](https://codemany.com/docs/reference/cli)
