Skip to content

send_email Auth Hook does not attach Authorization header despite signing secret being configured #2499

@marshallwells23

Description

@marshallwells23

Here's the filled-out report:


  • I confirm this is a bug with Supabase, not with my own application.
  • I confirm I have searched the Docs, GitHub Discussions, and Discord.

Describe the bug

When a signing secret is configured for the send_email Auth Hook (Authentication → Hooks → HTTPS endpoint), Supabase does not attach an Authorization: Bearer <jwt> header to outgoing hook requests. The secret is visible and confirmed saved in the dashboard, but the hook is called unsigned on every invocation.

To Reproduce

  1. Go to Authentication → Hooks → Add hook → Send Email hook
  2. Set an HTTPS endpoint URL
  3. Set a signing secret (using the v1,whsec_<base64> format shown in the Supabase docs)
  4. Save the hook
  5. Trigger a password recovery email for an existing user
  6. Inspect the incoming request at your hook endpoint - the Authorization header is absent

Expected behavior

Every hook request includes Authorization: Bearer <hs256-signed-jwt>, signed with the configured secret, as described in the Auth Hooks documentation.

Actual behavior

No Authorization header is present. Server-side logs confirm:

authHeader present: false, len: 0

GoTrue's own logs show 500: Hook requires authorization token - this is the GoTrue error generated when the hook endpoint returns 401 due to the missing header.

Bypassing signature verification at the hook endpoint confirms the rest of the pipeline (payload parsing, email delivery) works correctly. The issue is solely that the Authorization header is never attached.

Screenshots

N/A

System information

  • OS: macOS
  • Browser: N/A (server-to-server hook call)
  • Version of supabase-js: N/A (this is a server-side Auth Hook, not client SDK)
  • Node.js: 24.x (Vercel serverless function receiving the hook)

Additional context

  • The signing secret in the Supabase dashboard and the server-side env var are confirmed identical (matched by prefix and length in logs)
  • The hook is called by GoTrue (User-Agent: Go-http-client/2.0) - the request arrives, just unsigned
  • Auth Hooks are currently labeled BETA in the Supabase dashboard
  • Workaround: accept requests without auth header and log a warning - email delivery then works end-to-end

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions