Security and trust model
Built for code you trust.
Honest about the rest.
OwnCI runs code from your workflows on your machine. Here is exactly what it enforces, and what a container does not protect you from. Read this before pointing it at anything you don’t control.
Supported
Private repositories, trusted workflows.
OwnCI is meant for private repositories whose workflows you trust: your own, your team’s. ownci setup refuses public repositories unless you pass --allow-public-repo, because pull requests from forks can run arbitrary code on a self-hosted runner.
If you accept that risk anyway, set the repository’s Approval for running fork pull request workflows from contributors to Require approval for all external contributors (Settings → Actions → General), and read each pull request, including its changes to .github/workflows/, before you approve its run: approving runs that code on your machine.
In a team, the per-developer label routes jobs but does not restrict who can reach a runner. To let only maintainers decide which jobs reach which machine, seeLet only maintainers decide where jobs run.
What OwnCI enforces
Guard rails that are checked, not assumed.
- Container jobs only. In host mode the runner is configured to reject any job without a container: line. If OwnCI can’t establish this, it refuses to start the runner.
- The runner stays in its container. In container-runner mode the runner is only ever started inside its container, which is replaced after every job. The cleanup hook is mounted read-only, so a job can’t disable the wipe by editing it.
- A clean workspace for every job. After each job, _work (workspace, actions, tools) is wiped from a throwaway, network-less container using a digest-pinned image. If the cleanup fails, the job fails visibly.
- Opt-in label. The runner carries the ownci label (plus any you add with --labels) and none of GitHub’s default or hosted-runner labels, so a stray runs-on: self-hosted or runs-on: ubuntu-latest never lands on your laptop.
- Visibility re-checked. Unless you accepted a public repository at setup, start checks again (when a GitHub token is available) and refuses to run if the repository has become public. status --remote flags it too.
- No privileged containers. None of the containers OwnCI uses are privileged.
- Tokens handled carefully. Your GitHub token is never stored. The registration token is short-lived and reaches the runner through its environment, not its command line. The runner’s credentials live in its directory under runners/, mode 0700 like the rest of the data directory; OwnCI’s own files are mode 0600. GITHUB_TOKEN and GH_TOKEN are removed from the runner’s environment, so jobs never inherit them. Tokens are redacted from the logs OwnCI writes and captures.
- Checked every time. All of this is re-asserted on every start and reported by status and doctor.
What a container does not protect against
A container is not a sandbox for hostile code.
- The Docker socket is mounted into job containers. The official runner does this, and jobs run as root. A job can therefore control your Docker daemon, which is effectively root on your machine: it can start privileged containers, mount host paths and read other containers’ data. The container is a barrier against accidents, not against a malicious workflow.
- Network. Job containers use Docker’s default network and can reach the internet and your LAN. OwnCI sets no network policy.
- Sibling containers. services:, uses: docker://… and Dockerfile actions run as siblings on your Docker daemon, outside the job container and outside OwnCI’s control.
- Shared Docker daemon. Jobs share the daemon, images and build cache with everything else on the machine (with Docker Desktop, with Windows too). Images persist between jobs; only _work is wiped.
- Root in the container. Containers run as root by default and can read and write the runner’s work directories while a job runs.
- The runner runs on your host as you. OwnCI only allows container jobs, but a vulnerability in the runner, Docker or an image is a vulnerability on your machine.
- No resource limits. No CPU, memory or disk limits are applied to jobs.
- Container-runner credentials. In container-runner mode a job without container: runs next to the runner’s files, including its registration credentials, and can read or change them while it runs.
OwnCI does not claim to safely run arbitrary untrusted pull request code.
Comfortable with the model?
Set up your first runner.
Start with ownci doctor; it checks isolation too.