Dify SECRET_KEY management and rotation risks

Dify's SECRET_KEY signs session cookies and JWTs and encrypts OAuth credentials, so changing it logs every user out and can break plugin credentials. Plan the generation, storage and rotation window before go-live.

On this page

Why Dify SECRET_KEY management needs a plan before go-live

Generate and store the Dify SECRET_KEY deliberately before the first user signs in, because changing it after deployment logs out all users. The same value does two jobs in a self-hosted deployment: the Dify environment reference says it signs session cookies and JWTs, and it also encrypts OAuth credentials. That means one environment variable controls who stays signed in and whether stored OAuth credentials for plugins can still be read. Teams often treat it as a default to be copied from a sample file, but the value needs an owner, a secure home outside casual copies of the .env file, and a written record of when it was set. Community edition, which is free and limited to a single workspace, places this responsibility entirely on your team. Dify Enterprise, which adds SSO and multiple workspaces, still depends on the same key for session and credential protection, so the plan applies there too.

Plan for three moments: the first deployment, the first audit or security review, and any suspected leak of the key. Before go-live, confirm who generates the value, where it is stored, who can read the environment file or orchestration secret that holds it, and whether backups of that store are protected to the same standard. During an audit, expect the reviewer to ask how the key is stored, who can access it, and when it was last changed, so keep that answer written down and tied to a change record. If the key may have been exposed, rotation is the response, but it forces every user to sign in again and can break OAuth plugin credentials, so it should happen inside a planned maintenance window with users and plugin owners notified. Ask your deployment partner or internal platform team to confirm the rotation steps for your exact Dify version against the Dify environment variables reference before any incident occurs.

How to generate and store the SECRET_KEY safely

This sequence produces a high-entropy SECRET_KEY that is set once in the Compose environment, readable only by the operator account, shared consistently by the api and worker services, and verified without leaking into logs.

  1. Confirm where the Compose stack reads variables

    The operator opens the Docker Compose quick start and confirms which file holds the Dify environment variables for the deployment, typically the .env file copied from .env.example in the Dify docker directory. Before editing anything, they check which compose file and env file the stack is started with, so the value is read from the location they plan to protect. The step is done when they can name the env file and the command used to start the stack.

  2. Generate a high-entropy value with a standard tool

    The operator generates the key with a cryptographically secure random source available on the host, such as openssl rand with a 256-bit or longer output encoded as base64 or hex, and does not type a passphrase or reuse a value from another system. The generation runs on a trusted administrative workstation or host, and the output is not written to shell history or a shared ticket. The step is done when the value is in a password manager or secrets store entry with a recorded creation date.

  3. Set SECRET_KEY in the deployment environment file

    The operator sets SECRET_KEY in the env file used by the Compose deployment, replacing any placeholder from the example file, and makes sure no second definition in an override file or shell environment takes precedence. Because the value signs session cookies and JWTs and encrypts OAuth credentials, it is set before first use wherever possible. The step is done when a grep of the effective configuration shows exactly one non-placeholder definition.

  4. Restrict file permissions and exclude the file from version control

    The operator sets the env file to be readable only by the account that runs Docker Compose, for example owner read and write only, and adds the file to .gitignore or equivalent so it is never committed. Backups of the Dify host and its configuration directory are handled with the same restriction, because a widely readable backup exposes the key as much as the live file does. The step is done when the permission check and the ignore rule are both confirmed and the backup job's access list has been reviewed.

  5. Recreate services so both api and worker load the value

    The operator recreates the stack with the Compose command they normally use, so the api and worker containers start with the new environment, and then inspects the running containers to confirm both received the same value. Comparing a hash of the value inside each container avoids printing it. Restarting only one service would leave the other on an older value, so both are checked. The step is done when both containers report the same fingerprint.

  6. Verify login after restart and check logs for the value

    The operator signs in to the console, opens a workspace and confirms the session survives a full stack restart, which shows the value is stable across restarts. They then search container logs and any log shipping destination for the key string or its first characters, and confirm it does not appear. The step is done when login persists after restart and the log search returns no matches.

  7. Record the key and the change in the operations log

    The operator records in the secrets inventory where the key is stored, who can read it, the date it was set and the Dify version in use, without storing the value in the ticket or wiki. This record is what a later rotation will depend on, because rotation logs all users out and affects stored OAuth plugin credentials, so it needs a planned window. The step is done when the inventory entry exists and names the owner.

