Skip to main content

Storage support policy

This policy describes storage behavior implemented in the current CaseBender codebase. It does not announce or imply a MinIO retirement date. MinIO remains a supported provider for releases whose release notes include it; any future lifecycle change requires a separately published notice and migration window.

Provider support matrix

“Supported” means the provider implements upload, download, delete, exists, list, metadata, copy, and availability methods behind StorageService. It does not mean every S3-compatible product/version is certified. Record the product version and contract-suite result for each customer deployment.

Configuration contract

Always set STORAGE_PROVIDER explicitly in production. Auto-detection is a developer convenience and must not select a backend during a release rollout.
  • local: STORAGE_PATH=/data
  • minio: MINIO_ENDPOINT is a hostname, MINIO_PORT, MINIO_USE_SSL=true, MINIO_ACCESS_KEY, MINIO_SECRET_KEY, MINIO_BUCKET, optional MINIO_REGION
  • s3: S3_BUCKET, AWS_REGION, optional IAM-provided credentials, optional HTTPS S3_ENDPOINT
  • gcs: GCS_BUCKET, optional GCS_PROJECT_ID; use Workload Identity/ADC
Store credentials in the deployment secret provider, not a ConfigMap, manifest, image, support bundle, or command history. In production, fail the deployment when object-storage TLS verification fails. Do not set MINIO_USE_SSL=false or use an http:// S3 endpoint outside an explicitly isolated development system. Application object keys are durable references in the database. Preserve keys byte-for-byte during migration. Attachment keys currently use attachments/<entity>/<timestamp>-<sanitized-name>.

Direct MinIO reference inventory

The supported boundary is apps/web/lib/storage/index.ts, with provider construction in apps/web/lib/storage/factory.ts. Expected direct SDK usage inside provider adapters:
  • apps/web/lib/storage/providers/minio.ts
  • apps/web/lib/storage/providers/s3.ts
Legacy direct runtime usage:
  • apps/web/lib/minio/minio.ts constructs a MinIO client from a database-backed integration and can create buckets.
  • apps/web/server/routers/attachment.ts deletes attachment objects through the legacy MinIO service instead of StorageService. This bypasses STORAGE_PROVIDER, so deletion is incomplete for local, S3, and GCS.
  • apps/web/services/attachment/index.ts imports MinioService but does not use it. Uploads correctly delegate to services/attachment/server.ts, which uses StorageService.
The MinIO settings UI and MinIO tests are integration/configuration surfaces, not additional production client construction sites. Compose and installer references configure providers or provision a MinIO service; they are not runtime storage API calls. Attachment deletion is routed through the existing deleteAttachmentFile/StorageService.delete path, so local, MinIO, S3, and GCS use the same lifecycle boundary. A storage deletion failure blocks deletion of the database record and is surfaced to the caller for operational follow-up.

Startup health contract

Before serving writes:
  1. validate the explicit provider and all required values;
  2. resolve the endpoint and establish a verified TLS connection;
  3. authenticate with the runtime identity;
  4. confirm the existing bucket/container or writable /data;
  5. perform a namespaced write/read/hash/delete canary;
  6. expose failure through readiness without logging credentials.
Current provider isAvailable() methods can create absent MinIO/GCS buckets. Therefore pre-create storage and validate it with deployment credentials before application startup. Runtime credentials should normally have object CRUD/list permissions, not account-wide administration.

Provider contract and integrity

Run scripts/storage/validate-storage.sh with credentials scoped to a dedicated test prefix. The test verifies startup access, upload, metadata/list visibility, download SHA-256 integrity, copy integrity, and deletion. Run it:
  • before installation and after credential/CA rotation;
  • against every S3-compatible product/version offered for support;
  • before and after a provider migration;
  • during release qualification from the same network and CA trust context as the application.
The script is destructive only within its unique casebender-contract/<timestamp>-<pid> prefix. A passing CLI test supplements, but does not replace, an application attachment lifecycle test.

Data protection and operations

  • Enable bucket/volume encryption, versioning or snapshots, and independently protected backups.
  • Apply retention/object-lock only after validating CaseBender delete and legal hold workflows; retention can make deletes intentionally fail.
  • Deny public access. Signed URLs must be short-lived and audited.
  • Monitor availability, latency, throttling, capacity, failed deletes, and checksum mismatches.
  • Include storage and database in one documented consistency set.
  • Test restore and the copy-verify-rollback runbook at least once per supported release train.
Follow storage-migration-runbook.md for migration and storage-release-security.md for release evidence and SBOM handling.