cli icon indicating copy to clipboard operation
cli copied to clipboard

403 SignatureDoesNotMatch when hitting Supabase CLI Storage via tunnel (/storage/v1/s3 with rclone/awscli)

Open NickAnthony opened this issue 3 months ago • 1 comments

Describe the bug

When accessing the Supabase CLI’s S3-compatible Storage endpoint through a public tunnel, every SigV4 request returns 403 SignatureDoesNotMatch. The client signs Host=<public-host> and path=/storage/v1/s3, but responses consistently include Via: kong, suggesting the local proxy rewrites host/path so the storage signer computes a different canonical request.

To Reproduce

  1. Start Supabase CLI (local dev stack) so Storage is available at http://localhost:54123/storage/v1/s3 and create S3 Access/Secret keys from supabase status.
  2. Expose the port publicly using any of:
    • ngrok (with host header preservation), Cloudflare Tunnel, or Tailscale Funnel.
    • The public URL looks like https:///storage/v1/s3
  3. Configure rclone:
[supabase]
type = s3
provider = Minio
endpoint = https://<public-host>/storage/v1/s3
region = us-east-1        # also tried: local
force_path_style = true
v2_auth = false
access_key_id = ****
secret_access_key = ****

  1. Create an empty bucket, e.g., memory-filesystem, then run:
  • rclone -vv --dump headers --dump bodies lsd supabase:memory-filesystem
  • aws --debug --endpoint-url https:///storage/v1/s3 --region us-east-1 s3 ls
  1. Both return 403 SignatureDoesNotMatch.

Expected behavior

SigV4 verification should succeed when the client signs Host= and canonical URI=/storage/v1/s3; listing a bucket should return 200 OK (or a normal empty listing), not 403.

System information

  • Version of OS: macOS 14 (darwin 24.6.0)

  • Version of CLI: supabase 2.45.5

  • Version of Docker: Docker version 28.4.0, build d8eb465

  • Version of Docker Compose: Docker Compose version v2.39.2-desktop.1

  • Other client tools: rclone v1.60.1 (Debian build), awscli 1.42.40 (botocore 1.40.40)

  • Versions of services (supabase services):

    SERVICE IMAGE LOCAL
    supabase/postgres 15.8.1.085
    supabase/gotrue v2.179.0
    postgrest/postgrest v13.0.7
    supabase/realtime v2.51.3
    supabase/storage-api v1.27.4
    supabase/edge-runtime v1.69.12
    supabase/studio 2025.09.22-sha-7b3007d
    supabase/postgres-meta v0.91.6
    supabase/logflare 1.22.3
    supabase/supavisor 2.7.0

Additional context

  • Tunnels tried: ngrok (with --host-header preserve), Cloudflare Quick Tunnel, Tailscale Funnel. All produce the same failure.
  • Regions tried: local and us-east-1. Provider tried: Minio. force_path_style=true.
  • Keys: using “S3 Access Key/Secret Key” from supabase status (not service role/JWT). Keys are not included here.

AWS CLI debug

CanonicalRequest:
GET
/storage/v1/s3

host:<public-host>
x-amz-content-sha256:e3b0c442...
x-amz-date:20250928T191635Z

host;x-amz-content-sha256;x-amz-date
e3b0c442...

HTTP/2.0 403 Forbidden
Content-Type: application/xml; charset=utf-8
Via: kong/2.8.1
<Error><Code>SignatureDoesNotMatch</Code>...</Error>

Observation / hypothesis

Because every response contains Via: kong and fails with SignatureDoesNotMatch, it appears the local proxy may be rewriting the request (e.g., stripping or reshaping the /storage/v1/ prefix or altering Host) before the storage service verifies SigV4, causing a canonical URI mismatch.

Questions

  • What’s the recommended way for external clients to reach the Supabase CLI Storage S3 endpoint with SigV4 so the signer sees the same Host and canonical URI? Is /storage/v1/s3 intended to be signed as-is?
  • Is there a documented way to bypass Kong locally (non‑proxied storage endpoint) so we can target the storage S3 gateway directly?
  • If this is a known limitation of the local stack, what configuration or workflow do you recommend for local development (e.g., using a hosted project endpoint or alternative local endpoint)?

NickAnthony avatar Sep 29 '25 13:09 NickAnthony

Hi!, did you find some workaround for this?

rrbarrero avatar Nov 13 '25 11:11 rrbarrero