Secrets
Secrets stores your API keys, passwords and other credentials in Frazer Secrets, run by Frazer in each region outside your clusters. People add values and see metadata; clusters, serverless services, devboxes and agents read values with their own identity, and every read is on the record. Rotation keeps two versions valid until every consumer has moved.
Product overview: Secrets.
How it works
Section titled “How it works”A secret has an ID (stripe-secret-key), the environment key your code reads (STRIPE_SECRET_KEY), a folder
(/payments), a kind, labels, aliases and a rotation schedule. Each new value is a version with its author, the time and
the reason given. Versions are enabled, disabled or destroyed; a disabled version can be enabled again.
Values live in a namespace of their own per project. Snapshots are taken every 5 minutes and copied to Frazer Storage and off-site. No other cloud’s secret manager sits behind a Frazer secret.
- Alias: a name such as
prodthat points at a version. Consumers follow the alias, so moving it rolls out a new value. - Where used: every cluster, service, devbox and agent that reads a secret, with the version it holds.
- Rotator: who makes the next version:
frazerfor credentials Frazer issues,notifyto remind the secret’s owners, orjobfor a serverless job that runs your own rotate handler.
| Kind | Written by | Rotation | Example |
|---|---|---|---|
| Opaque | People, CI or an import | On a schedule, with a reminder to the owners | STRIPE_SECRET_KEY |
| Managed | Frazer, for a Frazer resource | Frazer rotates it; two valid versions overlap | The app user of a managed Postgres, a Valkey ACL user, an LLM gateway key |
| Dynamic | Created on each read | A lease: 1 hour by default, 24 hours at most | A Postgres role for an analyst or an agent session |
| Derived | Frazer, from a template with references | Whenever a referenced secret changes | DATABASE_URL |
| Certificate | Frazer’s certificate authority | Before it expires | mTLS client certificates |
A derived secret is a template whose references Frazer fills in, so DATABASE_URL follows its password through every
rotation:
postgres://app:${secret:db/acme-ledger/app}@ledger.db.acme-production.internal/ledgerCreate a secret
Section titled “Create a secret”-
Create the secret with its folder, environment key and rotation period.
Terminal window frazer secrets create stripe-secret-key --folder /payments \--key STRIPE_SECRET_KEY --rotation 90d -
Add the first value. It is read from stdin, so it never lands in your shell history, and the reason is kept with the version.
Terminal window printf %s "$V" | frazer secrets versions add stripe-secret-key \--from-stdin --reason "rotated in Stripe" -
Point the
prodalias at the version. Consumers that follow the alias get it.Terminal window frazer secrets versions alias stripe-secret-key prod 7
-
Open Data › Secrets and choose New secret.
-
Give it an ID, an environment key, a folder and a rotation schedule.
-
Add the value with a reason. The console never shows it again.
Import on the same page opens the import wizard instead.
Then deliver it. In your environment repository, point an ExternalSecret at the alias path. The cluster’s secret sync
reads it with the cluster’s own identity, so no value enters Git.
# envs/production/payments/stripe.yaml: no value in GitapiVersion: external-secrets.io/v1kind: ExternalSecretmetadata: name: payments-stripe namespace: paymentsspec: secretStoreRef: kind: ClusterSecretStore name: frazer-secrets target: name: payments-stripe data: - secretKey: STRIPE_SECRET_KEY remoteRef: key: "@prod/payments/stripe-secret-key" # follows the prod aliasCheck who uses it: frazer secrets where-used stripe-secret-key lists every consumer and the version it holds.
Deliver secrets to workloads
Section titled “Deliver secrets to workloads”| Consumer | How it gets the value | Version |
|---|---|---|
| Kubernetes cluster | An ExternalSecret in the environment repository, through the ClusterSecretStore named frazer-secrets, with the cluster’s own identity; a config reload restarts pods on change |
Latest, an alias, or a pinned number |
| Workload without a Kubernetes Secret | A file mount through the Secrets Store CSI driver, opt-in | Latest or pinned |
| Serverless service | A binding from secret to variable | Pinned per revision; a new version starts a new revision |
| Devbox | References in the provisioning profile; short-lived credentials where the credential broker can mint them | Latest |
| Agent | Never a value in the sandbox: the egress gateway adds the credential for each allowed host | Latest |
A secret can also be shared from one project to chosen projects in the organization. The share grants read access to its versions, and reads are audited in both projects.
Rotate a secret
Section titled “Rotate a secret”-
Set a schedule: a period of an hour or more, an overlap of 24 hours by default, and a rotator. With
notify, the owners get an email and an Inbox item, and Frazer sends thefrazer.secret.rotate_due.v1event to your webhooks. -
Add the new version. Frazer adds it for credentials it issues; for the rest, an owner adds the value with a reason.
Terminal window printf %s "$V" | frazer secrets versions add stripe-secret-key \--from-stdin --reason "rotated in Stripe" -
Move the alias. Clusters refresh, serverless services start a new revision, and the broker hands out the new value.
Terminal window frazer secrets versions alias stripe-secret-key prod 8 -
Wait for Where used to show every consumer on the new version. A rotation that cannot finish keeps the old version valid and raises a finding.
-
Frazer disables the old version after the overlap and destroys it after 7 days. Every read stays on the record.
Managed secrets rotate without you: Postgres app users, Valkey ACL users with two passwords, registry tokens, LLM keys and Frazer service account keys.
Read a value
Section titled “Read a value”Values are write-only for people by default. No basic role reads them, owners and admins included, and workloads read only the secrets bound to them.
A person can read a value only with an explicit grant of the Secret Accessor permission, secrets.versions.access. Each
read asks for a second factor and is audited. A project can require an approval for reads in production, or forbid human
reads with a policy. With the grant, frazer secrets run starts a local command with the project’s secrets in its
environment:
frazer secrets run --project acme-staging -- npm startImport from another secret manager
Section titled “Import from another secret manager”The import wizard runs four steps: Source (a read-only credential and filters), Select (the secrets and their folders), Dry run (a plan of what is copied, skipped or in conflict, with the source’s egress estimate) and Import (progress per item with checksum verification).
- Sources: Google Secret Manager, AWS Secrets Manager, Azure Key Vault, HashiCorp Vault, 1Password, Doppler and Infisical.
- A
.envfile: upload it in the browser, where it is parsed on your machine, or runfrazer secrets import .env. - The source is only read. Values pass from the import worker straight into Frazer Secrets and are never logged.
- An import stays open for up to 30 days, so you can rerun a delta while you cut over; nothing keeps syncing after.
- The import credential is kept in Frazer Secrets and deleted when the import closes.
The same wizard imports container images; see Registry.
Access and audit
Section titled “Access and audit”| Role | Metadata | Add a version | Manage aliases, rotation, access |
|---|---|---|---|
| Owner, Admin | Yes | Yes | Yes |
| Developer, Infra admin | Yes | In non-production; production needs an admin or an approval | Developer: no |
| Viewer, Auditor | Yes | No | No |
| Workload identities | No | No | No; they read only the secrets bound to them |
- Permissions:
secrets.secrets.get,list,create,update,deleteandsetIamPolicy;secrets.versions.add,enable,disableanddestroy; andsecrets.versions.accessfor reading values. - Every read is an audit entry, counted per identity and hour, so “who read it” has an answer without a flood of rows.
- Every version keeps its author and reason. Access changes, alias moves, disables and destroys are on the record.
- An emergency read outside these grants is a two-person, recorded procedure.
- Encryption keys and certificates live in the same namespaces but appear in Security Center, not on the Secrets page.
Limits and quotas
Section titled “Limits and quotas”| Item | Default |
|---|---|
| Secrets per project | 10,000 |
| Value size | 64 KiB |
| Versions kept per secret | 100 |
| Reads per project | 100 a second, bursts to 500 |
| Rotation period | 1 hour or more |
| Rotation overlap | 24 hours |
| Destroy delay | 7 days after a version is disabled |
| Dynamic lease | 1 hour by default, 24 hours at most |
| Imports | 5 running per organization; each open for up to 30 days |
Pricing
Section titled “Pricing”Secrets add nothing to a budget: there is no fee per secret, per version or per read. Imports have no Frazer fee; the source bills its own egress, which the dry run shows.
| Secrets | On your servers | On the Frazer fleet |
|---|---|---|
| Price | No per-secret or per-access fee | No per-secret or per-access fee |
Every line, with the estimator: pricing.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Cause | Fix |
|---|---|---|
| The console shows no value | Values are write-only for people | Let workloads read it; for local work, ask an admin for the Secret Accessor permission |
| A developer cannot add a version in production | Production needs an admin or an approval | Ask an admin, or request an approval |
| Pods still use the old value | The ExternalSecret pins a version number, or has not refreshed yet |
Follow an alias path such as @prod/…; check the refresh with where-used |
| A rotation raised a finding | A consumer still holds the old version | Run frazer secrets where-used and update that consumer; the old version stays valid until then |
| A version is refused as too large | Values are limited to 64 KiB | Store large files in a bucket and keep only the credential here |
Reads fail with RATE_LIMITED |
The project passed 100 reads a second | Lengthen refresh intervals or read once per process |
| An agent cannot see a value | Agents never hold values | Allow the host on the agent; the egress gateway adds the credential |
Reference
Section titled “Reference”CLI
| Command | What it does |
|---|---|
frazer secrets create | Create a secret with its folder, environment key and rotation schedule. |
frazer secrets versions add | Add a version from stdin, with a reason. |
frazer secrets versions alias | Point an alias such as prod at a version. |
frazer secrets where-used | List every consumer of a secret and the version it holds. |
frazer secrets run | Run a local command with a project's secrets in its environment (needs the Secret Accessor permission). |
frazer secrets import | Import keys and values from a .env file. |
All of them: CLI reference.
Terraform and OpenTofu
| Resource | What it manages |
|---|---|
frazer_secret | A secret's metadata, folder, aliases and rotation; never its value. |
frazer_secret_version | A secret version with a write-only value; as an ephemeral resource it reads a value without storing it in state. |
All of them: Terraform and OpenTofu reference.
Events
| Event type | When it is sent |
|---|---|
frazer.secret.rotate_due.v1 | A secret with the notify rotator is due for rotation. |
All of them: Events reference.
Related
Section titled “Related”- Secrets product page
- Kubernetes for the secret sync in your clusters
- Serverless for bindings
- Databases for managed Postgres credentials
- Frazer Agents for credentials injected at the egress gateway
- Identity and access for roles and approvals