DX-2969: add Blob commands - #17
Open
ytkimirti wants to merge 1 commit into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Adds first-class Upstash Blob bucket management to
@upstash/cliand gives agents a simple bridge into Blob's S3-compatible data plane.The CLI manages buckets through the Upstash Developer API. For object operations, it returns short-lived, bucket-scoped S3 credentials rather than reimplementing upload, download, list, copy, multipart, and signing behavior. Agents can use those credentials with AWS CLI, rclone, or any S3 SDK they already understand.
Command reference
upstash blob createupstash blob listupstash blob getupstash blob credentialsupstash blob deleteAccount-level commands use the CLI's existing authentication flow:
upstash login,UPSTASH_EMAILplusUPSTASH_API_KEY, or the global credential flags.Create a bucket
Create a private bucket:
Create a public bucket:
Allow specific browser origins at creation time:
The command prints the created bucket as JSON. Create responses include the initial
tokenandtoken_nextvalues, so an agent can immediately connect to the bucket.Blob currently has no CLI region or plan option, because those are not part of the Blob bucket API.
List buckets
This prints the account's buckets as a JSON array. The list endpoint intentionally does not return
tokenortoken_next, making it safe for inventory and discovery workflows.A simple way to select a bucket ID by name:
BUCKET_ID=$(upstash blob list | jq -r '.[] | select(.name == "uploads") | .id')Get a bucket
Get complete bucket details, including the current and next bucket tokens:
upstash blob get --bucket-id "$BUCKET_ID"Hide both token fields when output will be logged, copied, or shared:
upstash blob get --bucket-id "$BUCKET_ID" --hide-credentials--hide-credentialsremoves the fields locally before printing. It does not depend on an unsupported API query parameter.Get temporary S3 credentials
When account credentials are available, the CLI fetches the current bucket token through the Developer API and exchanges it for temporary S3 credentials:
upstash blob credentials --bucket-id "$BUCKET_ID"The JSON response contains:
{ "accessKeyId": "...", "secretAccessKey": "...", "sessionToken": "...", "endpoint": "https://<account>.r2.cloudflarestorage.com", "bucket": "<bucket-id>", "region": "auto", "expiresAt": 1234567890 }expiresAtis the authoritative Unix expiry. The credentials are short-lived and scoped to one bucket.If an agent only has a bucket token, it can use the standard Blob environment variable without Developer API account credentials:
UPSTASH_BLOB_TOKEN="$TOKEN" upstash blob credentialsThere is deliberately no
--tokenoption because secrets passed as command-line arguments can leak into shell history and process listings.Use the credentials with AWS CLI
The same response works with rclone or an S3 client library.
Delete an empty bucket
Preview the action without resolving authentication or sending a request:
upstash blob delete --bucket-id "$BUCKET_ID" --dry-runExample preview:
{ "action": "delete", "bucket_id": "...", "dry_run": true }Delete the bucket after all objects have been removed:
upstash blob delete --bucket-id "$BUCKET_ID"The CLI intentionally does not recursively delete objects. The Developer API refuses deletion of a non-empty bucket, preventing a bucket-management command from silently becoming a destructive object purge.
Credential safety and failure handling
https://blob.upstash.io/v1/credentials.r2.cloudflarestorage.com429and503responses use bounded retries withRetry-AftersupportScope
This PR intentionally does not add Blob object commands or a new runtime dependency. There is no local SigV4 implementation and no AWS SDK dependency. Once credentials are returned, the existing S3 ecosystem handles object operations better and is already familiar to coding agents.
Advanced control-plane operations such as rename, token rotation, visibility updates, CORS updates, and usage stats can be added separately without complicating this initial workflow.
Testing
Unit coverage includes:
UPSTASH_BLOB_TOKENauthentication flows429and503retriesVerification performed:
The opt-in live lifecycle test passed against the real APIs. It creates a private bucket, verifies list/get, waits for provisioning, obtains working temporary S3 credentials, and deletes the empty bucket with bounded cleanup retries.
Linear: https://linear.app/upstash/issue/DX-2969/cli-blob