# What is secret zero?

> Secret zero is the first credential a workload needs before it can fetch any other secret. Why it can't be stored in the vault, and how to make it short-lived.

URL: https://crunu.com/learn/secret-zero
Language: en
Updated: 2026-10-30

Secret zero is the first credential a machine, container or pipeline needs in order to authenticate to a secrets vault, the one secret that can't come from the vault itself because the workload must already hold it before it can ask the vault for anything.

## The bootstrap problem

Moving every secret into a vault leaves one behind: the credential that lets an application into the vault. If that credential sits in a config file or a CI variable, an attacker who finds it gets everything the application could fetch. The vault has moved the problem, not removed it.

HashiCorp calls this the "secure introduction" challenge: "Getting the first secret to the consumer", and asks, "How does a secret consumer, an application or machine, prove that it is the legitimate recipient for a secret so that it can acquire a token?" ([HashiCorp](https://developer.hashicorp.com/vault/tutorials/app-integration/secure-introduction)).

## Ways to shrink it

There is no way to have zero secrets; there are ways to make the first one worth very little.

- **Use an identity the platform already provides.** A CI job's OIDC token, a cloud instance's role, a Kubernetes service account token. The platform vouches for the workload, so nothing has to be stored. See [workload identity federation](https://crunu.com/learn/workload-identity-federation).
- **Make it single-use and short-lived.** A bootstrap code that works once, for minutes, is useless after the machine has used it, and an attempt to reuse it is a signal.
- **Keep it out of arguments and history.** Pass it through standard input or an environment variable, not as a command-line argument that shows up in process lists and shell history.
- **Verify the other side.** The person setting up the machine should confirm they are talking to the right workload, for example by comparing a fingerprint.

## Common mistakes

- **A long-lived vault token in CI settings.** It is the most valuable secret in the pipeline and the least protected.
- **The same bootstrap token for every machine.** One leak enrolls anything.
- **Baking it into an image.** Everyone who can pull the image has it.

## How Crunu handles it

**Machines.** An admin creates the machine in the web app and gets a one-time enrollment code, valid for 15 minutes by default and at most 24 hours, optionally limited to addresses. On the server, `crunu enroll` reads the code only from standard input or the `CRUNU_ENROLL_CODE` variable, never from an argument, and prints the machine's fingerprint; the admin approves the machine after comparing it. The code is used up on first use, and presenting it again marks the machine as a possible interception and raises an alert. After enrollment the machine has its own keys, and the code is worth nothing.

```sh
printf '%s\n' "$CODE" | sudo crunu enroll --server https://app.crunu.com -
```

*Figure: Example: the fingerprint printed on api-prod-1 and the one in the approval window match group by group, R7KQ M2XD WPLA V4TE. Priya has ticked “The fingerprint matches the crunu enroll output on this machine” and is about to approve it for payments-api production.*

**CI.** A pipeline's service token is a stored secret, and in a plain setup it is secret zero. A **CI binding (OIDC)** changes what it is worth: with a binding, the token signs in only together with a fresh JWT that the CI provider issues to a matching job, and each JWT works once. A token copied out of CI settings then fails anywhere else. The token also gets only its own environments, and can have a lease and a usage limit. See [CI/CD secrets with OIDC](https://crunu.com/guides/ci-cd-secrets-with-oidc).

## Sources

- [HashiCorp: Secure introduction of Vault clients](https://developer.hashicorp.com/vault/tutorials/app-integration/secure-introduction), checked October 30, 2026.
