[RFE] Allow users to sign and verify difypkg files with their own key pairs. #48

Closed
opened 2026-02-16 00:19:23 -05:00 by yindo · 4 comments
Owner

Originally created by @kurokobo on GitHub (Mar 18, 2025).

In the current implementation, signature verification for difypkg can only be performed with the public key embedded in the executable of the daemon. Only difypkg files signed with Dify's private key are currently supported.

Therefore, if someone wants to introduce a self-developed plugin in their self-hosted environment at a company, they have no choice but to set FORCE_VERIFYING_SIGNATURE to false. However, this poses the risk of allowing the installation of unsafe unauthorized plugins.

I believe supporting the following scenarios would be especially useful in enterprise environments and beneficial not only for users of the free community edition but also for enterprise edition users.

  • Easy issuance of key pairs (this already can be done with cmd/license if we mamually build it)
  • Ability to sign difypkg with any private key (this already can be done with cmd/license if we mamually build it)
  • Specify the path of any public key through environment variables
  • Verify signatures using both the public key for the official marketplace and the public key specified through environment variables
  • Allow installation of the plugin if the signature is verified with any of the public keys
Originally created by @kurokobo on GitHub (Mar 18, 2025). In the current implementation, signature verification for `difypkg` can only be performed with the public key embedded in the executable of the daemon. Only `difypkg` files signed with Dify's private key are currently supported. Therefore, if someone wants to introduce a self-developed plugin in their self-hosted environment at a company, they have no choice but to set `FORCE_VERIFYING_SIGNATURE` to `false`. However, this poses the risk of allowing the installation of unsafe unauthorized plugins. I believe supporting the following scenarios would be especially useful in enterprise environments and beneficial not only for users of the free community edition but also for enterprise edition users. - Easy issuance of key pairs (this already can be done with `cmd/license` if we mamually build it) - Ability to sign `difypkg` with any private key (this already can be done with `cmd/license` if we mamually build it) - Specify the path of any public key through environment variables - Verify signatures using both the public key for the official marketplace and the public key specified through environment variables - Allow installation of the plugin if the signature is verified with any of the public keys
yindo closed this issue 2026-02-16 00:19:23 -05:00
Author
Owner

@Yeuoly commented on GitHub (Mar 20, 2025):

I agree, it makes sense to allowing users to specific their own private key, but It's hard to make sure the safety of plugins, for personal use and company self-deployed use, they may want a keychains, use different key to verify different plugins, maybe a folder named .keychains? how do you think of it

@Yeuoly commented on GitHub (Mar 20, 2025): I agree, it makes sense to allowing users to specific their own private key, but It's hard to make sure the safety of plugins, for personal use and company self-deployed use, they may want a keychains, use different key to verify different plugins, maybe a folder named .keychains? how do you think of it
Author
Owner

@kurokobo commented on GitHub (Mar 22, 2025):

@Yeuoly
Thanks for your feedback!

If the daemon unconditionally trusts all keys within a specific folder like .keychains/*.pem, it could lead to issues where unintended keys are trusted due to user error or some malicious attack. As the first step, wouldn't it suffice to specify the paths of the trusted key files as a semicolon-separated list in an environment variable?

Below are implementation ideas.

Step 1: Add a feature to the existing dify-plugin CLI to generate key pairs and sign difypkg file using the specified private key as an argument.

Step 2: Add a feature to the daemon to verify signatures using the list of public keys specified by an environment variable.

Step 3: Once it has been confirmed that the features up to Step 2 are sufficiently effective, enable management of trusted public keys for each workspace through a web GUI as part of the workspace management functionality. The public keys will be registered in the database.

@kurokobo commented on GitHub (Mar 22, 2025): @Yeuoly Thanks for your feedback! If the daemon unconditionally trusts all keys within a specific folder like `.keychains/*.pem`, it could lead to issues where unintended keys are trusted due to user error or some malicious attack. As the first step, wouldn't it suffice to specify the paths of the trusted key files as a semicolon-separated list in an environment variable? Below are implementation ideas. Step 1: Add a feature to the existing `dify-plugin` CLI to generate key pairs and sign difypkg file using the specified private key as an argument. Step 2: Add a feature to the daemon to verify signatures using the list of public keys specified by an environment variable. Step 3: Once it has been confirmed that the features up to Step 2 are sufficiently effective, enable management of trusted public keys for each workspace through a web GUI as part of the workspace management functionality. The public keys will be registered in the database.
Author
Owner

@benjamin-mogensen commented on GitHub (Mar 23, 2025):

I have previously worked with application signing and Microsoft and Apple has some more rigorous processes in place that ensure trusted software. This involves both signing with a trusted certificate issued by a trusted provider as well as notarization where you upload your software to them for scanning and if they approve your app is fully notarized and can then be made available in their App Store. Now, this process is quite complex and I am not sure if Dify would go down that kind of route and maybe this would also only be applicable to the public cloud version of Dify and not so much for self hosted one.

I do think that if running enterprise edition we could allow install of unsigned plugins and at the same time only allow admins to install plugins that way the security risk of malicious code is minimized IMO.

@benjamin-mogensen commented on GitHub (Mar 23, 2025): I have previously worked with application signing and Microsoft and Apple has some more rigorous processes in place that ensure trusted software. This involves both signing with a trusted certificate issued by a trusted provider as well as notarization where you upload your software to them for scanning and if they approve your app is fully notarized and can then be made available in their App Store. Now, this process is quite complex and I am not sure if Dify would go down that kind of route and maybe this would also only be applicable to the public cloud version of Dify and not so much for self hosted one. I do think that if running enterprise edition we could allow install of unsigned plugins and at the same time only allow admins to install plugins that way the security risk of malicious code is minimized IMO.
Author
Owner

@kurokobo commented on GitHub (Mar 23, 2025):

@Yeuoly
I have implemented Step 1 and Step 2 from my above comment as a proof of concept and created a draft PR: https://github.com/langgenius/dify-plugin-daemon/pull/137.
I would appreciate it if you (or of course anyone here!) could try it out if possible.

New sub commands for CLI

Ready-to-Use binaries: https://github.com/kurokobo/dify-plugin-daemon/releases/tag/0.0.6%2Bsignature%2Bp02

# generate new key pair with specified name; 
dify-plugin signature generate -f myorg

# sign existing difypkg with specified private key
dify-plugin signature sign ./mypkg.difypkg -p myorg.private.pem

# verify existing difypkg with both official public key and specified public key (for testing purpose)
dify-plugin signature verify ./mypkg.difypkg -p myorg.public.pem

New environment variables for daemon

Ready-to-Use container images: https://github.com/kurokobo/dify-plugin-daemon/pkgs/container/dify-plugin-daemon

# Enable or disable third-party signature verification for plugins
# Set to "true" to allow verification using additional public keys specified in THIRD_PARTY_SIGNATURE_VERIFICATION_PUBLIC_KEYS
THIRD_PARTY_SIGNATURE_VERIFICATION_ENABLED=false

# A comma-separated list of file paths to public keys in addition to the official public key for signature verification
THIRD_PARTY_SIGNATURE_VERIFICATION_PUBLIC_KEYS=

Example Configuration Steps

For Self-Hosted Dify 1.0+ only. Not applicable for Cloud edition.

  1. Download executable dify-plugin binary from the release page of forked demo project
  2. Prepare your own difypkg file by dify-plugin plugin package command
  3. Generate new key pair for signing and verification
    dify-plugin signature generate -f myorg
    
    • This step will generate myorg.private.pem and myorg.public.pem
  4. Sign your difypkg with myorg.private.pem
    dify-plugin signature sign my-custom-plugin.difypkg -p myorg.private.pem
    
    • This step will generate my-custom-plugin.signed.difypkg
  5. You can verify signature of difypkg by verify command
    dify-plugin signature verify my-custom-plugin.signed.difypkg -p myorg.public.pem
    
  6. Create new directory public_keys under your docker/volumes/plugin_daemon
  7. Place your myorg.public.pem (Public Key) under docker/volumes/plugin_daemon/public_keys
  8. Place docker-compose.override.yaml file with following content, on the next to your docker-compose.yaml
    services:
      plugin_daemon:
        image: ghcr.io/kurokobo/dify-plugin-daemon:0.0.6-signature-p02-local
        environment:
          FORCE_VERIFYING_SIGNATURE: true
          THIRD_PARTY_SIGNATURE_VERIFICATION_ENABLED: true
          THIRD_PARTY_SIGNATURE_VERIFICATION_PUBLIC_KEYS: /app/storage/public_keys/myorg.public.pem
    
  9. Start your Dify and try installing my-custom-plugin.signed.difypkg.
@kurokobo commented on GitHub (Mar 23, 2025): @Yeuoly I have implemented Step 1 and Step 2 from my above comment as a proof of concept and created a draft PR: https://github.com/langgenius/dify-plugin-daemon/pull/137. I would appreciate it if you (or of course anyone here!) could try it out if possible. ### ✨ New sub commands for CLI **Ready-to-Use binaries**: https://github.com/kurokobo/dify-plugin-daemon/releases/tag/0.0.6%2Bsignature%2Bp02 ```bash # generate new key pair with specified name; dify-plugin signature generate -f myorg # sign existing difypkg with specified private key dify-plugin signature sign ./mypkg.difypkg -p myorg.private.pem # verify existing difypkg with both official public key and specified public key (for testing purpose) dify-plugin signature verify ./mypkg.difypkg -p myorg.public.pem ``` ### ✨ New environment variables for daemon **Ready-to-Use container images**: https://github.com/kurokobo/dify-plugin-daemon/pkgs/container/dify-plugin-daemon ```bash # Enable or disable third-party signature verification for plugins # Set to "true" to allow verification using additional public keys specified in THIRD_PARTY_SIGNATURE_VERIFICATION_PUBLIC_KEYS THIRD_PARTY_SIGNATURE_VERIFICATION_ENABLED=false # A comma-separated list of file paths to public keys in addition to the official public key for signature verification THIRD_PARTY_SIGNATURE_VERIFICATION_PUBLIC_KEYS= ``` ### ✨ Example Configuration Steps For Self-Hosted Dify 1.0+ only. Not applicable for Cloud edition. 1. Download executable `dify-plugin` binary from [the release page of forked demo project](https://github.com/kurokobo/dify-plugin-daemon/releases/tag/0.0.6%2Bsignature%2Bp02) - This is built by GHA, you can review [the build logs](https://github.com/kurokobo/dify-plugin-daemon/actions) and [its source code](https://github.com/kurokobo/dify-plugin-daemon/tree/sign-demo) 2. Prepare your own difypkg file by `dify-plugin plugin package` command 3. Generate new key pair for signing and verification ```bash dify-plugin signature generate -f myorg ``` - This step will generate `myorg.private.pem` and `myorg.public.pem` 4. Sign your difypkg with `myorg.private.pem` ```bash dify-plugin signature sign my-custom-plugin.difypkg -p myorg.private.pem ``` - This step will generate `my-custom-plugin.signed.difypkg` 5. You can verify signature of difypkg by `verify` command ```bash dify-plugin signature verify my-custom-plugin.signed.difypkg -p myorg.public.pem ``` 5. Create new directory `public_keys` under your `docker/volumes/plugin_daemon` 7. Place your `myorg.public.pem` (Public Key) under `docker/volumes/plugin_daemon/public_keys` 8. Place `docker-compose.override.yaml` file with following content, on the next to your `docker-compose.yaml` ```yaml services: plugin_daemon: image: ghcr.io/kurokobo/dify-plugin-daemon:0.0.6-signature-p02-local environment: FORCE_VERIFYING_SIGNATURE: true THIRD_PARTY_SIGNATURE_VERIFICATION_ENABLED: true THIRD_PARTY_SIGNATURE_VERIFICATION_PUBLIC_KEYS: /app/storage/public_keys/myorg.public.pem ``` 9. Start your Dify and try installing `my-custom-plugin.signed.difypkg`.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify-plugin-daemon#48