Skip to content

SignatureVerifier raises ValueError on an empty signing_secret (regression in 3.43.0), breaking apps constructed without a signing secret (e.g. Bolt Socket Mode) #1903

Description

@rlaneth

Reproducible in:

The Slack SDK version

slack_bolt==1.28.0
slack_sdk==3.43.0

(The code that breaks under slack_sdk==3.43.0 works with slack_sdk==3.42.0.)

Python runtime version

Python 3.13.5

OS info

# Linux (sw_vers is macOS-only):
Linux 6.12.94+deb13-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.94-1 (2026-06-20) x86_64
Debian GNU/Linux 13 (trixie)

Steps to reproduce:

As of slack_sdk==3.43.0, SignatureVerifier.signing_secret became a property whose setter rejects an empty value, so simply constructing a SignatureVerifier with an empty secret raises. This is a behavior change from 3.42.0 (where construction with an empty secret was allowed), shipped in what looks like a patch/minor release.

  1. Minimal, SDK-only reproduction:

    from slack_sdk.signature import SignatureVerifier
    
    SignatureVerifier(signing_secret="")  # raises in 3.43.0; OK in <= 3.42.0
    Traceback (most recent call last):
      ...
      File ".../slack_sdk/signature/__init__.py", line 29, in __init__
        self.signing_secret = signing_secret
        ^^^^^^^^^^^^^^^^^^^
      File ".../slack_sdk/signature/__init__.py", line 41, in signing_secret
        raise ValueError("signing_secret must not be empty.")
    ValueError: signing_secret must not be empty.
    
  2. Real-world impact via slack_bolt (Socket Mode). A Socket Mode app receives events over a WebSocket and has no HTTP request signature to verify, so it is commonly constructed without a signing secret. App/AsyncApp default request_verification_enabled=True and resolve the secret to "" when none is provided (or SLACK_SIGNING_SECRET is unset), then eagerly build RequestVerification(SignatureVerifier(self._signing_secret)) during __init__. With slack_sdk==3.43.0 this now crashes at construction:

    import os
    os.environ.pop("SLACK_SIGNING_SECRET", None)
    
    from slack_bolt import App
    App(token="xoxb-...")  # raises: ValueError: signing_secret must not be empty.
    
    from slack_bolt.app.async_app import AsyncApp
    AsyncApp(token="xoxb-...")  # same

    Both the sync App and async AsyncApp are affected. The same code paths work unchanged with slack_sdk==3.42.0.

  3. Because most projects pin Slack libraries loosely (e.g. slack-sdk>=3.42), a fresh build/install silently picks up 3.43.0 and a previously-working Socket Mode service fails to start with no code change on the user's side.

Expected result:

Constructing a SignatureVerifier (and, transitively, a Bolt App/AsyncApp without a signing secret) should not raise at construction time, preserving <= 3.42.0 behavior. Request-signature validation is only meaningful when a request is actually verified, so an empty/absent secret could be tolerated at construction and surfaced only if/when verification is attempted (or this guard should ship as a clearly-documented breaking change with an appropriate version bump and migration note).

Actual result:

SignatureVerifier.__init__ raises ValueError: signing_secret must not be empty. as soon as it is instantiated with an empty secret. This breaks any downstream code that constructs it without a secret — most notably Bolt Socket Mode apps, which build the request-verification middleware eagerly and have no use for signature verification.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

questionM-T: User needs support to use the project

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions