Skip to content

Changelog

Each version release produces all three artifacts from the same v* tag:

  • Docker imagestephenjr002/sairo:X.Y.Z on Docker Hub
  • Helm chart — published to oci://registry-1.docker.io/stephenjr002/sairo-helm
  • CLI binaries — on GitHub Releases and via brew install ashwathstephen/sairo/sairo

OpenID Connect SSO + a real per-bucket access UI (issue #9)

  • Generic OIDC single sign-on — works with any compliant provider (Keycloak, Authentik, Okta, Auth0, Microsoft Entra ID, Google, Dex, …). Auto-discovers endpoints, fully validates the ID token (JWKS signature, iss/aud/exp/azp, nonce), and protects the flow with state + nonce + PKCE. Only the username is synced — new users are viewers with no access until an admin grants it. Confidential or public client. See SSO setup.
  • Optional group→role mapping, verified-email and email-domain restrictions, and RP-initiated single logout — all opt-in.
  • Per-bucket access management UI — auth-source badges (Local / SSO / LDAP / OAuth), a bucket-grant count, and a Manage access editor (Read / Write / No Access, with search and bulk grant/revoke).
  • Security: federated logins (OIDC/OAuth/LDAP) now go through one hardened path that cannot take over an account owned by a different auth source — notably the local admin. An auth_source is tracked per user.

Anonymous telemetry schema v2 — richer, still privacy-first

  • The heartbeat now also reports instance health (trailing-24h requests/errors, restarts, disk used/total, derived status), activation milestones, and engagement (active buckets, last write, enabled features, update-available). Still aggregate counts + timestamps only — never names, keys, paths, IPs, or content; clamped and < 4 KB.
  • Cadence is now hourly (TELEMETRY_INTERVAL, default 3600s). Fully opt-out via TELEMETRY=false. See Telemetry.

S3-key authentication is scoped per user

  • Fixed (issue #8): In AUTH_MODE=s3, every S3 operation is now performed with the logged-in user’s own keys, so the provider’s IAM scopes exactly what they can see and do. Previously an S3-key user got an unscoped admin session and could see every bucket on every configured endpoint. The user’s keys are kept encrypted in the session token; bucket access is independently enforced per request (the local index can no longer be used to reach a bucket the user’s keys can’t).
  • Fixed: an IDOR where the per-bucket permission check could be skipped by prefixing a request with /api/e/{endpoint}/ — the check now runs on the resolved path, and S3-key sessions are bound to the endpoint they logged into.
  • Existing S3-key users should log in again after upgrading.

Direct browser-to-S3 upload for files of any size (issue #6)

  • Uploads now go directly from the browser to S3 via presigned URLs — small files with a single PUT, large files (> 100 MB) with presigned multipart (parts signed just-in-time, no single-PUT size ceiling). No file data passes through the Sairo server, so large uploads no longer cause memory pressure or pod restarts.
  • The proxy upload path remains as a fallback but now streams to S3 with bounded memory (~100 MB per in-flight file regardless of size; UPLOAD_PROXY_CONCURRENCY, default 3).
  • In-progress uploads can be Stopped, which aborts the multipart upload on S3 to avoid orphaned parts.
  • New tunables: UPLOAD_PROXY_CONCURRENCY, MULTIPART_URL_EXPIRY.

Delta-crawler freshness fixes

  • New partitions are reliably indexed even when they sort beyond the first 1000 siblings; discovery walks all datasets in parallel; natural-sort partition selection (so day=2day=10 picks the true newest); a cooldown prevents back-to-back delta crawls; restart resumes from the existing index instead of re-crawling; the index stays “ready” during crawl transitions.

Performance & freshness at scale

  • Keyset pagination for listings — million-object folders open instantly (first page ~73 ms vs ~1.4 s before).
  • Adaptive crawl scheduler with fast incremental delta crawls that pick up new objects in ~30 s on large buckets, plus a periodic full reconcile.
  • Covering index + covered range scans for folder listings and storage breakdowns (top-level breakdown ~2.5 ms).
  • Direct presigned-PUT uploads (completed in v3.4.0), restart-resumes-from-index, SQLite tuning. New tunables: S3_MAX_POOL_CONNECTIONS, FULL_CRAWL_INTERVAL, LARGE_BUCKET_SECONDS, DELTA_*.

Cost Intelligence, Multipart Cleanup & Optimization Recommendations

  • Cost heatmaps — Per-folder cost breakdown with 13 S3 provider pricing tables
  • Live AWS pricing — Fetched from the AWS Bulk Pricing API with 24-hour cache
  • Provider auto-detect — Automatically identifies your provider from the S3 endpoint URL
  • Storage class comparison — See what your data would cost on Standard, Glacier, Standard-IA, and more
  • Provider selector — Switch between providers to compare costs side-by-side
  • Lifecycle gap analysis — Detects missing expiration rules, no abort-multipart rules, versioning without cleanup
  • Cold data detection — Age distribution by folder with configurable thresholds
  • Duplicate detection — Finds files with identical names and sizes across prefixes
  • Tiering savings — Calculates monthly/annual savings from moving cold data to cheaper storage classes
  • Severity badges — High / Medium / Info recommendations with actionable suggestions
  • Part sizes — Shows size and part count for each incomplete upload
  • Stale vs. active — Uploads older than 24 hours flagged as stale; recent uploads protected
  • Bulk abort — “Abort All Stale” button with confirmation dialog; active uploads untouched
  • Paginated — Handles buckets with 1,000+ incomplete uploads via S3 pagination
  • Insights panel — Consolidated “Storage” and “Optimize” tabs in one modal
  • Lazy loading — Optimization data fetched only when the Optimize tab is clicked
  • Settings page: 24s to 0.3s — Multipart data no longer blocks initial settings load
  • last_modified index — Cold data queries use indexed scans instead of full table scans
  • Lifecycle transitions — Model now supports transition_days and transition_storage_class
  • 6 new providers — DigitalOcean, Hetzner, Scaleway, OVH, iDrive e2, Storj

S3 Access Key Authentication

  • S3 auth modeAUTH_MODE=s3 lets users log in with S3 access key and secret key
  • Login toggle — Sliding pill on the login page to switch between Password and S3 Keys
  • Helm supportauth.mode value in Helm chart

AI Storage Intelligence + Petabyte-Scale Performance

  • MCP Server — Optional sidecar with 26 tools for natural language storage analysis. Connect Claude Desktop, Cursor, or any MCP client.
  • 4 guided workflows — Storage audit, cost optimization, data quality check, incident investigation
  • Security — Input validation (SQL injection, path traversal, prompt injection), per-bucket RBAC, output sanitization
  • Observability — Structured JSON logging, per-tool latency metrics, health endpoints
  • Folder listing: 191,231x faster — Pre-computed prefix_children via SQL, no more 1M-object skip. 311ms → 0.002ms on 2M objects.
  • SQLite PRAGMA tuning — 64MB page cache, 256MB mmap, in-memory temp store
  • Crawl workers: 12 buckets + 16 prefix threads — up from 6 + 4
  • 10K batch inserts — 5x fewer SQLite commits per crawl
  • Async FTS rebuild — Search stays available during index rebuild
  • Sub-prefix splitting — Auto-discovers sub-folders for single-prefix buckets with 500K+ objects
  • 45 backend tests (16 original + 29 scaling)
  • 103 MCP protocol tests (E2E + unit + security)
  • 48 comprehensive live tests against production data
  • Benchmarked on 557K objects / 167 TB (Leaseweb StorageGRID)

A complete rewrite of Sairo with a modern frontend and significantly expanded feature set.

  • Complete rewrite with React 18 and Vite build system
  • Dark mode with system preference detection and manual toggle
  • Virtualized file lists for smooth browsing of large buckets
  • NDJSON streaming for instant rendering of object listings
  • Connect to multiple S3-compatible backends simultaneously
  • Switch between endpoints from the sidebar
  • Fernet-encrypted credential storage for added endpoints
  • Full-text search powered by SQLite FTS5
  • Per-bucket SQLite databases with WAL mode
  • Prefix-parallel crawling for fast initial indexing
  • Background reindexing on a configurable interval
  • Storage analytics dashboard with per-prefix breakdown
  • Storage growth history charts
  • Visual treemap of bucket contents
  • Browse, compare, and restore object versions
  • Version scanner for discovering all versions in a bucket
  • Bulk version deletion
  • Share links for individual files with optional password protection
  • Configurable expiration
  • Public access without authentication
  • Audit logging with 37 tracked action types
  • Two-factor authentication (TOTP) with QR code setup and recovery codes
  • OAuth integration with Google and GitHub
  • LDAP authentication with group-based role mapping
  • API tokens for programmatic access (format: sairo_ prefix + 32 chars)
  • Per-bucket viewer permissions (No Access, Read, Write)
  • Rate limiting (global, login, upload, search)
  • 8 settings tabs: Overview, Lifecycle, Policy, ACL, Tags, CORS, Multipart, Index
  • Visual editors for lifecycle rules, CORS policies, and bucket tags
  • Helm chart for Kubernetes deployments
  • Non-root container (UID 1000, no privilege escalation)
  • Custom branding support (app name, logo, colors, login message)
  • 261 tests across the full stack:
    • 164 end-to-end tests
    • 39 API integration tests
    • 20 indexing tests
    • 16 pytest unit tests
    • 22 Vitest frontend tests