Core Concepts

Before diving into individual features, it helps to have the right mental model for what s3BEAR actually is and how its pieces fit together.

The single gated door

s3BEAR sits in front of any backend that exposes an S3-compatible API. AWS S3, MinIO, Ceph, and Wasabi are examples rather than an exhaustive provider list. s3BEAR acts as the single gated access path to it. Nothing — not a browser, not an LLM provider, not an external partner — talks to the underlying storage directly. Every request, whether it comes from your own frontend or an unauthenticated GET from a share link, passes through s3BEAR's permission checks first.

Why it matters: instead of every service re-implementing auth, MIME checking, and presigned-URL logic against S3 directly, you get one consistent enforcement point for the whole organization.

Private by default

The S3 bucket itself is never made public. There are no bucket ACL changes, no public-read policies. s3BEAR decides access at the application layer — per user, per share link, per request — while the bucket stays private at the storage level. Even a tokenized public share link doesn't change anything on the S3 side; s3BEAR validates the token and streams the object through itself.

Three roles

s3BEAR's capabilities fall into three roles:

  1. LLM-ready public hosting — expose private objects as expiring, revocable HTTPS URLs suitable for multimodal LLM inputs (Claude, GPT-4o, Gemini). See LLM Integration.
  2. Authenticated image serving — serve images from private buckets to the browser, with per-user permission checks and on-the-fly transforms (resize, re-encode). See Image Serving.
  3. S3 management console — manage buckets, objects, permissions, quotas, and cleanup policies from the web UI or API.

Share tokens

A share token turns one object into a tokenized, expiring, revocable HTTPS URL without touching the S3 bucket's ACLs. Tokens are:

  • Expiring — choose 1h / 24h / 7d / 30d, a custom duration, or never (permanent until revoked).
  • Revocable — an admin or the creator can revoke a link at any time.
  • Hashed at rest — the raw token is stored as a SHA-256 hash; the raw value is shown only once, at creation.

An expired, revoked, or unknown token always returns 410 Gone — the response never reveals whether the underlying object exists. See Share Links for the full API and use cases.

Groups & permissions

Users belong to one or more groups. Each group holds a list of bucket permissions, where each permission pairs a glob bucket pattern (matched with *, ?, [seq]) with four boolean flags: can_list, can_read, can_write, can_delete.

A user's effective permission for a given bucket is the union of every matching permission across all of their groups — if any group grants write on a matching pattern, the user has write. Admin users bypass all permission checks entirely.

Why it matters: naming buckets by convention (<team>-*) means new buckets created inside a team's namespace are automatically covered by existing group permissions — no manual grant per bucket.

See Permissions for the full model and worked examples.

s3BEAR exposes images to the outside world through two distinct paths:

Image proxyShare link
AuthJWT (authenticated)Tokenized, no auth
AudienceYour logged-in users / frontendAnyone with the URL (LLM providers, partners)
LifetimeUntil permissions changeExpires / revocable
Use caseIn-app previews, dashboardsLLM image inputs, external embeds

Both support the same on-the-fly transform query params (w, h, format, q, fit). See Image Serving and Share Links for details.

Data plane

Two stores back everything above:

  • S3-compatible storage — holds the actual objects. s3BEAR never buffers large uploads through itself; big files move browser-to-storage directly via presigned URLs.
  • PostgreSQL — holds everything that isn't an object: users, groups, permission policies, audit log entries, share links, and webhook configuration/delivery history.

Next steps

  • Architecture — how the client, backend, and data plane fit together, request-by-request.
  • Quick Start — run s3BEAR locally in about a minute.