Storage options for the SECRET_KEY and when each fits

This table compares three ways to store Dify's SECRET_KEY: a restricted .env file, a secrets manager injected at container start, and a Kubernetes secret for Enterprise on Kubernetes. Read each row against your own platform and the controls your assessors expect. The main takeaway is that the key must be stored outside the image and backed up securely, because losing or exposing it has consequences that are hard to reverse.

OptionWhat it protects againstOperational costWhen it fits
Restricted .env fileAccidental exposure in source control and casual reads by other local users when file permissions are set tightlyLow setup cost, but ownership, permissions and backup of the host file stay with your team and need routine checksSingle-host Docker Compose deployments with a small operator group and a clear procedure for keeping the file out of repositories
Secrets manager injected at container startCentral storage, access logging and rotation control, with the value kept out of image layers and shared filesHigher setup cost for the injection step and an added dependency that must be available when containers startRegulated teams that already run a secrets manager and need audit trails for who can read the key; confirm the injection method with your platform team
Kubernetes secret for Enterprise on KubernetesKeeps the value out of manifests and config maps and limits access through cluster role bindingsModerate cost for RBAC design, encryption at rest for etcd and a rotation runbook; often paired with an external secrets operatorEnterprise deployments on Kubernetes where the cluster already enforces access control; confirm etcd encryption and access policies with your cluster team
Backup of the key held separatelyRecovery if the host or cluster is lost, since sessions and encrypted OAuth credentials depend on the same valueRecurring effort to keep the copy current and tested, plus controls on who can retrieve itEvery production deployment, because a changed or missing key logs out all users and affects stored OAuth plugin credentials
Key stored only inside the Dify host or imageLittle beyond convenience; the value travels with backups, images and snapshotsLowest setup cost, but the highest exposure and the hardest cleanup if the image or snapshot leaksGenerally unsuitable for production; use only for throwaway test environments

What rotating the key breaks and why it needs a window

Changing SECRET_KEY after deployment is not a routine configuration edit. The Dify environment reference states that changing it after deployment logs out all users, because the key signs session cookies and JWTs. Every console user, end user and integration that holds a session will need to sign in again. Because the same key encrypts OAuth credentials, stored plugin OAuth credentials may also stop decrypting. Our expectation is that affected plugins will need to be re-authorized by someone with the right access, but the docs do not spell out this outcome, so confirm it in a test environment before you schedule anything in production.

Treat rotation as a change window with named owners. Decide who announces the window, who can sign back in and re-authorize plugin connections afterward, and which service accounts or automated jobs depend on a live session. Tell console administrators and workspace owners in advance that they will be signed out, and give end users a clear message if web apps or embedded experiences rely on Dify sign-in. Agree on a rollback point before you start, because restoring the previous key is the only way to recover encrypted OAuth credentials if the new key cannot read them.

Rehearse the full sequence on a copy of the instance before production. Restore a recent backup into a separate environment, change SECRET_KEY there, and check which plugins need re-authorization, which integrations fail and how long the operator steps take. Back up before every change, as the Dify Docker Compose guidance recommends for upgrades, and apply the same discipline here. When you move to a new Dify release at the same time, check .env.example for new variables first, so a new setting is not mistaken for a rotation problem during the window.

Risks to review before changing the key

Changing SECRET_KEY touches sessions, stored credentials, background work and recovery, so each risk below needs a decision before the change window opens. The cards are ordered from user-facing impact to the audit trail you will need afterward.

Forced logout for every user

The environment reference says changing SECRET_KEY after deployment logs out all users. That includes people signed into the console to build and publish apps, not only end users of published web apps. Confirm who needs to sign in again, announce the window to workspace owners, and check that administrators can still reach the console afterward using their own recovery path.

Broken OAuth plugin credentials

SECRET_KEY also encrypts OAuth credentials, so plugins that store OAuth tokens may stop working after the value changes. Ask every workspace which plugins hold OAuth connections, record the reauthorization steps for each, and plan who will complete them. Treat this as a separate task from the logout notice, because users may not notice a failing integration until a workflow runs.

Mismatched values across containers

Several services in a Docker Compose deployment read the same environment file, and a container that keeps the old value can fail to decrypt or verify data written by a container with the new one. Confirm that api, worker and any other service that loads SECRET_KEY all restart with the same value, and check that no stale copy is pinned in an override file or orchestration secret.

Lost access without a backup

Because the key encrypts stored OAuth credentials, a database restore paired with a different key can leave encrypted fields unreadable. Before changing the value, record the current key in your secrets store with its version and date, and take a backup of the metadata database and file storage. Confirm you can restore both and still decrypt the stored data before you rely on the procedure.

Rushed rotation after a leak

A suspected leak creates pressure to rotate immediately, which raises the chance of the other risks landing at once. Decide in advance who can authorize an emergency rotation, which dependencies must be reauthorized first, and whether you will rotate during business hours. Also check whether the leaked value could have been used to forge sessions, and review access logs for the exposure period.

Audit evidence of the change

Changing a root secret is a privileged change that auditors and security reviewers will expect to see documented. Keep a change record with the reason, approver, window, the version of Dify running, and the checks you performed afterward. Store the record with your other change management evidence, and confirm with your auditor which format they accept.

Rotating SECRET_KEY in a planned window

This sequence turns a SECRET_KEY change from an unplanned logout and broken plugin connections into a scheduled, reversible maintenance window with known checks at each stage.

  1. Back up database and file storage

    The operator who owns the Dify deployment takes a full backup of the metadata database and the configured file storage before any change. Confirm the backup can be restored by checking that the archive is complete and readable, and record where it is stored and which SECRET_KEY value was in use when it was taken. Dify's Docker Compose guidance recommends a backup before every upgrade, and the same discipline applies to a key change because encrypted OAuth credentials live in the database. The step is done when the backup is verified and its location is written into the change record.

  2. Document current OAuth plugin connections

    The platform owner lists every plugin that holds an OAuth credential, the workspace it belongs to, the external account it authorizes, and who will re-authorize it after the change. Changing SECRET_KEY affects encrypted OAuth credentials, so this inventory is the list of connections that must be rebuilt. Keep the list outside the Dify instance so it remains available if the console is unreachable. The step is done when each connection has a named owner and a re-authorization path that does not depend on the old key.

  3. Rehearse rotation in a non-production copy

    Restore the backup into a separate environment with the same Dify version, then apply the planned new SECRET_KEY and restart the services. Confirm that the restored instance starts, that the login and console behave as expected after the logout, and that plugin credentials fail in the way the inventory predicted. Measure the steps you need so the production window is sized from observation rather than assumption. Confirm each action against the upgrade guide for the target version, since configuration expectations can change between releases. The step is done when the rehearsal log records every command and the observed result.

  4. Set the new value across all services

    The deployment owner updates SECRET_KEY in the environment file used by every Dify service that reads it, including the API, worker and any other container that receives the variable in your Compose or Kubernetes configuration. Use one source of truth for the value, store it in your secrets manager, and avoid leaving the old value in shell history, tickets or backup copies of the env file. Check each service's configuration for a stale copy before restarting. The step is done when a search of the deployed configuration shows one consistent value and no service still holds the old one.

  5. Restart services and confirm health

    The operator restarts the Dify services in the order the version's guide describes and waits for each container to report healthy before the next. Expect every existing session to end, so announce the window to users beforehand. Check the API health endpoint, the web console and background worker logs for decryption or signing errors. The step is done when all core services are running without key-related errors in their logs and the console loads.

  6. Re-authorize plugin credentials

    Each owner from the inventory signs in to the affected plugin and completes its OAuth authorization again so new credentials are encrypted under the new key. Work through the list in order and record the date and the connecting account for each one. Test one tool call per plugin to confirm it returns data from the external service. The step is done when every inventory entry shows a working connection and a recorded re-authorization.

  7. Confirm sign-in and close the window

    Test sign-in with an administrator account, a standard member account and, where used, an SSO or social login, then open a published app to confirm that its workflows run. Check that the backup from the first step remains available until these checks pass. Record the outcome, any deviations and the rollback decision in the change record before closing the window. The step is done when each sign-in path and app run is confirmed and the change record is signed off.

  8. Define the rollback path before starting

    Agree the rollback conditions in advance: for example, a failed restart, unreadable credentials or users locked out after the checks above. Rolling back means restoring the prior SECRET_KEY value together with the backup taken earlier, because a restored database without the matching key cannot decrypt credentials written under the new one. Confirm with your Dify version's upgrade guide and your own environment whether a key revert alone is supported. The step is done when the rollback owner, trigger conditions and restore steps are written in the change record before the window opens.

Operational controls around the key

The SECRET_KEY sits in a small set of places: the environment file, the host that reads it, backups, and the test copies people make while debugging. Each of those places needs its own control, and the controls only work together if you know who can read the value and how quickly you can change it.

Restrict the environment file and host

Your .env file holds SECRET_KEY next to database and Redis passwords, so treat it as a credential file. Set ownership so only the deployment account and the Docker daemon can read it, keep it out of shared directories and version control, and limit SSH and sudo access to the host to people who run deployments. Check file permissions after every upgrade, since upgrade steps tell you to compare .env with .env.example and it is easy to recreate the file with default permissions.

Separate production and test keys

Do not copy the production .env into a staging or developer environment. A test instance built with the production SECRET_KEY can have its session cookies and JWTs accepted by production if the two share any trust path, and a leaked test value then exposes production. Generate a distinct key for each environment, and record which key belongs to which instance so a rotation in one does not get confused with the other.

Log who reads and changes the value

Record access to the .env file and the secrets store that holds it, including reads by configuration management tools and changes to the file. Your host audit tool or secrets manager can usually provide this, but confirm that it captures file reads, not only writes. Review the log before and after each rotation, so that a change you did not plan is visible.

Handle backups that contain the key

Backups of the Dify deployment may include the .env file or a copy of the Docker configuration, which means the SECRET_KEY is inside the archive. Encrypt backup archives, restrict who can restore them, and store the key separately so a restored copy does not carry live credentials into an unexpected place. Confirm with your backup tool whether it captures hidden files and environment files by default, because omissions and inclusions both cause problems during restore.

Respond to a suspected exposure

If you believe SECRET_KEY has leaked, treat it as compromised and plan a rotation outside normal hours. Rotation logs out all users and invalidates the OAuth credentials that plugins store, so expect a sign-in wave and plugin re-authorization. Identify where the value was exposed, such as a chat log, a support ticket or a repository, and remove those copies. Then check for unexpected sign-ins and record the timeline for your incident team.

Questions teams ask about SECRET_KEY rotation

Does a self-hosted Dify need its SECRET_KEY rotated on a schedule?

No supplied guidance sets a fixed rotation interval, so treat scheduled rotation as a policy decision for your security team rather than a Dify requirement. The Dify environment reference says SECRET_KEY signs session cookies and JWTs and encrypts OAuth credentials, and changing it after deployment logs out all users. That makes every rotation a disruptive event, so most teams rotate when they have a reason: suspected exposure, staff departures with access to the env file, or a policy that your auditors expect you to follow. Confirm your organization's rule before you plan the first window.

How long does a SECRET_KEY rotation take in a self-hosted Dify?

The time depends on how much depends on the old key, and no supplied fact gives a duration. The main drivers are the number of OAuth plugin connections that must be re-authorized, the number of environments that share or copy the key, the size of the user base who will be logged out and must sign in again, and whether you run any external process that holds sessions or tokens. Each environment, including staging, needs its own planned change, and the change must be tested on a copy before production. Ask any partner for a written effort estimate that lists these drivers for your instance.

