Rotated secrets, Tailscale integration & Kubernetes Operator v2.0

We've added support for automated secret rotation, along with several other platform updates and improvements. We also rewrote the Kubernetes Secrets Operator in Go (2.0), overhauled the secret deployment pipeline so references stay in sync across apps, added self-hosting on Tailscale, and shipped rotation support across the CLI, SDK, and REST API.
Rotating Secrets
Rotating Secrets are credentials for third-party services that Phase mints, exposes, and revokes automatically on a schedule. The active credential surfaces alongside your regular secrets in an environment — SDKs, the CLI, REST clients, and sync integrations all pick up the rotated value with no application-side changes. Point your app at the env var, and Phase keeps the value fresh underneath it.

The lifecycle:
- Mint — At the configured cadence, Phase calls the provider to create a fresh credential. The minted value is encrypted with your environment key and stored server-side.
- Expose — The active credential is merged into the standard secret read path. No application changes, no extra fetch — it reads exactly like any other secret.
- Expire — The previous credential enters an expiring window. It stays valid at the provider until a configurable revocation delay elapses, giving every consumer time to pick up the new value — so rotation is zero-downtime.
- Revoke — A scheduled job calls the provider's revoke endpoint and the old credential is retired.


Health monitoring and alerts: Phase watches every rotation. If a mint or revoke call fails, the rotation is marked degraded and retried with backoff; if failures persist, it's paused automatically so a broken upstream credential can't keep erroring silently. The organization owner, admins, and whoever set up the rotation are emailed the moment a rotation degrades or fails.
Launching with two initial providers:
- OpenAI — Rotates OpenAI project service-account keys, scoped to a single project rather than your whole org. A project picker lets you select by name instead of pasting a
proj_id. - LiteLLM — Rotates LiteLLM virtual API keys, with support for the full policy surface (models, budgets, rate limits, metadata, permissions). An Import config tab can mirror an existing key's policy so a rotating key behaves identically to the one it replaces.
We have many more providers on the roadmap. If there's a service you'd like Phase to rotate credentials for, request it on Slack or GitHub.
Set up a secret rotation:
- From the New Secret menu, choose Rotating Secret.
- Pick a provider and configure its settings, including the admin credentials Phase uses to mint and revoke keys on your behalf.
- Set a rotation cadence and revocation delay, and map the minted keys to outputs in your app's environment.
Phase mints the first credential on save and manages the schedule from there. Check out the Rotating Secrets docs along with the OpenAI and LiteLLM provider guides.
Available in Console v2.70.0.
Self-Hosting w/ Tailscale
Tailscale puts all your machines on a single private network — a tailnet — with no firewall rules or VPN gateways to manage. With this release, a self-hosted Phase Console can run entirely inside your tailnet: private to your team by default, and optionally published to the public internet with Tailscale Funnel. Living on the tailnet works both ways — Phase can also reach and manage secrets for your other private infrastructure, like a self-hosted GitLab or an internal LiteLLM gateway, without exposing any of it publicly.
Tailscale automatically provisions a valid, publicly-trusted TLS certificate — normally the hardest part of an internal deployment, where a self-signed cert otherwise means standing up and distributing your own certificate authority to every client.
Under the hood, a new Docker Compose template adds a Tailscale sidecar to the standard Compose stack. Phase joins your tailnet and is served at https://phase.<your-tailnet>.ts.net through Tailscale Serve — no reverse proxy, no DNS records, no certificate management, and nothing extra to install on the Docker host. Phase services also get transparent egress to other tailnet machines over MagicDNS, so syncs and integrations can reach private services with no public ingress.
Check out the Docker Compose + Tailscale docs for the full setup.
Available in Console v2.70.0.
SDK, CLI & API updates
Because rotated values flow through the same read path as any other secret, every Phase client serves them with no special handling — and this month rotation became first-class across all of them:
- REST API — The secrets API returns rotating secrets inline in the standard secrets response. Every secret now carries a
lifecyclefield —"rotating"for a Phase-managed rotating credential,"static"for a regular secret — so API consumers can tell them apart without any extra call. - CLI —
phase secrets listmarks rotating secrets with a 🔄 indicator, right alongside the existing 🔒 sealed and 💬 commented markers, so it's clear at a glance which values are managed on a schedule. - Go SDK — Secrets carry the same
lifecyclefield, exposing rotation metadata to programmatic consumers. v2.4.0 also addsRetry-Afterhandling on rate-limited requests and a stricter reference-resolution mode that errors on an unresolved${...}reference instead of passing the raw placeholder through.
Available in CLI v2.3.0, Go SDK v2.4.0, and the REST API in Console v2.70.0 — see the secrets API reference for the response shape.
Kubernetes Secrets Operator 2.0
The Phase Kubernetes Secrets Operator has been completely rewritten from Python/Kopf to Go, built on controller-runtime and the new Go SDK. The v1alpha1 PhaseSecret API is unchanged, so your existing manifests keep working — but almost everything underneath is faster, leaner, and far more robust.
Leaner and faster. The container image shrank from roughly 39 MB to 11 MB compressed — about 70% smaller, nearly 3.5× — now a single static Go binary on a distroless, non-root base instead of a full Python runtime. The old operator also held 150–200 MB of memory per instance and had a 5–8 second startup that could race fresh installs; the Go build starts near-instantly on a fraction of the footprint.
More reliable at scale. v1 was built on Kopf, which came with a few sharp edges we kept running into:
- Its field manager conflicted with Helm's server-side apply, which could leave the operator unable to write status and quietly stop syncing secrets — a real problem for GitOps and CI/CD.
- Its daemon model capped concurrent reconciliation at roughly 8 resources on a 4-CPU node, silently starving every
PhaseSecretbeyond that. - A credential-refresh bug restarted the pod about once an hour as the projected service-account token rotated.
2.0 replaces all of that with a standard controller-runtime reconcile loop, configurable reconcile concurrency, HTTP retry/backoff, and per-reference failure isolation — one broken reference no longer blocks the others, and managed Secrets are updated in place, so a failed update leaves the previous working Secret untouched instead of tearing it down.
New in the CRD:
onSecretReferenceErrorpolicy — aspec.onSecretReferenceErrorfield (FailorWarn) chooses what happens when a reference can't be resolved.Fail(the default) aborts the sync and raises a Kubernetes event rather than shipping a half-rendered config;Warnsyncs the literal reference and flags it. Either way it surfaces as a visible event, never a silent bypass.- More targeting and templating controls —
spec.phaseAppIdto target an app by ID (no more ambiguity between same-named apps),spec.redeployLabelSelectorto narrow which Deployments get auto-redeployed, and custom labels/annotations on managed Secrets for tools like Argo CD and Prometheus.
Check out the Kubernetes integration docs for the full walkthrough.
Available in Kubernetes Secrets Operator v2.0.0.
Overhauled Secret Deployment Pipeline
This release reworks how referenced secrets reach your integrations. Phase now maps every ${...} reference across every environment of every app in your organization that has syncing enabled, building a live graph of what depends on what. When a secret changes, Phase walks that graph and automatically queues sync jobs for each environment that references it — directly or through a chain of references, across environments and across apps.
So if one app references a rotated credential owned by another app, the moment that credential rotates Phase re-syncs the dependent app's environments on its own — no manual redeploy — keeping every downstream destination in a consistent state.
References now also resolve through nested chains — a reference to a reference to a reference — both when pushing to a destination (Vault, AWS Secrets Manager, GitHub Actions, and the rest) and when reading through the REST API. Previously, server-side resolution stopped at one level, so chained references reached destinations only partially resolved. Resolution is cycle-aware and bounded to 25 levels deep, so a circular or runaway reference is caught instead of looping forever.
Reliable references inside syncs has been a long-standing request — in GitHub issues #700, a cross-app reference failing in a GitHub sync and #877, Render syncs stopping after one level.
A few related improvements landed alongside the pipeline work:
- New "Queued" sync status — syncs now show a distinct Queued state while waiting for a worker, so it's clear whether a sync is lined up or actively running.
- Combined references parse correctly — a value mixing a local and a qualified reference (e.g.
${HOST}-${Production.PORT}) no longer breaks the sync or garbles reference highlighting in the editor. - Faster bulk saves — importing or bulk-editing secrets now triggers dependent syncs once per environment instead of once per secret.
Check out the Secret Referencing docs for syntax and examples.
Available in Console v2.71.0.
Reworked User Invite & Acceptance Flow
If you've been invited to one or more organizations, those invites now show up directly in your organization lobby. New users who sign up with a pending invite are routed straight to the lobby to accept it, instead of being pushed through the create-organization onboarding flow first.

Available in Console v2.71.0.
Other improvements and fixes
- JetBrains IDEs — A new integration for injecting Phase secrets into JetBrains IDE run configurations — IntelliJ, PyCharm, GoLand, WebStorm, and more — via the EnvFile plugin. Check out the JetBrains integration docs.
- Hardened Lockbox sharing (security) — View limits on secrets shared via Lockbox are now enforced server-side, so a share's view count can't be bypassed from the client.
- Plus numerous UI refinements and fixes across the Console, self-hosted deployments, and the CLI. Update to the latest release to pick them all up.
All features are live on Phase Cloud and available in the latest releases for self-hosted users.
As always, we'd love your feedback — come say hi on Slack, X, or GitHub.