privacy
Privacy Policy
Last updated: 13 October 2026.
Codemany is made by Rainbow Labs Inc. ("we"). In short: your code, workflows, job logs and GitHub token stay on your Mac and with GitHub. We get only what licensing and billing need, your account settings (so all your machines share them; never tokens or keys) unless you turn that off, anonymous usage stats (counts and sizes, never names, code or tokens) unless you turn them off, and, only if you say yes, what it takes to show your GitHub account on codemany.com or to start your cloud machines while your Mac is off. There are no ads or tracking cookies, and we do not sell your data. How we protect your data explains the safeguards.
What stays on your Mac
- Your GitHub token is kept in Codemany's Keychain vault on this Mac (login Keychain item
com.codemany.vault), which trusts only Codemany.app and its daemon. It is never sent to us except as described under "Starting a trial or subscribing". - Your license is kept in the Keychain and in
~/.codemany/license.token. - This machine's own settings (how many jobs it runs at once, its disk reserve, Docker, isolation, keep awake, appearance, the login item and ports), runner files, job working directories and logs live in
~/.codemanyand are never sent to us. Run history lives in~/Library/Application Support/Codemany. Settings marked "Syncs with your account" are also stored with us: see Account settings. - Cloud provider access, if you add a cloud machine: Google Cloud connects through federation, so there is no Google key to keep; the Google sign-in used during setup stays in the Keychain vault on a Mac (or the system keyring on Linux) until setup is done, and is then revoked. A Hetzner or DigitalOcean API token stays in the same vault, and is sent to us only if you choose Store Encrypted (details).
- Your jobs run on your Mac and report to GitHub. Their code, output and secrets never pass through us.
What leaves your Mac
To GitHub, directly
The app and daemon call GitHub with your token to sign you in, list your repositories, register a fresh runner for each job, watch workflow runs and download the GitHub Actions runner. GitHub's privacy statement covers this.
To us: starting a trial or subscribing
The app sends your GitHub token to api.codemany.com once, so we can confirm your GitHub account. We use it for two GitHub API calls (your profile and your email addresses) and then drop it: it is not stored, logged or sent to Stripe. From GitHub we keep your user id, login and email address (your primary verified email, or else your public email, or else your GitHub no-reply address).
The app also sends a device id and your Mac's name (for example "Ann's MacBook"). The device id is a SHA-256 hash of the Mac's hardware UUID, never the UUID itself. It ties your license to one Mac.
To us: license checks
About once a day, the app (or the daemon, if the app is closed) sends its license and device id to api.codemany.com to renew the license. Listing or moving your Mac's seat and opening the billing portal send the same.
To us: bug reports, only when you send one
A report contains the title and description you type, the app and macOS versions and, only if you turn it on, a diagnostics summary. The summary is reduced to counts, states, versions and error text, with owners, repos, branches, run titles, runner names, hostnames, URLs and IPs removed. The form shows exactly what will be sent. We file the report as an issue in our private GitHub repository, without your email or subscription ids.
To Stripe
When you subscribe, you pay on Stripe's checkout page. Stripe collects your payment and billing details; we never see your card number.
To PostHog: anonymous usage stats
Unless you turn them off, the daemon sends anonymous usage events to PostHog. What is sent, and how to turn it off.
To us: account settings
Unless you turn account sync off, your account settings go to api.codemany.com so every machine on your account shares them. What is stored, and how to turn it off.
Update checks
The app checks codemany.com/updates/appcast.xml for updates. Like any web request this reveals your IP address and app version. No system profile is sent.
Your local network
The daemon serves a status dashboard on your local network (port 8825, advertised as codemany.local). It shows repo and workflow names, branches, run titles and runner state to anyone on that network. It is never sent to us. Set "lanDashboard": false in ~/.codemany/config.json to keep it on this Mac only.
Account settings
Settings marked Syncs with your account are stored with your Codemany account, so a change on one machine shows up on your other machines within seconds. Settings marked This Mac only never leave the machine.
What is stored: for each GitHub account or organisation you run Codemany for, its repositories (the list, the public repositories you opted in, and the repositories allowed risky triggers), its runner labels, its cloud defaults (provider, region and monthly spending cap) and its cloud machine definitions (name, provider, region, size, labels, repositories and schedule); and for you, your update channel and notification preferences. Each change is recorded in a change log with who made it, when, through which app, and the names of the settings that changed, never their values. Tokens, keys and passwords are never part of account settings.
Who sees it: people GitHub says belong to that account or organisation. Only its owner (for an organisation, its admins and whoever pays for its subscription) can change it; other members see it read-only. Your own update channel and notification preferences are seen only by you.
On by default. Turn it off on a machine in Settings › Privacy & Sharing › Sync account settings (or codemany account-sync off): that machine then keeps its own copy and sends no changes. What is already stored stays until you ask us to delete it.
Cloud machines and your Google account
You can let Codemany create runner machines in your own cloud account: Settings › Machines › Cloud (dashboard: Settings › Machines). Nothing here happens unless you connect an account.
Google Cloud: federation, no key
Google Cloud connects through Workload Identity Federation: you run a short setup in your project (in Cloud Shell, or with Terraform) that lets Codemany's server identity act as a service account you create (codemany-runners), with permission to manage Compute Engine machines only. Codemany never holds a Google key or password for your project. We store only the identifiers needed to use it: your project id and number, the workload identity pool and provider ids, and the service account's email. Our server uses this to create, start, stop and delete the runner machines you ask for, so they can start when your Mac is off. Remove the pool, the provider or the service account in your project to cut access at once.
What Codemany accesses
During setup, when you choose Sign in with Google (to pick a project, and on Macs not yet moved to federation), Google asks you to allow three permissions, and Codemany uses each only for this:
- View and manage your Google Compute Engine resources (
https://www.googleapis.com/auth/compute): to list the zones and machine types in the project you choose, and to create, start, stop and delete the runner machines you ask for. Codemany only starts, stops or deletes machines it created, which carry its labelcodemany=managed; it never reads or changes your other machines, disks or data. - View your Google Cloud Platform billing accounts (
https://www.googleapis.com/auth/cloud-billing.readonly): to read Google's public price list, so the app can show what each machine size costs. Codemany does not read your billing accounts, invoices or spending. - View your Cloud Platform projects (
https://www.googleapis.com/auth/cloudplatformprojects.readonly): to list your projects' names and ids once, right after you sign in, so you can pick the one for your machines instead of typing its id. It is optional: leave it unticked and you type the project id instead. Codemany reads nothing else about your projects and never changes them.
Codemany does not ask for your name, email address, contacts, files or any other Google data.
After setup, through federation. Our server reaches your project only as the codemany-runners service account you created, never as you, and only within the roles you gave it. It asks Google for short-lived tokens with these scopes: https://www.googleapis.com/auth/compute to create, start, stop and delete your runner machines; https://www.googleapis.com/auth/cloud-platform.read-only, only for the setup check, to confirm the service account has the permissions it needs (Google's projects.testIamPermissions requires it); and https://www.googleapis.com/auth/cloud-platform, only in the token exchange step that Google's Security Token Service requires before it issues the service account token. These tokens last at most 1 hour, are kept only in our server's memory, and are never stored or logged.
Where it is kept and who sees it
The sign-in (an access token and a refresh token from Google) stays on your computer, in the Keychain on a Mac or the system keyring on Linux, and its calls go straight from your computer to Google. It is used during setup only: once federation is verified, Codemany deletes it and asks Google to revoke it. Nothing Codemany receives from Google through the sign-in is sent to us, stored on our servers, shared with anyone, used for advertising, or used to train AI models. The federation identifiers above, and your cloud machines' definitions and state (running or stopped, last start and stop), are stored with your account settings.
Removing access
In Settings › Machines › Cloud › Connections, remove Google Cloud: we delete the federation identifiers, and our server can no longer reach your project. Before federation, choose Disconnect next to Google Cloud (remove its cloud machines first), then one of two choices. Disconnect here only deletes the sign-in from this computer; other computers you signed in to Codemany with the same Google account stay signed in. Disconnect and revoke at Google also deletes the sign-in from this computer and asks Google to revoke Codemany's access; this also signs out any other computer using this Google account for Codemany. You can also remove Codemany at any time at myaccount.google.com/permissions, which signs out every computer the same way. Uninstalling Codemany does not revoke Google access or delete cloud machines: remove your cloud machines and choose Disconnect first.
Limited Use of Google user data
Codemany's use and transfer to any other app of information received from Google APIs will adhere to the Google API Services User Data Policy, including the Limited Use requirements. In particular:
- We use Google user data only to provide the cloud machine features described above, which you can see and control in the app.
- We do not transfer it to anyone, except as needed to provide those features, to comply with the law, for security (for example, investigating abuse), or as part of a merger or acquisition with notice to you.
- We do not use it, or sell it, for advertising, retargeting or interest-based ads, and we do not use it to determine credit-worthiness or for lending.
- We do not use Google user data to develop, improve or train generalized or non-personalized AI or machine learning models. Codemany has no AI or machine learning features that process it.
- No person at Codemany reads it, unless you ask us to (for example, to help with a problem you report), it is needed for security or to comply with the law, or it has been aggregated and anonymised for internal operations.
Other providers
With Hetzner or DigitalOcean, the API token you provide stays on your computer, in the same vault, and is used only to manage the machines Codemany created, unless you choose to store it with us. Codemany asks first ("Store this key with Codemany?"); only if you choose Store Encrypted is the token sent to api.codemany.com. There it is encrypted with a key for your account alone, which is itself protected by Google Cloud Key Management Service (envelope encryption), and used only by our server to start, stop and remove your machines, so they can start when your Mac is off. It is never logged, shown back to you or anyone, or sent anywhere but that provider. Choose Keep on This Mac Only and nothing is sent; machines on that account then start only while that Mac is on. Remove a stored token at any time in Settings › Machines › Cloud › Connections: we delete it, and once no stored token is left for your account, the key that encrypted them. Revoke the token in that provider's console as well if you no longer use it.
Anonymous usage stats
Why: to see how Codemany is used so we can improve it, and to publish combined totals for all Macs on codemany.com (jobs run, minutes, dollars saved, the kinds of Mac, and a top-10 list under anonymous names like "Mac a1b2").
Where: PostHog, US cloud. The daemon sends events in batches, about once a minute.
On by default. The first time the app opens with this feature, and during setup, it tells you so with Turn Off and OK. To turn it off at any time:
- Settings › Privacy & Sharing › Share anonymous usage stats (the app saves the setting and restarts the daemon), or
"analytics": {"enabled": false}in~/.codemany/config.json, then restart the daemon, or- the environment variable
CODEMANY_ANALYTICS=0for the daemon (it wins over the config).
Turning it off stops sending at once: nothing is kept to send later. Events already sent are not recalled.
Identity: a random install ID (a UUID) created on first run and kept in ~/.codemany/analytics-id. It is not derived from your Mac's hardware or your account. Turning stats off keeps the file, so counts continue if you turn them on again; delete it to start a new ID.
Every event also carries the app version, the macOS version (major.minor) and the processor architecture.
| Event | When | What it carries |
|---|---|---|
install_active | When the daemon starts, then every 24 hours | CPU cores, performance cores, memory in GB, disk size in GB (rounded to 10), chip (for example "Apple M2 Pro"), how many runners, isolation mode (host, user or vm) |
repos_connected | At start and when the watched repos change | How many repos, organisations and workflows (counts only) |
job_scheduled | The first time a job queued for this Mac is seen | A run key, and whether the job is Linux or macOS work |
job_finished | A job that ran on this Mac completes | A run key, Linux or macOS, result (success, failure or cancelled), duration in seconds, billed minutes, the estimated dollars saved (standard and larger GitHub runners), and whether the repo is public |
runner_failed | A runner fails to start, crashes, goes offline or its VM fails | Which of those it was, and the isolation mode |
runner_recovered | A runner that failed is back online | Seconds since the failure |
The run key is the first 16 hex characters of a SHA-256 hash of your install ID, the repo and the run's id. It lets the same run count once, but cannot be turned back into a repo.
Never sent: repository, organisation, workflow, job, branch, runner or host names; URLs; tokens; logs; file paths; GitHub user names; email addresses; license keys. PostHog is told not to look up a location from your IP address; like any web request, the connection itself shows PostHog your IP address.
Showing you on codemany.com (only if you say yes)
Codemany asks once, after setup: “Can we show you on codemany.com?” Nothing below happens unless you answer Yes, show us. It is a separate choice from usage stats.
What is shown: the GitHub avatar and login of your account and of the organisations you run runners for, in a strip beside the total savings on codemany.com, each linking to its GitHub page. No repository names, numbers or jobs are shown next to them.
How it works: once a day your Mac sends api.codemany.com your license, your runner targets and your GitHub token. We use the token for that request only, to ask GitHub which account it belongs to and which of those organisations it administers; we never store or log it. We keep each shown account's GitHub id, login and type, when it was first shown, and your Mac's job minutes per organisation (to order the strip; never shown), plus a copy of each avatar, in Google Cloud Storage. Someone else's personal account is never shown. The strip appears only once 6 accounts are shown.
Turn it off in Settings › Privacy & Sharing › Show me on codemany.com (or codemany featured off): your accounts leave the site within minutes. If your subscription ends or your Mac stops checking in, they leave within 8 days.
Console (console.codemany.com)
The console shows your machines, their runners and recent runs in a browser at console.codemany.com, and lets you send them commands. A machine reports to it while it holds a Codemany license (a trial or a subscription) and the console switch is on. The switch is on by default.
Before a Mac reports, the Mac app shows a one-time notice that this Mac appears at console.codemany.com, with Turn Off and OK. The Mac sends nothing to the console until you answer it. A Linux server prints the same notice in codemany setup and in its log at every start, and reports without waiting.
What a machine sends, within 15 seconds of a change and otherwise about every 30 seconds: the machine's name, operating system, architecture and Codemany version; its mode (running, draining or paused); its configured number of runners and how many are in each state; its targets (the GitHub accounts, organisations and repositories it runs jobs for, with their GitHub ids); its cloud machines' names, provider, region, size, state and monthly price; and summaries of up to 50 recent runs: repository, workflow, run number and attempt, status and result, branch, trigger, created, started and finished times, and for the jobs this machine ran, job name, status, result, runner name and times. Each request carries the machine's license and is signed with the machine's key, to prove it holds a seat. The console records when the machine last reported, to show whether it is online.
What never leaves the machine: job logs and step output, your code, run titles and commit messages, file paths, environment variables, URLs, GitHub tokens, cloud provider keys and email addresses. Commands from the console carry no secrets either: the machine acts with its own credentials.
Where it is stored: Google Cloud Firestore, in our license database in Google Cloud's us-central1 region (Iowa, United States). With each command we keep the GitHub id of the person who sent it and the machine's reply.
How long: the newest 50 runs per machine and the newest 50 commands per machine; older ones are deleted as new ones arrive, and Firestore's automatic expiry deletes a run or command not updated for 30 days. A machine that stops reporting shows as offline with its last report; a machine silent for 30 days is deleted, with its runs and commands, by a sweep that runs every hour, and by Firestore's automatic expiry (usually within a day after) if the sweep does not run. A sign-in session stops working after 1 hour; signing out deletes it at once, and expired sessions are deleted by the hourly sweep and by Firestore's automatic expiry.
Who sees it: people GitHub says may activate Codemany on the account or organisation that owns the machine's seat, and only that owner's targets and runs. A machine's cloud machines are shown only to people who belong to every owner whose seat it holds. Who can send commands: for a personal account, its owner; for an organisation, its admins and whoever pays for its subscription. Changing one target's runners needs that right on the target's owner; commands that reach the whole machine (stop, start, drain, resume, cloud machines) need it on every owner whose seat the machine holds.
Signing in to the console uses GitHub OAuth with only the read:org scope, to read which organisations you belong to and your role in them. We keep your GitHub user id, login and avatar link, and those organisations with your role in each, for the session; the GitHub token is dropped right after sign-in. The console sets two cookies, both needed to sign you in, and no others: a sign-in cookie (__Host-codemany_oauth) that carries one GitHub sign-in attempt, lasts at most 10 minutes and is deleted once you are signed in; and the session cookie (__Host-codemany_console) that keeps you signed in for 1 hour and is deleted when you sign out.
Account settings in the console: the console also shows your account settings (repositories, runner labels and cloud defaults) and their change log to the people above, and lets those who can send commands change them. They are the same settings your machines sync; the console's separate copy of your repository list, kept before account settings existed, is no longer used and is deleted.
Turn it off in Settings › This machine in the dashboard, Settings › Privacy & Sharing › Show this Mac at console.codemany.com in the Mac app, or with codemany console off. It applies within a minute, with no restart. The machine then makes no request to the console at all and shows as offline; its records are deleted 30 days after its last report. To have them deleted sooner, send a direct message to @arpwal on X.
What we store
- Stripe holds your email, your GitHub user id and login, the GitHub account or organization a subscription is for, your subscription, invoices and payment details.
- Our license database (Google Cloud Firestore) holds, for each subscription and trial, the GitHub ids of its owner and of who paid, and for each machine on it: the device id, the machine's name, its public key, the GitHub id of who added it, and when it was added and last checked in. We need these to count machines and stop a license being copied.
- Account settings (the same database), unless you turn sync off: for each account or organisation, its repositories, runner labels, cloud defaults and cloud machine definitions and state; for you, your update channel and notification preferences, including the beta-channel choice we already kept. A change log records who changed which settings, when and through which app, by setting name only, never secret values; entries are deleted after 400 days. Details.
- Cloud connections, only if you set one up: for Google Cloud, the federation identifiers (project id and number, pool, provider and service account email), never a Google key; for Hetzner or DigitalOcean, only if you choose Store Encrypted, the API token encrypted with Google Cloud Key Management Service, with a short fingerprint so you can tell keys apart. Details.
- We keep these while you are a customer and afterwards as long as billing, tax and accounting rules require. Cloud connections and account settings are deleted when you remove them, or on request.
- API logs (api.codemany.com) record the method, path, status and duration of each request. Emails, tokens, licenses and device ids are scrubbed from every log line. Your IP address is used in memory for rate limiting; our API code does not log it. Google Cloud also keeps its standard request log (path, status, user agent).
- Website logs (codemany.com) record each request's URL, status, IP address, user agent and referrer, in Google Cloud Logging.
How we protect your data
The short version: the most sensitive data (your code, jobs, GitHub token and Google sign-in) never reaches us. For what does, here is how it is protected.
Encryption in transit
- codemany.com, api.codemany.com and console.codemany.com are served only over HTTPS (TLS). Plain HTTP requests are redirected to HTTPS, and every response carries HTTP Strict Transport Security (
max-age=31536000; includeSubDomains), so browsers refuse to connect without encryption. - Traffic between Cloudflare and our Google Cloud load balancer is also HTTPS, and our services accept requests only through that load balancer.
- The app's calls to Google, GitHub, Stripe, PostHog, DigitalOcean and Hetzner go straight to them over HTTPS. Google sign-in uses PKCE and a one-time redirect to your own computer (
127.0.0.1), so the sign-in code is bound to the app that started it.
Encryption at rest
- On your computer: your GitHub token, your Google sign-in (during setup) and provider API tokens are kept in Codemany's vault in the macOS Keychain, or the system keyring on Linux, both encrypted by the operating system.
- On our servers: everything we store (our Firestore database, Cloud Storage and logs) is in Google Cloud, which encrypts all data at rest (AES-256) by default.
- Provider API tokens you choose to store with us get a second layer: each is encrypted with AES-256-GCM under a key unique to your account, and that key is itself encrypted by a key in Google Cloud Key Management Service (envelope encryption), rotated every 90 days. Only our cloud machine service's own service account may use that key; our deploy and infrastructure automation cannot decrypt with it. If that key is not available, our server refuses to store a token rather than store it unencrypted.
- Google Cloud: we hold no Google key, password or refresh token for your project. Federation tokens last at most 1 hour and live only in our server's memory.
Access control
- Each of our services runs under its own Google Cloud service account with only the roles it needs. No downloadable service account keys exist: our automation signs in with short-lived Workload Identity Federation tokens limited to our own repository.
- Inside Codemany, administrative access to production is limited to Rainbow Labs' owner. We look at customer records only to run the service, to fix a problem you report, to keep the service secure, or when the law requires it.
- Inside the console and account settings, GitHub decides who may see or change an account's data (see Console and Account settings).
- Tokens, keys, licenses, device ids and email addresses are scrubbed from our API logs, and secret values never appear in errors or logs.
Retention and deletion
- Google sign-in: kept on your computer only until federation setup is verified, then deleted and revoked at Google. Disconnect deletes it at any time; Disconnect and revoke at Google, or removing Codemany at myaccount.google.com/permissions, also revokes it at Google.
- Google Cloud federation identifiers and provider tokens: deleted as soon as you remove the connection. When you remove your last stored provider token, we also delete your account's encryption key, so no copy of a token left anywhere (for example in a backup) can be opened again.
- Console records: deleted automatically as described under Console (newest 50 runs and commands, 30 days of silence, 1-hour sessions). Account settings change-log entries are deleted after 400 days.
- Anything else we hold is deleted on request: send a direct message to @arpwal on X. We keep billing records as long as tax and accounting rules require.
Security testing and monitoring
We keep a written threat model of every part of Codemany and review it quarterly. Before every release, and weekly, our code is scanned with CodeQL, gosec and govulncheck, and Dependabot proposes dependency updates. Our servers sit behind Cloudflare and Google Cloud Armor, which admit only Cloudflare's traffic and rate-limit the API. Google Cloud keeps audit logs of administrative actions.
If something goes wrong
We follow a written incident procedure: contain first (rotate any exposed secret or take the API offline), then investigate using audit logs. If an incident affects your data, we will tell you without undue delay, with what happened and what we are doing about it, and notify authorities where the law requires. To report a security problem, send a direct message to @arpwal on X (also listed in security.txt).
This website
codemany.com sets no cookies and has no analytics or third-party scripts. Its font (JetBrains Mono) loads from Google Fonts, so Google receives your IP address and browser details when you visit.
Who processes data for us
| Service | What for |
|---|---|
| Stripe | Checkout, subscriptions, invoices, the billing portal and our customer records. |
| Google Cloud | Runs codemany.com, api.codemany.com and console.codemany.com, stores their logs and our license database (with the console's records and your account settings), starts and stops your cloud machines, and hosts the app downloads. Cloud Key Management Service protects the provider keys you choose to store with us. Google Fonts serves the site's font. |
| Cloudflare | DNS, CDN and security for codemany.com, api.codemany.com and console.codemany.com. All traffic passes through it. |
| PostHog (US cloud) | Receives the anonymous usage stats, unless you turn them off. |
| GitHub | Sign-in, and the issue tracker that receives bug reports. Your jobs run under your own GitHub account. |
We do not sell, rent or share your data for advertising, and we share it with no one else unless the law requires it.
Your choices
- Delete what is on your Mac: uninstall Codemany.
- Stop syncing account settings: turn off Settings › Privacy & Sharing › Sync account settings on each machine (details).
- Stop usage stats: turn off Settings › Privacy & Sharing › Share anonymous usage stats (other ways).
- Stop being shown on codemany.com: turn off Settings › Privacy & Sharing › Show me on codemany.com (details).
- Remove a cloud connection or a stored key: Settings › Machines › Cloud › Connections (dashboard: Settings › Machines); we delete the federation identifiers or the encrypted key at once (details).
- Revoke cloud access on this computer: choose Disconnect next to the provider in Settings › Machines › Cloud. For Google, Disconnect here only deletes the sign-in from this computer; Disconnect and revoke at Google, or removing Codemany at myaccount.google.com/permissions, also signs out any other computer using this Google account for Codemany (details).
- Revoke GitHub access: remove "Codemany" under GitHub › Settings › Applications, or delete the token you gave it.
- Get a copy, a correction or deletion of what we hold in Stripe: send a direct message to @arpwal on X. We keep what tax and accounting rules require.
Codemany is not meant for children under 13.
Changes and contact
We will post changes here and update the date at the top. Questions: send a direct message to @arpwal on X. See also the Terms of Service.