Feature Specification: Component garage

Created: 2026-10-07

Status: Implemented

Input: Reconstructed from the code of core/components/hosting-provider/garage/ and the setups at 093e68b6f.

User Scenarios & Testing (mandatory)

User Story 1 - Run the shared S3 store of the hosting provider (Priority: P1)

The hosting provider needs one S3 store for all tenants. The garage component marks the node that provides objectStore, and carries no server configuration itself. The setups give the server, the layout bootstrap, the buckets, the S3 keys and the TLS names to that node (see garage, 005). Each bucket and key has the prefix of its tenant.

Why this priority: the backups and the telemetry stores keep their data here.

Independent Test: unit tests of the setups hold that each provisioned bucket has a key, that the key pair renders where the import reads it, and that the admin API is internal and not published.

Acceptance Scenarios:

  1. Given the node that provides objectStore, When the setups evaluate, Then it provisions the garage requests of its group, and the OpenBao agent writes each key readable only by its owner and group.

User Story 2 - Browse buckets in a web UI (Priority: P2)

An administrator looks at the buckets and keys in a web UI on its own name under the apex, behind an Authelia forward-auth check.

Why this priority: a convenience. Garage works without it.

Independent Test: unit tests hold that a new admin token restarts Garage and the UI, and that the UI name is a label under the apex.

Acceptance Scenarios:

  1. Given the policy deploys admin UIs, When a browser opens the UI name, Then Authelia asks for one factor. Without that policy, the node has no UI and no name for it.

Edge Cases

  • The UI reads the admin token only at start, so a new token reaches it through a restart.
  • The UI admits each user who passes one factor, unlike the windmill UI, which admits only administrators.
  • The UI starts after Garage without requiring it, and restarts after a failure.

Requirements (mandatory)

Functional Requirements

  • FR-001: The component MUST declare that it provides objectStore, and the setups MUST give the server and its buckets to that provider.
  • FR-002: The component MUST request a SPIFFE identity, and MUST open the web ports to the internet, because clients on the internet fetch media from the buckets.
  • FR-003: The component MUST request a one-factor forward-auth vhost for the UI with no condition of its own; the deployment policy gates admin UIs in the resource. The UI MUST exist only with that vhost.
  • FR-004: The UI MUST run without a fixed user on loopback, talk to the admin and S3 APIs on loopback, and restart when the admin token renders again.

Key Entities

  • Garage request: buckets and keys with the tenant prefix.
  • Admin token: a generated secret that Garage and the UI read.

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: The unit tests of the setups for minted keys, key paths, internal reach, wildcard TLS, the token reload and the apex pass.
  • SC-002: On a live node, the UI name sends a browser without a session to the Authelia portal.

Assumptions

  • Authelia runs in the deployment (see authelia), and OpenBao renders the admin token.
  • The entry point gives the apex to the module.

Known Deviations

None.