Dify service API keys and end-user identity

Dify issues API keys per app and accepts a user identifier with each call, but it does not authenticate that user. Your backend has to decide who the end user is and keep that decision out of the client.

On this page

How Dify service API keys work for backend calls

Each published Dify app is called with its own service API key, and the user field in a request is a label that Dify does not verify. Your backend holds the key, authenticates its own customer or employee, and then passes an identifier for that person in user. Dify uses that value to group conversations and files, but it cannot confirm that the caller is who the value claims. Anyone holding the key can send requests under any user label, so the key is the credential that matters. It belongs in a server-side secrets store, never in browser code, mobile apps or shared client configuration.

This design fits three common shapes. A customer-facing product calls Dify from its own backend so end users never see a key. An internal portal does the same for employees, where your existing sign-in decides who may reach each app. Scheduled or event-driven pipelines call Dify from a job runner, with the key held in that runner's secrets. This topic sits in the API and app delivery area of this hub, alongside embedded web apps, the difyctl CLI and promotion between instances. Before you build, confirm how keys are created, listed and revoked for each app in your version, using the App management documentation.

Settle the identity mapping before the first production call. Choose a user label that is stable and opaque, drawn from your own user ID, so personal data such as email addresses is not copied into Dify records. Confirm whether the label can be seen by end users in any Dify interface. Record which key serves which app and which backend service holds it, and write a rotation and revocation runbook before launch. Dify's SECRET_KEY is a separate secret that signs session cookies and JWTs, so rotating it does not replace rotating an app key. Treat each app key with the same care as a production database password.

What the user field does and does not prove

The user value on a Dify API call groups conversations and files, but Dify takes it at face value. Each card below marks one thing the field does and does not establish, and what your backend must own before a request reaches Dify.

Supplied by the caller

The user identifier arrives in the request body or query that your backend sends to Dify. Dify does not check that the value belongs to the person who started the request. Whatever your service passes is what Dify records. Treat the field as an assertion made by your server, not as proof of who is signed in.

Dify does not authenticate it

Dify authenticates the API key, not the end user. A valid app key lets the caller send any user value and read the conversations that value owns. Authentication of the person happens in your application, through your own login and session handling, before the call is made.

Groups conversations and files

The user value is the grouping key for conversation history and for files uploaded to an app. Listing and continuing conversations, and reusing uploaded files, depend on matching that value. Confirm in the current API reference for your version exactly which endpoints filter by user and which return data across users.

Not a Dify account

An end-user value does not correspond to a Dify workspace member, a console login or a role. Removing a person from your system does not remove their conversation history in Dify, and no Dify permission follows from the value. Plan your own retention and deletion process for these records separately.

Cross-customer exposure risk

If the browser or mobile client supplies the user value, one customer can change it and read another customer's conversation history through the same app key. Keep the key on the server and derive the user value from the authenticated session on each request, so a client cannot choose a different value.

Confirm before you build

Check the current API reference for the Dify version you run. Confirm which conversation, message and file endpoints require the user value, whether a missing or mismatched value is rejected, and how deletion behaves. Test with two synthetic users and confirm that neither can read the other's data.

Which identity pattern fits which backend

This table compares three ways a backend can fill the user field when it calls a Dify app: a shared service user, a per-customer identifier from the backend session, and a per-employee identifier for internal tools. Read each row for what the pattern isolates, what it leaves open and when it fits. The main takeaway is that Dify stores whatever user string the backend sends, so the isolation you get is only as strong as the mapping your backend applies.

PatternWhat it isolatesWhat it leaves openWhen it fits
Shared service user per appCalls from one app are grouped under one identifier, separate from web app users and other appsConversations and uploaded files from all end users share one user scope, so one customer can see or resume another customer's history if the backend passes the same identifierSingle-purpose internal tools or batch jobs where every caller has the same access and no end-user data separation is required
Per-tenant or per-customer identifier derived from the backend sessionConversations and files are grouped by customer account, so one customer's history does not appear under another customer's identifierThe identifier must be stable and unguessable, and the backend must never let a client choose it; mapping errors, reused IDs or deleted accounts can still cross data boundariesCustomer-facing products where end users sign in to your application and the backend holds the session
Per-employee identifier for internal toolsConversations and files are grouped by the employee who made the request, which supports audit by personThe identifier is a label Dify does not verify, so access control to the app and its history still depends on your internal gateway or SSO; shared workstations can blur attributionInternal assistants and workflows used by staff where your identity provider already controls who can reach the backend
Identifier taken from the browser or request bodyNothing reliable; the caller controls the valueAny client can send another user's identifier and read or continue that user's conversationsGenerally not suitable. Use only for prototypes that never hold real data
Confirm before go-liveWhether conversation listing, resume and file retrieval filter by the user field in your deployed versionBehavior of file uploads and deletion per user, and whether a web app user and an API user with the same string are treated as the same personTest with two identifiers in a staging instance and record the results before you choose a pattern

