g7 — Object Storage/Managing Buckets

Managing Buckets

Buckets are the top-level containers in g7. Each bucket holds objects identified by string keys. Buckets are scoped to your account — two different accounts can both have a bucket named uploads without conflict, but within your account each bucket name must be unique.


Create a bucket

ribo bucket create <name>

Bucket name rules:

  • 3–49 characters
  • Lowercase letters, numbers, and hyphens only — no underscores
  • Must start and end with a letter or number
ribo bucket create avatars
ribo bucket create raw-uploads
ribo bucket create processed-images

Buckets are private by default. Pass --public to allow anonymous GET/HEAD on the bucket's objects (see Public access and external clients below).


List buckets

ribo bucket list
avatars
raw-uploads
processed-images

List objects in a bucket

ribo bucket ls <name>

List the objects stored in a bucket with their sizes.

ribo bucket ls avatars
portraits/alice.jpg    24601
portraits/bob.png      38912
thumbnails/alice.jpg   4096

Upload, download, and sync files

You don't need an S3 client to move files in and out of a bucket — ribo does it directly. One side of each command is a local path, the other a bucket:key reference; the direction is inferred from which side carries the bucket: prefix.

# copy a single file up or down
ribo bucket cp ./photo.jpg avatars:portraits/alice.jpg
ribo bucket cp avatars:portraits/alice.jpg ./alice.jpg

# copy a whole tree (-r)
ribo bucket cp -r ./dist site-assets:site/
ribo bucket cp -r site-assets:site/ ./restore

# one-way sync (transfers only missing/changed files)
ribo bucket sync ./dist site-assets:site/ --delete

# delete an object, or every object under a prefix
ribo bucket rm avatars:portraits/alice.jpg
ribo bucket rm -r avatars:thumbnails/

sync skips files that are unchanged (same size and content), making it ideal for pushing build output or pulling backups. See the ribo CLI reference for the full flag list.


Delete a bucket

ribo bucket drop <name>

This removes the bucket and all objects inside it. This is irreversible.

ribo bucket drop old-uploads

Public access and external clients

Cell bindings are the primary way to use a bucket, but not the only one:

Public-read buckets. Create a bucket with --public, or toggle an existing one:

ribo bucket create avatars --public
ribo bucket set avatars --public     # or --private to revert

Anonymous clients can then GET/HEAD the bucket's objects through the public g7 endpoint at https://g7.tissue.systems (object URLs use the bucket's account-namespaced storage name — a pre-signed URL shows the full form). Public-read only ever applies to object reads — listing, writes, and deletes always require credentials.

Pre-signed URLs. The management API can mint a short-lived signed URL for a single upload or download (POST /v1/buckets/:bucket/presign) — useful for handing a browser or external service one-off access without sharing credentials.

S3-compatible endpoint. https://g7.tissue.systems accepts SigV4-signed requests with per-bucket credentials, so standard S3 tooling can read and write buckets directly.


Binding a bucket to a Cell

Once a bucket exists, declare it in ribo.toml:

[[bindings]]
type    = "g7"
binding = "AVATARS"
bucket  = "avatars"

The binding name becomes a property on env inside the Cell (env.AVATARS). See the g7 API Reference for how to use it.


Automatic bucket creation for FILES bindings

When you use a files binding, ribo automatically creates a dedicated bucket during ribo deploy. You do not need to create it manually:

[[bindings]]
type    = "files"
binding = "ASSETS"
dir     = "./public"

ribo creates a bucket named after your Cell's address and the binding name, then uploads the directory contents. The bucket is owned by your account and persists across redeploys.


See also