Security

Your code and builds stay yours

Each job runs alone on a machine that accepts no inbound connection, and every change Latchkey makes to your code arrives as a pull request you review.

Last updated

Read the full security architecture
  • 1job per machine, then the machine is destroyed
  • 0inbound connections a runner accepts
  • 0pull requests Latchkey merges
  • AES-256encryption on the secrets you store with Latchkey

01 · Isolation

A machine of its own for every job

Each job runs on its own virtual machine, with its own kernel and an encrypted disk. When the job ends, the machine is terminated and the disk deleted, and no machine ever runs a second job.

  1. 01StartA virtual machine no job has used
  2. 02RunYour job, alone on the machine
  3. 03TerminateShut down for good, never reused
  4. 04DeleteThe encrypted disk goes with it

Your code is checked out on a machine that runs only your job and is destroyed when it ends. What Latchkey keeps after a job is listed in the Privacy Policy and the documentation.

02 · Network

Runners reach out. Nothing reaches in.

Each runner reaches the internet through its own public IPv4 address, used only for connections the runner opens, and its firewall has no inbound rules. Your build can still fetch packages and call your services. A pull request from a fork on Latchkey CI reaches only GitHub and a fixed set of public package registries.

03 · Credentials

Credentials minted for each job

Every credential Latchkey mints for a job is minted for that job alone and reaches no other workspace's data. Each ends with the job or within about an hour, except the token Docker uses for Latchkey's container registry, which lasts 12 hours. No long-lived GitHub token is ever placed on a runner.

  • Clone tokenread-onlyone repositoryabout 1 hour
  • Job tokenthis job onlystored hashedends with the job
  • Cache accessthis workspace onlyscopedup to 12 hours

04 · Secrets

Your Latchkey secrets stay sealed

Secrets you store with Latchkey are encrypted with AES-256-GCM, and Latchkey unseals one only for a running job with a step that names it. Its value is masked wherever it appears whole in the job's log, and no dashboard, CLI or API-key request returns it.

Latchkey never calls GitHub's API for your Actions secrets.

05 · Changes

Every change to your code waits for your review

Latchkey commits only to new latchkey/ branches it creates, then opens a pull request. It never pushes to your branches and never merges, so merging is always your call.

06 · Self-heal

Self-heal works inside guardrails

When a step fails, self-heal can only take actions from a fixed, checked list, and the AI gets no shell. If self-heal errors or times out, a failed step still fails.

  • Allowedapt-get install -y libssl-devpackage on the fixed list
  • Allowedretry the failed stepsame step, same machine
  • Refusedsudo rm -rf /var/lib/dockeronly one sudo command is allowed
  • RefusedLD_PRELOAD=/tmp/hook.sounsafe environment variable
  • Refusedread ~/.ssh/id_rsasensitive path

07 · The basics

And the rest, covered

  • Encrypted at rest

    Runner disks, build cache and artifacts are encrypted at rest.

  • Encrypted in transit

    Every public endpoint uses HTTPS, and our API requires TLS 1.2 or later.

  • Isolated caches

    A workspace's build cache is reachable only with credentials scoped to that workspace.

  • Retention periods

    Dependency caches expire after 14 days, artifacts and job logs after 7, heal records after 90 and proposed fixes after 365.

  • Scoped API keys

    API keys are read-only unless you choose more, stored as SHA-256 hashes, and shown once.

  • Workspace roles

    Owner, Admin and Member roles decide who can manage billing, members and integrations.

  • Sandboxed forks

    On Latchkey CI, pull requests from forks reach only GitHub and a fixed set of public package registries.

  • Runner time limit

    A backstop terminates any runner still running 8 hours after it starts.

08 · GitHub App

The GitHub App, permission by permission

You choose which repositories the app can see, and it holds no permission to read your Actions secrets. Here is every permission it asks for, and why.

WhyPermissionAccess
Run your jobs on Latchkey runnersOrganization self-hosted runnersRead and write
Read runs and logs, start a run you ask for, cancel a runActionsRead and write
Read files, branches and pull requests, including the list of files a pull request changes, and propose changes as pull requestsContents, Workflows, Pull requestsRead and write
Report Latchkey CI results on your commits, and read the checks on them while you migrate from GitHub ActionsChecksRead and write
See each group your merge queue makes, so Latchkey CI can build the ones your workflow files run onMerge queuesRead
Read your organization's plan, Actions usage, GitHub-hosted runners and membersOrganization plan, Organization administration, MembersRead
Read basic repository detailsMetadataRead
Remove webhooks Latchkey created on a repositoryRepository hooksRead and write
Not used by any Latchkey feature todayAdministration, Organization hooksRead and write, unused
Not used by any Latchkey feature todayArtifact metadataRead, unused

No Actions secrets permission.

Report and review

Found a vulnerability?

Email security@latchkey.dev and please report it privately, not in a public issue.

security.txt

Doing a security review?

The documentation has the full detail.

Give your agents a CI they can drive

Commit a workflow file, connect your agent, and Latchkey runs, heals and reports every job. Write your workflow file

30-day free trial · No credit card · 10,000+ CI failures healed every week