Why API users and web app users stay separate

Your backend calls a Dify app with a service API key that belongs to that app. The key identifies the calling system, not a person. The user field in each request is a string your backend supplies to label the end user it is acting for. Dify does not verify that value against any directory, so your application is responsible for deciding who that string represents and for only sending values your own login system has already checked.

  • Key scope: A service API key authorizes calls to one app, so plan one key per app and per environment rather than one shared key.
  • Caller identity: The key proves the backend holds the credential. It does not prove which customer is on the other end.
  • User string: Use a stable, non-sensitive identifier from your own identity system, and avoid raw email addresses or national identifiers unless your privacy review allows them.
  • Conversation boundaries: Conversations and files are scoped by the user value your backend sends, so a mismatch can mix one person's history with another's.
  • Credential storage: Keep keys in your secrets manager and rotate them through your normal process.

Before launch, confirm in your own test instance how your chosen Dify version handles the user field, including conversation and file behavior, against the Dify docs on app management.

How to set up per-app keys and identifiers safely

This sequence gives each Dify app its own API key, keeps that key in your backend secret store, and maps signed-in users to identifiers that Dify can scope conversations and files by. It ends with a rotation runbook that your team has tested in a non-production instance.

  1. Create a dedicated app in the console

    A platform engineer or app owner creates one Dify app for each backend integration, in the workspace that integration will use. Give the app a name that shows its owner and purpose. Confirm in the current app management docs where new apps are created and which workspace roles on your edition can create them. Check: the app appears in the workspace app list, and your inventory records the app name, workspace, and owning team.

  2. Generate the app's API key

    Open the API access area of the new app and generate a key for that app only. Confirm the current menu label in the docs, whether the key is displayed once, and which console roles can view or create keys. Store the key only in the secure channel described in the next step. Check: a test request with this key succeeds against this app, and the same key is rejected when it is used against a different app.

  3. Store the key in the backend secret store

    Place the key in the secret manager your backend already uses, under a path that names the Dify app and environment. Keep the key out of source control, container images, client-side code, and browser storage. Limit read access to the service that calls Dify. Check: a secret scan of the repository and the frontend build finds no Dify key, and the service loads the key from the secret store at runtime.

  4. Define the identifier mapping from your session

    Decide how the signed-in user in your application becomes the user identifier sent to Dify. Dify does not authenticate that value, so your backend must derive it from the verified session on every call. Prefer a stable, pseudonymous identifier over an email address. Never accept the identifier from the browser request body. Check: a written mapping rule exists, the security owner has reviewed it, and the backend rejects any call where the session identifier is missing.

  5. Test with two identifiers in a non-production instance

    From the backend, start a conversation for the app under identifier A, then send a follow-up under identifier B using the same conversation ID. Upload a file under each identifier. Confirm in the current API docs how conversation IDs and uploaded files are scoped in your Dify version before you run the test. Check: identifier B cannot continue A's conversation, and neither identifier can retrieve the other's file. If either check fails, stop and review the mapping and conversation handling before release.

  6. Confirm web app users stay separate

    Confirm how end users of the published web app are authenticated and recorded in the app's access settings and the current access docs. Make sure no API identifier is reused as a web app user, and that backend-driven conversations do not appear in web app user history. Check: a signed-in web user and an API identifier with the same string produce separate conversation lists, and the security owner has recorded the result.

  7. Document and rehearse key rotation

    Write a rotation runbook that names who generates a new key, how the secret store entry is updated, how the backend reloads it, and how the old key is revoked. Confirm in the current docs whether an old key can be disabled as soon as a new one is issued. Rehearse the process on a non-production app. Check: after rotation, the new key passes the step 5 tests, the old key is rejected, and the runbook has been reviewed by the team that owns the backend.

Security risks in service key and identifier design

