Skip to content

Local Storage TUS rejects signed upload token generated by the same stack with "Invalid Compact JWS" #1268

Description

@tmprrodrigues

Summary

createSignedUploadUrl generates a signed upload token in a clean local Supabase stack. The token is structurally a valid three-segment compact JWS using HS256, but the initial TUS request is rejected with Invalid Compact JWS.

The same result occurs through the local API gateway and directly against the Storage container. The reproducer contains no application code.

The attached results were captured during an earlier isolated diagnostic run. This package-preparation pass did not re-run the matrix.

Environment

  • Windows x64
  • Docker 29.6.2
  • Bun 1.3.14
  • Node 24.18.0
  • Supabase CLI 2.109.1
    • storage-api v1.62.5
    • image digest 1dbe962d9862ef12e20357f9d7ba5431989c1daf4a556d6cb20ee4efd1c57320
  • Supabase CLI 2.109.0
    • storage-api v1.61.7
    • image digest 7dae5013474c1b5f816d138605e33434d83b87df1716032cf588a15561dcd937

Reproduction

  1. Start a clean isolated local stack using one of the exact CLI versions.
  2. Create a private bucket through the official Storage API.
  3. Call createSignedUploadUrl for a random temporary object.
  4. Verify only that the token is a decodable three-segment compact JWS with alg = HS256.
  5. Send the initial resumable upload request with standard TUS metadata, x-signature, and x-upsert: false.
  6. Observe HTTP 400 and Invalid Compact JWS.
  7. Send the same request and token directly to the Storage container through stdin.
  8. Observe the same result.

Relevant files:

  • src/reproduce.ts
  • src/run-cli-matrix.ts
  • src/sanitize.ts
  • src/verify-no-secrets.ts

Minimal reproduction command

bun install --frozen-lockfile
bun run matrix
bun run verify

An optional trusted CA file can be supplied with --cafile <path-to-trusted-ca.pem> when local HTTPS inspection is enabled.

Expected behavior

The initial TUS request should accept the signed upload token generated by the same local Storage stack and create a resumable upload session with a session location.

Actual behavior

During the earlier isolated diagnostic run:

  • Gateway: HTTP 400, Invalid Compact JWS / invalid_compact_jws
  • Direct Storage container: HTTP 400, Invalid Compact JWS / invalid_compact_jws
  • No TUS session was created

Control observations

  • The token was a compact JWS.
  • It contained three segments.
  • The protected header was decodable.
  • The reported algorithm was HS256.
  • The same local stack generated and rejected the token.
  • Direct-container control rules out the gateway as the exclusive cause.
  • No token transformation, manually generated signature, public bucket, upsert, policy change, or JWT-validation workaround was used.

Version matrix

CLI storage-api Digest SHA-256 Gateway Direct container TUS session
2.109.1 v1.62.5 1dbe962d9862ef12e20357f9d7ba5431989c1daf4a556d6cb20ee4efd1c57320 HTTP 400, invalid_compact_jws HTTP 400, invalid_compact_jws not created
2.109.0 v1.61.7 7dae5013474c1b5f816d138605e33434d83b87df1716032cf588a15561dcd937 HTTP 400, invalid_compact_jws HTTP 400, invalid_compact_jws not created

Security

No token, local key, signed URL, object path, connection string, or production data is attached. The reproducer uses only isolated local stacks and temporary private buckets.

Additional context

CLI 2.109.1 was the latest stable official release observed during preparation. CLI 2.109.0 was the immediately previous stable release tested.

The behavior blocks local TUS integration tests. This report does not claim that hosted Supabase is affected and does not assume an internal cause.

Could you confirm whether this is a Storage bug or an incompatible local-stack configuration, and advise which local CLI/Storage combination should accept its own signed upload token?

Reproducer

A sanitized minimal reproducer package is available on request. It contains the two-version matrix, the minimal Storage/TUS request, sanitization and secret-verification scripts, historical validated results, and security notes.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions