Persisting and rotating Backstage token signing keys

Backstage signs its auth tokens with keys, and auto-generated keys change on restart, which invalidates sessions. This page covers static key stores, ES256 key pairs, rotation and protecting private keys.

On this page

Why Backstage token signing keys reset on restart and when to pin them

If your production Backstage signs users out, or plugin-to-plugin calls start failing, after every restart or redeploy, the likely cause is that the token signing keys were generated automatically and never persisted. An auto-generated key lives in memory or local state. When a new process starts, it creates a new key pair, and any token signed by the previous key no longer verifies. The fix is to configure key stores that stay the same across restarts, so every process loads the same keys. Two places in Backstage use these keys: the user key store, which signs the tokens issued to people after sign-in, and the plugin key store, which signs the tokens backend plugins use when calling each other.

You need pinned keys in three situations: when you run more than one backend replica, because each replica would otherwise generate its own keys and reject tokens issued by its peers; during rolling deploys, when old and new pods overlap and must accept each other's tokens; and whenever sessions must survive a restart at all. If you run a single instance with short sessions and can accept a forced sign-in after each deploy, auto-generated keys may be acceptable for a sandbox, but they are a poor fit for production. Plan the key stores before the first multi-replica rollout, not after users report failed sign-ins.

Before you change anything, confirm the exact configuration keys, the key store options and the supported signing algorithms in the Backstage authentication documentation for the release you run, since these details can differ between versions. Ask your platform team where the private keys will be stored and who may read them, because a pinned private key is a credential that can mint valid sessions. Record the owner of the key material and the rotation procedure from the start, so that the first rotation is a planned change and not an incident response.

Key store options and when each one fits

This table compares auto-generated keys, a static user key store and a static plugin key store on purpose, restart behavior, replica behavior and operating effort. Read each row against your deployment shape: how many backend replicas you run and how often they restart. The main takeaway is that anything beyond a single throwaway instance needs keys that persist outside the process.

OptionBest fitWhat survives a restartReplica behaviorOperational effort
Auto-generated keysLocal development and disposable test instancesNo. Keys are regenerated on restart, so existing sessions and tokens stop validatingNot suitable for multiple replicas, since each instance can hold different keysLowest to start, but restarts break user sessions
Static user key storePersisting keys that sign and verify user-facing tokensYes, when the key material is supplied from a file, environment variable or secret referenceAll replicas must load the same key set from the same sourceModerate: you supply, protect and rotate the key pair yourself
Static plugin key storePersisting keys for plugin-to-plugin and service callsYes, when the key material is supplied the same way as the user key storeAll replicas must load the same key set, and it is separate from user keysModerate: a second key set to supply, protect and rotate
ES256 (ECDSA P-256 with SHA-256)Asymmetric signing where verifiers need only the public keyDepends on key storage, not the algorithmPublic key can be shared widely; private key stays with the backendRequires generating and handling an EC key pair; confirm the supported key format in the authentication documentation
Other algorithms listed in the docsOnly where your security team has a stated requirementDepends on key storage, not the algorithmConfirm which algorithms the current release accepts before choosingConfirm the list and configuration keys in the authentication documentation
Key from a file pathMounted secrets in Kubernetes or a file managed by your secrets toolingYes, if the file persists across pod restartsMount the same secret to every replicaRotation means updating the mounted secret and restarting pods
Key from an environment variableSimple deployments where your platform injects secrets at startYes, if the variable is set from a persistent secret storeSet the same value on every replicaVisible to anyone who can read the process environment; confirm your platform's exposure
Key from a secret referenceTeams with an external secrets managerYes, if the reference resolves to a persistent storeEvery replica resolves the same referenceDepends on your secrets manager; confirm the reference syntax in the authentication documentation

How to configure static Backstage token signing keys

This sequence moves a Backstage instance from auto-generated signing keys to a static ES256 key pair, so sessions and issued tokens survive backend restarts and redeployments. Each step ends with a check you can run in a non-production environment before the change reaches production.

  1. Confirm the current key behavior

    Before changing anything, record how the instance behaves today. Restart the backend in a non-production environment, sign in, and note that the session is invalidated after the restart. Check the backend startup logs for a message indicating that a signing key was generated. Confirm the exact key store settings for user and plugin keys in the Backstage authentication documentation, because configuration key names change between releases and should not be copied from older examples. Done when you have a written baseline showing the session loss and the generation message.

  2. Generate an ES256 key pair outside the cluster

    Generate an ES256 (elliptic curve P-256) private key and its public key using a standard tool such as OpenSSL, run on a workstation or a controlled build host rather than inside the cluster or the application container. Keep the private key out of the Git repository and out of any shared drive. Create one pair for user keys and one for plugin keys if your key store configuration keeps them separate. Done when each pair has been created, the public key can be derived from the private key, and both files are stored only in a restricted location your team controls.

  3. Store the private keys in the secret store

    Place each private key in the secret store your organization already uses for Backstage, such as a Kubernetes Secret with encryption at rest or an external secrets manager, and mount or inject it into the backend environment as a file or variable. Restrict read access to the service account that runs the backend and to the operators who must rotate keys. Do not place private keys in app-config files. Done when the backend pod or process can read the key at startup and no other workload or user role can read it.

  4. Add the public keys to the key store configuration

    Reference the public keys in the static key store configuration for user keys and plugin keys, using the key names and paths listed in the Backstage authentication documentation for your release. Include the public key material only, so the configuration can be reviewed and stored in version control without exposing signing capability. Keep the private key path or secret reference in the deployment configuration, not the public configuration file. Done when the configuration validates and the backend starts with the static keys referenced.

  5. Deploy to a non-production environment

    Roll the change out to a non-production Backstage instance that matches production in authentication provider, database and deployment method. Start the backend and watch the startup logs for the absence of any message that reports a newly generated signing key. Confirm that the authentication flow completes with your configured sign-in resolver. Done when the backend starts cleanly, sign-in succeeds, and the logs contain no key generation message for the static keys.

  6. Verify that a session survives a restart

    Sign in and keep the browser session or a token issued by the instance. Restart the backend without changing any key material, then call an authenticated endpoint with the same token or reload the page. The session should still validate. Repeat the restart once more and check the logs again for key regeneration. Done when the token issued before the restart still validates after each restart and the logs show no key regeneration.

  7. Document the rotation and ownership plan

    Record who owns each private key, where it is stored, who can read it, and how a new public key is added alongside the existing one during rotation so that tokens signed with the old key keep validating until they expire. Confirm the rotation mechanics against the Backstage authentication documentation for your version before you write the runbook. Done when the runbook has been reviewed by the security owner and a rotation has been rehearsed once in the non-production environment.

How to rotate Backstage signing keys by adding a new key first

Rotate a Backstage signing key by adding the new key pair alongside the old one, keeping the old public key available until every token signed with it has expired, and only then removing it. The old private key should stop signing new tokens as soon as the new key is in place, but its public half must remain in the key store for as long as tokens issued before the change are still valid. Removing the old key early causes sessions to fail verification at the moment users are least expecting it, so the overlap is the part of the procedure that needs a deliberate decision rather than a default.

The length of the overlap window depends on the token lifetime configured in your deployment, and that setting is not something to assume from defaults. Confirm for your release how long issued tokens remain valid, including any refresh behavior of your sign-in provider, and read the authentication documentation at Backstage: Authentication for the settings that govern it. Set the retirement date for the old public key at or after the longest lifetime you confirm, plus a margin agreed with the security team. Record that date in the change ticket so the retirement step is not forgotten after the rotation team has moved on.

Assign ownership before scheduling anything. The platform team usually performs the change, the security team approves the key lifecycle and the retirement date, and the change approval board records both steps as one change with a rollback plan. Rehearse the full sequence in staging first: add the new key, confirm new sign-ins and plugin calls verify, confirm tokens issued before the change still verify, then retire the old public key and repeat the checks. Schedule production rotation in a low-traffic window, keep the previous key files available for a rollback, and make sure the private key is removed from any location outside the approved secret store once the rotation is complete.

Which key setup fits each Backstage deployment

A single backend instance in a test or pilot environment is the simplest case. One process holds the signing keys, so a static key store backed by a local file is usually enough. The main risk is forgetting that automatically generated keys change on every restart, which signs out every user and makes sessions look unreliable. Keep the setup simple, but do not let pilot keys or pilot file locations carry into production unchanged.

  • Key store: Use the static key store with an ES256 key pair you generate yourself, so a restart does not invalidate existing sessions.
  • Private key location: Keep the private key file on the host or volume that runs the backend, readable only by the account that runs Backstage.
  • Delivery: Mount the file from a local path or a container volume. Do not copy it into the image or commit it to the application repository.
  • Backups: Confirm that backups of the host or volume are protected, because a copy of the private key can sign tokens.

Before go-live, confirm that a restart keeps existing users signed in and that the key file is excluded from version control. Review the Backstage authentication documentation for the current key store configuration keys, since these settings can change between releases.

Protecting Backstage token signing keys in production

Once keys persist across restarts, the private key becomes a credential that can mint sessions for your whole portal. The cards below assign each protection to the team that acts on it, from file access and secret storage to change control and incident response.

Restrict private key reads to the backend

Only the Backstage backend service identity should be able to read the private key file or secret. Platform engineering sets this up through file permissions or Kubernetes RBAC, scoping read access to the workload's service account and nothing else. Check that developers, CI jobs and other namespaces cannot list or mount the secret. The public key is safe to share, so keep the two artifacts separate.

Keep keys out of config and source

Private keys must never appear in app-config.yaml, environment files committed to Git or container images. Application teams own the config files, so they should reference the key by path or secret name instead of embedding its contents. Add secret scanning to the app repository so an accidental commit is caught before it is pushed.

Encrypt keys at rest

Store the private key in a secret store that encrypts data at rest, such as a Kubernetes Secret with encryption at rest enabled, or an external secrets manager synced into the cluster. The platform team owns the secret store and should confirm its encryption and backup settings with the provider. Avoid copies in ticket attachments, chat history or shared drives.

Limit who changes key configuration

Changes to key store settings, signing algorithm or key file location alter how every session is validated. Restrict write access to the deployment repository and the secret store to a named group, and require review for changes to these values. Security owners should approve any change that adds or removes a key, since a mistake here can break sign-in for all users.

Audit every key change

Record who created, read, replaced or deleted a signing key, and when. Use the secret store's audit log together with Git history for configuration changes, and forward both to the security team's log platform. Compare these records during reviews so an unexpected key addition shows up as an event, not a surprise during an incident.

Treat a suspected leak as an incident

If a private key may have been exposed, treat it as a security incident. The security owner should add a new key, remove the compromised one from the key store, and invalidate existing sessions so tokens signed with the old key stop working. Confirm the exact session invalidation steps with your Backstage version before an incident occurs. Also review sign-in resolvers and guest access settings against the Backstage authentication documentation while you are in the middle of the response.

What persisting Backstage signing keys costs and what it asks of your team

What drives the effort of pinning Backstage signing keys?

The effort depends on four things: whether you already run a secrets manager that your platform team operates, how many environments need keys (development, staging and production each need their own), how many backend replicas must read the same key material, and what your audit requirements ask you to record. A team with a working secrets manager, a deployment pipeline and a staging environment has a short path. A team that must first build secret delivery into Kubernetes or a cloud account has more work before the key change itself. Ask a partner to quote each of these as a separate line so you can see which items you would absorb internally.

Can our internal team pin Backstage keys without a partner?

Yes, if your engineers can edit the app configuration, generate ES256 key pairs, store the private keys in your secrets manager and roll the change through your pipeline. The work is configuration and operational discipline rather than custom code. Most internal teams benefit from a written checklist covering who holds the private keys, how the public keys are published to the backend, and how a restart is tested in staging before production. A partner is useful when you lack that experience, need the change done within a fixed window, or want an independent review of how keys are stored and accessed.

How long does the initial key change take, and what sets the timeline?

The timeline depends on the same drivers as cost: the state of your secrets manager, the number of environments, the number of replicas and the change control your organization requires. We do not publish a duration for this work because it varies with those inputs. The steps are generating key pairs, adding the static key stores, testing a restart and a rotation in staging, and then promoting the change. Ask any provider, including us, for a schedule in the written scope that lists each step, the environments it covers and the approvals it needs.

What must our team provide before a key change can start?

You need to provide three things. First, access to the secret store where private keys will live, with rights to create and read the entries that the Backstage backend uses. Second, access to the deployment pipeline that rolls out configuration changes to each environment. Third, a staging environment that matches production closely enough to test a backend restart and a key addition without affecting real users. Name the owners of each item in the scope, because delays in these areas usually cost more time than the key work itself.

What recurs after go-live, and who pays for it?

Pinned keys are a one-time build, but they create recurring work. Your team must rotate keys by adding a new public key, deploying it, switching signing to the new key and then retiring the old one once tokens signed with it have expired. You must also review who can read the private keys at a set interval and record those reviews. If you pay a partner for ongoing support, the recurring cost covers rotation runs, access reviews and upgrade testing. If your team does this internally, the cost is staff time, which should be planned as a standing operational task.

What evidence should a compliance reviewer expect for key handling?

Reviewers usually look for a record of where private keys are stored, who can access them, when keys were created and rotated, and how access was reviewed. Your secrets manager's access logs and change history can supply much of this. DeployOpen prepares systems, controls and evidence for compliance assessments, but it does not issue audit reports or certifications. Independent auditors and certification bodies make those determinations. Confirm with your auditor which evidence format they accept before the change is scoped.

What should we ask for in a written quote for this work?

Ask the provider to state the scope in writing: the Backstage version and deployment method, the environments covered, the secrets manager used, the number of backend replicas, the rotation procedure to be documented, and the evidence to be delivered. Ask which items are one-time and which are recurring, and whether rotation runs or access reviews are included or billed separately. Request the assumptions behind the schedule and the list of items you must supply. A fixed-scope quote with these items lets you compare a partner with your internal estimate on equal terms.

What to confirm about key behavior in your Backstage release

The key store behavior described on this page depends on the release you run, so treat each item below as a question to answer, not a fact to assume. Confirm them against the release your organization follows and record the answers before you change production configuration.

Supported configuration keys and formats

Confirm the exact configuration keys for the static user and plugin key stores, and which key formats the release accepts, including whether ES256 key pairs are supported as written in your version. Check the key names against the authentication configuration reference for your release line, not against examples copied from older guides. A key name that is silently ignored leaves the portal on auto-generated keys, which reset on every restart. Ask the platform owner to confirm the keys by starting a test instance and checking that the same token verifies after a restart.

Handling of removed public keys

Confirm how the release treats a public key that you remove from the listed keys. Some releases continue to accept tokens signed by a key that is no longer published, while others reject them immediately. This decides whether rotation is a two-step process (add the new key, then retire the old one after tokens expire) or a single change. Test with a token signed by the old key, remove that key from the store, and record whether verification fails, and when.

Plugin caching of keys

Confirm whether plugins outside the core authentication flow cache signing keys or fetch them on each request. A plugin that keeps a copy of the public key may keep trusting a retired key, or may fail to validate a new one until its process restarts. List each backend plugin your portal runs that verifies Backstage tokens, and ask its maintainer or check its source for key caching behavior. Record the refresh interval, if one exists, in your rotation runbook.

Session behavior during a key change

Confirm what happens to signed-in users and open sessions when the signing key changes. Some setups force users to sign in again, and others keep existing tokens valid until they expire. Find out whether the release keeps user sessions across a key change or invalidates them, and whether the answer differs for user tokens and plugin-to-plugin tokens. Tell the service desk what to expect, and schedule the change for a window your users can absorb.

Restart or rolling update requirement

Confirm whether a change to the key store takes effect only after a restart, or whether the backend reloads configuration without one. Also confirm whether replicas of the backend that run in parallel must all receive the same key store before any of them sign tokens. If the backend runs more than one replica, a rolling update can leave old and new replicas issuing tokens that the other side does not yet trust. Test the change in a staging environment with two replicas before you schedule production work.

Differences across your release line

Confirm how key handling differs between the release line your organization follows and the newer line. Backstage ships a main release line monthly and a next release line weekly, so a key behavior change may appear in one line before the other. Review the release notes for each version between your current release and your target, and check the versioning policy for the line you follow. Record the version you tested so that the result stays tied to a specific release.

How DeployOpen scopes and delivers Backstage key hardening

DeployOpen plans, implements and hands over Backstage key hardening inside your own infrastructure, so the signing keys, their storage and their rotation procedure are documented and owned by your team. Work is agreed as a fixed-scope engagement with written deliverables, and ongoing support is available as a retainer.

How we scope

  • Inventory where your Backstage instance currently generates keys and whether restarts invalidate existing sessions.
  • Agree in writing which key stores, key formats and secret locations are in scope for your environment.
  • Confirm with your team who approves rotation, who holds private key access and which systems must be updated first.

How we build

  • Configure a static key store for user and plugin keys, with ES256 key pairs generated under your own key management process.
  • Test that tokens issued before a restart remain valid after the instance restarts, in a non-production environment first.
  • Rehearse a rotation by adding a new key, confirming both keys validate, then retiring the old key in a controlled window.

How we hand over

  • Document the key locations, file permissions, environment variables and the rotation runbook your operators will follow.
  • Provide verification steps so your team can confirm the active key set after every deployment or configuration change.
  • Walk your engineers through the procedure and record the deliverables that were agreed in the written scope.

How we support

  • Offer ongoing support as a retainer for key rotation reviews, Backstage version upgrades and configuration changes.
  • Review key handling again when Backstage releases change authentication or plugin token behavior, as your scope allows.
  • Confirm the support terms, response expectations and included activities in writing before the retainer starts.

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.