Dify service API keys authorize calls to an app, and the user field that accompanies those calls is never authenticated by Dify. Most of the risks below come from treating a key as a browser credential or trusting a client-supplied user value, so each card names the control you own on your side of the integration.

Leaked app keys in client code

A Dify service API key grants the same access as the app it belongs to, so a key shipped in a browser bundle, mobile app or public repository can be used by anyone who finds it. Keep calls to Dify inside a backend you operate, load keys from a secrets store at runtime, and confirm that build pipelines and front-end bundles never contain them. Search your repositories and frontend artifacts for key strings as part of release checks.

Client-controlled user value

The user field in a Dify API request is a string your caller supplies, and Dify does not authenticate it. If your backend passes an identifier from the request body straight through, one customer can read or continue another customer's conversations and files by changing that value. Derive the user value on the server from the authenticated session, and test with two accounts that a caller cannot reach the other account's conversation IDs.

Keys shared across apps and environments

A single key reused by several apps, or copied between staging and production, widens the blast radius of any one leak and makes it impossible to tell which system made a call. Issue a separate key per app and per environment, record the owner of each key, and check in your audit trail which application issued each request. Ask the vendor or your own platform team how keys are scoped in the version you run before you finalize this model.

No rotation procedure

Keys that never change remain valid after a developer leaves, a server is retired or a secret appears in a ticket. Write a rotation procedure before go-live: who issues the new key, how the backend picks it up without a deploy freeze, when the old key is revoked, and how the change is verified. Rehearse it once in a non-production instance so the first real rotation is not the first test.

Keys and prompts in logs

Gateway logs, backend request logs, tracing tools and error reporters often capture full request headers and bodies, which can include the bearer key and the user prompts that contain customer data. Configure your reverse proxy and application logger to redact the Authorization header and sensitive body fields, and set retention limits on those logs. Review a sample of log lines from a test conversation before exposing the integration to real users.

SECRET_KEY changes that log out users

The SECRET_KEY setting signs session cookies and JWTs and encrypts OAuth credentials, and the Dify environment reference notes that changing it after deployment logs out all users. Treat it as a long-lived secret: store it in your secrets manager, keep it out of shared configuration files, and schedule any change as a planned maintenance event. Confirm the effect on stored OAuth credentials with the Dify docs before you rotate it.

Questions teams ask before building the identity layer

Can we trust the user field that a Dify app receives from our backend?

No. Dify uses the user value your backend sends to scope conversations and files, but it does not verify who that person is. Anyone holding an app's API key can send any user string, so the key must stay on the server and never reach a browser or mobile client. Your backend should authenticate the person through your own identity provider first, then send a stable internal identifier that Dify stores as the user. Treat that identifier as a label your system controls, not as proof of identity. Confirm the exact request fields and their behavior in the Dify API documentation for the version you run.

Can Dify map users to SSO accounts on the Community edition?

The pricing page lists SSO as part of the self-hosted Enterprise edition, while Community is free and limited to a single workspace. Plan on Community having no built-in mapping from identity provider accounts to Dify users until you confirm otherwise in the docs for your version. The usual approach is a mapping table in your backend that links each identity provider subject to a Dify user identifier. Your team then owns that table, its updates when people join or leave, and its audit trail. If SSO inside Dify's console is a requirement, compare the Enterprise terms directly with Dify's pricing before you commit to a design.

How much effort does backend user mapping take, and what drives it?

The effort depends on how many apps call Dify, how many identity sources feed them, and how the apps are used. The core work covers validating the caller's session, generating and storing the user identifier, scoping conversation and file access to the right person, handling account changes and deletions, and logging enough to investigate misuse. Costs rise with each app that needs its own rules, with external users who sign in through a separate path, and with data retention requirements that dictate how long conversation history is kept. Ask any partner, or your own planning document, to itemize these components separately so you can see which parts are one-time build work and which are ongoing maintenance.

Can our internal team build this without an implementation partner?

Yes, if the team has backend engineers who know your identity provider, can work with Dify's API and can own the code after launch. The hardest parts are usually not the API calls but the decisions around account lifecycle, data scoping and key handling, which need agreement from the people who own those systems. A partner is most useful when the team lacks that experience, when the schedule is tight, or when an outside reviewer is needed before security sign-off. DeployOpen plans and implements work like this as fixed-scope engagements, with scope, deliverables and timelines agreed in writing before any work starts.

What do app owners, identity owners and security reviewers need to provide?

