Secrets reach the servers that run them, not the pipeline in between
The crunu agent runs on your Linux servers, keeps decrypted environments in memory and starts your programs with them. CI gets a token for the environment it builds, bound to one repository and branch. Production values don't have to pass through CI at all.
Questions teams like yours ask
The questions that come up when a team like yours moves its secrets into one place. The guide below answers each of them.
- How does a server get its environment without a file on disk?
- How do we keep production values out of CI?
- How do we tie a CI token to one repository and branch?
- What happens to running services if the vault is unreachable?
- How quickly does revoking a machine take effect?
- Can we serve production only to our own networks?
- Who can enroll machines without seeing the values?
- How can a deploy script tell why crunu failed?
The parts of Crunu that cover it
Every part works on the same rule: the server keeps ciphertext, public keys and signed documents, and never holds a key that opens your values.
Machines
Enroll a server with a one-time code, and the crunu agent keeps its environments in memory and starts your programs with them.
Learn more
CI/CD
Give each pipeline a service token limited to its environments, and bind it to your CI provider with OIDC so a leaked token cannot sign in by itself.
Learn more
Network rules
Serve an environment's contents only to allowed IPv4 and IPv6 networks, with signed rules that cannot be loosened quietly.
Learn more
Audit log
Sign-ins, grants, versions, rotations and refusals go into a hash-chained log that you can verify in one click and export.
Learn more
Access control
Give each person, machine and pipeline only the environments they need, with roles backed by encryption keys rather than by server checks alone.
Learn more
How it works for platform teams
On this page
Where secrets leak on the way to a process
Getting a value into a running process is where it usually escapes: a .env baked into an image, a production key stored in CI variables, a deploy user who can read everything.
The job is for each machine and pipeline to get exactly its environments, for nothing to land on disk unless you choose, and for revoking to be one action.
Four steps from a new server to a running service
- Create the machine. Choose its environments and how to deliver them: an Environment key, which always gives the latest version of every file, or Selected files, a sealed copy of only the files the machine needs. Selected files can be revoked without changing the environment key.
- Install and enroll. The Enroll machine dialog shows one command that installs the agent, checks its SHA-256 and enrolls the machine with a single-use code. The code is valid for 15 minutes by default and 24 hours at most, and it's read from stdin or a variable, never from an argument.
- Approve by fingerprint.
crunu enrollprints the machine's fingerprint. Approve the machine after checking it matches the one in the app. - Start your service through the agent. The service user must be in the
crunugroup. With--restart on-change, the program restarts with new values after they change.
# /etc/systemd/system/payments-api.service
[Service]
User=payments
ExecStart=/usr/local/bin/crunu run --env payments-api/production --restart on-change -- /opt/payments-api/bin/serverWhat the agent and tokens do for you
| Need | What Crunu does |
|---|---|
| No secrets on disk | The agent service keeps decrypted environments in memory only and hands them to crunu run through a local socket open to the crunu group. See systemd. |
| Files where a tool expects them | crunu pull writes files with 0600 permissions in two phases, keeps the previous version as .prev, doesn't follow symlinks and refuses shell startup files, .ssh/ and systemd directories. --env-out writes one env file for EnvironmentFile=. |
| An agent you can audit | A static Go binary using only the standard library. On Linux it's shielded from other processes of the same user, core dumps are off, and the service runs in a systemd sandbox. Updates check an Ed25519 signature. |
| Servers that ride out an outage | The agent checks the server every minute and renews its lease every 5 minutes. If the server is unreachable, it serves the last verified state until the lease ends, 24 hours by default. |
| CI without production | Service tokens get only the environments you grant, with a lease, a usage limit and networks. A CI binding (OIDC) ties a token to a repository, branch and deployment environment in GitHub Actions, GitLab CI, Bitbucket Pipelines or any OIDC issuer. A replayed CI token is rejected. |
| Production only from known networks | Signed network lists and environment network policies for IPv4 and IPv6. Tightening applies at once; relaxing waits 15 minutes with an alert and an undo, or applies at once with a second signature. Machine passes cover address changes, 24 hours by default. |
| Revoking in one action | Revoking a machine erases its environments from memory within minutes while the machine is online, and rotates the environment keys it held. A reused enrollment code flags possible interception. |
| Signals | Alerts for sign-ins from new devices, reused enrollment codes, machines on new addresses, replayed CI tokens, expired leases and network events, sent to a webhook signed with HMAC or by email. Slack, Microsoft Teams and PagerDuty connect through their incoming webhooks. |
Failures you can tell apart
When crunu can't hand over variables, its exit code says why, so a deploy script can react. Otherwise crunu run returns your program's own exit code.
| Code | Meaning |
|---|---|
3 | The machine isn't enrolled, or nobody is signed in |
4 | Access was revoked or the lease expired |
5 | No connection and no valid verified state |
6 | A signature or certificate check failed |
7 | This address isn't allowed by the environment's network policy |
Where the agent stops
- The service runs on Linux with systemd. On macOS
crunuworks as a command-line tool, without a background service. There's no Windows build. - No Kubernetes operator, Helm chart or CSI driver, no Terraform provider and no SDKs. Programs get values through
crunu run. - No built-in sync into Vercel, Cloudflare, AWS Secrets Manager or GitHub Secrets. You can push values from CI with
crunu runand the platform's own CLI. - No dynamic secrets. Crunu doesn't mint short-lived database passwords; that would need a key on the server.
- A machine is a legitimate recipient. Root on it can read what it was given, and a running process keeps its variables until it restarts.
- Network restrictions are enforced by the server, not by encryption. A compromised server wouldn't honor them, and every machine behind one NAT has the same address.
Each limit, with what to do about it, is on the limitations page.
If you run the server too
Teams that want the server in-house can run it on Docker, Cloudflare Workers, Vercel or Google Cloud Run, and move between them with one archive that contains no plaintext values. A doctor command checks a deployment, and a status endpoint exposes metrics in Prometheus format. The server isn't published as a public download. Write to support@crunu.com. The self-hosting page compares the platforms.
Related docs and integrations
- Install the agent on a server
- Machines and leases
- crunu run
- crunu pull
- Enroll a machine and run the service
- Environment variables and exit codes
- Bind a service token to CI with OIDC
- Restrict production to an office network
- Self-hosting: overview and platforms
- systemd
- Docker
- GitHub Actions
- GitLab CI
- Bitbucket Pipelines
Questions and answers
Not covered here? Write to support@crunu.com and a person will answer.
What happens to running services if Crunu is unreachable?
They keep working. The agent serves the last verified state until its lease ends, 24 hours by default. If there's no valid state, crunu run exits with code 5.
How fast does revoking a machine take effect?
Within minutes while the machine is online: the agent checks the server every minute and erases its environments once it's revoked. A machine that stays offline loses access when its lease ends.
Can CI deploy to production without seeing production secrets?
Yes, and it's the setup Crunu recommends. The production server runs the agent and fetches its own environment; the pipeline delivers the code and restarts the service.
Does crunu work in containers?
The install script has a no-root mode meant for CI and containers, tested in node:24, Ubuntu 24.04 and Alpine 3.22 images. With a service token, crunu signs in and decrypts inside its own process, with no state files.
Can someone enroll machines without seeing any values?
Yes. The Operator role on an environment has no key: it adds machines and requests access for them, and an owner or admin approves.
Do you support Kubernetes?
No. There's no operator, Helm chart or CSI driver.