tracebin

Company storage (bring your own S3/R2)

Teams can connect their own S3-compatible bucket. Once connected, artifacts for bins filed under the team land in your bucket instead of tracebin's default storage. Collection links stay on tracebin.dev — only the storage destination changes. Personal bins, and team bins created before your team existed, keep using default storage.

Configuring storage is leader-only, in the Teams page's storage panel.

The fields

  • Endpoint — your provider's S3 API endpoint.
    • Cloudflare R2: https://<account-id>.r2.cloudflarestorage.com
    • AWS S3: https://s3.<region>.amazonaws.com
  • Region — for R2, use auto (the default if left blank). For AWS S3, your bucket's region, e.g. us-east-1.
  • Bucket name — the bucket artifacts should land in. Use a dedicated bucket (see below).
  • Access key ID — the key pair's public half.
  • Secret access key — the private half. Entered once; see "what tracebin stores".

Scope the credentials tightly

Give tracebin a token that can touch only this one bucket, nothing else in your account:

  • R2: create an API token scoped to the specific bucket with Object Read & Write permission.
  • AWS S3: create an IAM user or role whose policy allows s3:PutObject, s3:GetObject, and s3:DeleteObject on arn:aws:s3:::<bucket>/* only.

All three object permissions are needed because connecting runs a live validation: tracebin writes a small test object under _tracebin_validate/, reads it back, and deletes it. If any step fails, nothing is saved and you get the error with the provider's message attached. Granting GetBucketCors as well lets tracebin verify your CORS policy up front, but it is optional — R2 tokens generally can't grant it, and tracebin treats an unverifiable CORS policy as a warning, not a failure.

The CORS requirement

Browser uploads and downloads go directly between the browser and your bucket via signed URLs, so the bucket must allow the tracebin origin. Paste this into the bucket's CORS configuration:

[
  {
    "AllowedOrigins": ["https://tracebin.dev"],
    "AllowedMethods": ["GET", "PUT"],
    "AllowedHeaders": ["*"],
    "ExposeHeaders": ["ETag"],
    "MaxAgeSeconds": 3600
  }
]

This exact policy is also shown in the product when a missing CORS rule is detected. If tracebin can read your CORS config and the origin is missing, connecting fails with the policy to paste. If it can't read the config at all (typical on R2), you get a warning instead and the connection proceeds — a genuinely wrong CORS policy then surfaces later as failed browser uploads.

What tracebin stores — and what it can't show you again

On a successful connection, tracebin stores the endpoint, region, bucket, and access key ID, plus your secret access key encrypted with AES-256-GCM under a server-side key. After that:

  • The secret is never displayed again, in the UI or the API. The settings panel shows only the endpoint, bucket, and the last four characters of the access key ID.
  • The secret is decrypted in exactly one place: at the moment a signed upload or download URL is generated for a run. It is never sent to the customer, the browser, or the collector script — those only ever receive short-lived signed URLs.
  • Re-testing the connection means re-entering the credentials; there is no way to read them back out.

Failure modes during runs

Connection-time validation catches most misconfiguration before it can be saved. What remains:

  • Storage rejects an upload during a customer run — the customer's script prints tracebin: this bin's storage is misconfigured — contact the bin owner and continues with the remaining files. Re-run the storage panel's connection test; the usual causes are a rotated key or a deleted bucket.
  • Wrong CORS that couldn't be verified at connect time — script uploads are unaffected, but browser uploads from the ad-hoc upload page fail. Apply the policy above to the bucket.

Changing or disconnecting

  • Change: submit the form again with new values — the full validation runs again before anything is replaced.
  • Disconnect: removes the stored configuration; subsequent runs for team bins fall back to tracebin's default storage.
  • No data migrates in either direction. Files stay in whichever bucket they were uploaded to, and connecting, changing, or disconnecting storage only affects where new uploads land. Be aware that downloads are signed against the currently configured storage — files uploaded to a bucket you have since disconnected or replaced are still in that bucket, but tracebin can no longer serve download links for them until the same configuration is restored.

Questions: support@tracebin.dev