Each group supplies a different decision. App owners define which users each app serves, what data those users may send and how long conversations should be kept. Identity owners confirm the source of truth for accounts, how joiners, movers and leavers are handled, and which claims or attributes the backend can rely on. Security reviewers check how keys are stored, where the backend runs, who can read logs and how the design handles misuse, such as a leaked key. Ask for these decisions in writing before build starts, since changes to them after development usually cost more time than the original build.

How does API key rotation fit into Dify release cycles?

Rotate keys on a schedule that is separate from upgrades, but run both inside the same change window so one failure does not hide the other. Dify's GitHub releases show minor versions arriving roughly monthly, for example 1.16.0 on July 17, 2026 and 1.17.0 on August 25, 2026. Before each upgrade, take a backup, follow the upgrade guide for the target version and check .env.example for new variables. For key rotation, issue the new key, deploy it to the backend, confirm traffic has moved, then revoke the old key. Confirm in the docs how many keys an app can hold at once. Do not confuse this with SECRET_KEY, since changing it logs out all users.

Can one self-hosted Dify serve several customers with separate end users?

Separate end users inside one app is an identity design question that the backend can handle. Separate customer organizations sharing one Dify instance is a licensing question. The Dify Open Source License forbids using the source code to operate a multi-tenant environment, where one tenant is one workspace, without written authorization. If each customer needs its own workspace on your instance, ask Dify for written authorization before you design around that model. Also confirm that your backend keeps customer data separate, since end-user scoping alone does not isolate tenants. Read the license text with counsel before making that commitment.

What a fixed-scope engagement on this design covers

A fixed-scope engagement starts with a written scope that names every app and backend in scope, the Dify instance each one runs on, and the calling services that will hold keys. DeployOpen would also record the identifier model in that document: which value the backend sends as the user field, where that value comes from in your identity system, how it is formatted, and who owns the mapping. The scope would state which apps are chat, completion or workflow apps, because conversation and file scoping differ between them, and which apps are meant to be reached by end users through the web app instead of the API. Those decisions are easier to settle before build than to unwind after a key has been issued.

The scope would also set the secret storage approach. That covers where each app's API key lives (for example, a secrets manager you already operate or a platform secret store in your cluster), how services retrieve it at runtime, how keys are rotated and revoked when a service or developer changes, and how the Dify side is kept from exposing keys in logs, browser code or CI output. Your team should confirm which secrets platform is approved for production and whether your security policy requires rotation intervals, since DeployOpen would build the process around those requirements rather than assume them. Cross-user isolation tests are the other fixed deliverable: test cases that send requests for user A using conversation and file identifiers from user B, confirm rejection or empty results, and record the outcome for audit.

The quote follows from that written scope. Cost depends on the number of apps and backends, how many identity sources feed the user mapping, the depth of isolation testing, and the documentation set your owners need, including runbooks for key rotation and an app-to-owner register. DeployOpen does not publish a price list, so ask for a scope document and a quote tied to it, and check that the quote lists each deliverable, what your team must provide (such as identity system access and named owners), and what is excluded. Ongoing support after handover is priced separately as a retainer.

How DeployOpen scopes and supports Dify API integrations

DeployOpen plans, implements, documents and supports self-hosted Dify inside your own infrastructure, including the backend calls that use per-app API keys and the end-user identifiers your product sends. Engagements are fixed-scope, with the scope, deliverables and timelines agreed in writing before work starts.

How we scope

  • We inventory every Dify app your backends will call and record which key, workspace and instance each one uses.
  • We define how your product's user identifiers map to the Dify user field and where that mapping is stored.
  • We document which conversation and file behaviors you need, so the written scope reflects real ownership rules.

How we build

  • We implement a backend service layer that holds app keys in your secrets store and never in client code.
  • We build tests that confirm one end user cannot read another user's conversations or uploaded files.
  • We configure outbound calls and key rotation procedures inside the environment you operate.

How we hand over

  • We deliver a written reference covering key issuance, scoping, rotation and the identifier rules your teams must follow.
  • We provide runbooks for revoking a leaked key and for checking which apps a compromised credential could reach.
  • We walk your engineers through the code and tests so they can extend the integration without us.

How we support

  • Ongoing support, upgrades and continuous testing are available as retainers, covering Dify releases that change API behavior.
  • We re-run identity and file-scope tests after each upgrade, using the release notes and your written scope as the baseline.
  • Your team confirms current Dify API and key behavior against the vendor documentation for your installed version before changes.

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.