Can our own team rotate the SECRET_KEY without outside help?

Yes, a team that already operates Docker Compose deployments can usually make the change, provided it treats the rotation as an operational event. The work is mostly planning: announcing a window, updating the value in your environment file, restarting the services that read it, and then having affected users and plugin owners reconnect their OAuth credentials. The risk lies in skipping steps such as backing up the database before the change or inventorying which OAuth connections will break. If your team has not run a rotation before, a rehearsal on a non-production copy is the safest way to learn the sequence.

What does a consultant need from us before quoting SECRET_KEY rotation work?

A consultant needs enough detail to write a fixed scope that you can approve in writing before work starts. Prepare the Dify version you run, the deployment method, the number of environments, how the current SECRET_KEY is stored and who can read it, the list of OAuth plugins and connected accounts, and the user population and their sign-in methods. Also share your backup arrangements and your change-window constraints. Most engagements are fixed-scope, so the quote follows from that written scope rather than from a list price.

Can a SECRET_KEY change be undone after it is made?

Restoring the old value is the practical way to reverse a change, but it only works if you kept a copy of the previous key and the services have not already re-encrypted stored data under the new one. The supplied facts say changing the key logs users out, and they say the key encrypts OAuth credentials, so the safe approach is to take a backup of the database and the environment file before you start. Keep the previous key in your secrets store for a defined period, and test the restore path on a copy. Confirm the exact behavior with Dify's FAQs and your deployed version before you rely on a rollback.

How does SECRET_KEY rotation relate to workspace encryption keys?

They protect different things, so rotating one does not replace the other. The Dify environment reference says SECRET_KEY signs session cookies and JWTs and encrypts OAuth credentials, while workspace encryption keys can be stored locally or in Azure Key Vault. Your plan should record which encryption path holds each secret and what each rotation affects. Decide the workspace key storage choice before the first workspace exists, because that choice shapes how keys are managed later. Ask your security team to map both key types to owners and to a documented procedure.

Which Dify version should we confirm before planning a SECRET_KEY change?

Confirm the behavior against the release you actually run, because minor releases arrive roughly monthly and each one can change configuration or security behavior. The Dify releases page lists versions such as 1.16.0, 1.17.0 and 1.17.1, and the Dify Docker Compose docs advise checking .env.example for new variables after an upgrade. Plan the rotation after you have settled on a target version, so the window does not coincide with an unrelated upgrade. Review the release notes for any change to how secrets are read or stored.

How DeployOpen plans and runs SECRET_KEY rotation

DeployOpen treats SECRET_KEY as a planned change to a running Dify system, not a one-line edit. We scope where the key is stored, which sessions, OAuth credentials and plugin connections depend on it, and when a rotation window can be scheduled. The work is delivered inside infrastructure you control, with the steps written down before anything changes.

How we scope

  • Written scope lists every Dify instance, environment file and secret store that holds SECRET_KEY for your deployment.
  • We map which users, OAuth plugin credentials and integrations would be affected by a forced logout or re-authorization.
  • Engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts.

How we build

  • We generate and store the key in your approved secrets location, with access limited to the people and services that need it.
  • We write a rotation runbook with a backup taken beforehand, a named change window and a documented rollback path.
  • We test the rotation on a non-production copy first, checking logins, OAuth plugin connections and scheduled workflows afterward.

How we hand over

  • You receive the configuration record, the rotation runbook, the test results and the list of re-authorizations users must complete.
  • Operators are walked through the procedure so your team can repeat it at the next scheduled rotation.
  • Documentation covers where the key lives, who approves rotation and how exposure of the key should be handled.

How we support

  • Ongoing support is available as a retainer, including help planning rotations alongside Dify's roughly monthly minor releases.
  • Retainer work can cover upgrade checks against the environment example file so new variables are not missed after a release.
  • Ask any provider to confirm how SECRET_KEY is handled in your own environment before a rotation is scheduled.

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.