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

Open
#4,223 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
48/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
aws, docker, typescript

Research direction

Start by reproducing the request against the local /storage/v1/s3 endpoint with AWS CLI or rclone, then trace how the Kong proxy handles the public Host and path. Compare the client’s canonical request with the request reaching Storage; done means identifying the rewrite or confirming the limitation and documenting a supported endpoint or local-development workflow.

Written by the indexing model from the issue text.

Description

🐛 Bug supabase/cli

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)?
Dominant language
TypeScript
Stars
2.4k
Forks
523
Avg merge
20h 47m
Merged PRs (30d)
243

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from supabase/cli

All issues in supabase/cli

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.