Skip to content
Docs

Command palette

Jump to a page or view, or find a todo by name.

Changelog

ADR-0001 — Stored file keys keep the user's filename

The repository's architectural decision, rationale and consequences.

Markdown

Status: accepted · 2026-07-13. Isolation clarification · 2026-10-01.

Context

packages/storage shipped a sanitizeFileName helper — lowercase, strip unsafe characters, collapse whitespace, preserve one extension — that nothing in production ever called. It was exercised only by its own tests.

An architecture review flagged this as a gap: user-supplied filenames become object keys unsanitized. The obvious fix is to wire the sanitizer in at the upload boundary.

We are deliberately not doing that.

Decision

A stored file's key keeps the name the user gave it. The sanitizer is deleted rather than wired in.

Why

The raw name is a feature, not an oversight. The upload composer lets a user edit the name a file is stored under before uploading it, and that name becomes the key. Sanitizing would silently overwrite an explicit choice the user just made — a file the user named Relatório Final.PDF would come back as relatorio-final.pdf. The file gallery displays file.name || file.key, so the change would be visible.

The filename does not choose the Organization. The gateway applies orgs/<organizationId>/ server-side after checking the current Session and membership. This organization prefix replaced the original user prefix under ADR-0003. Client-supplied names cannot choose or escape the organization prefix. Object-storage keys are flat strings, so a .. segment is a literal character sequence rather than a parent directory.

Uploads are already gated where it matters. validateUpload enforces the size limit and the MIME allowlist. That is the boundary that protects the system; the filename is presentation.

Consequences

  • Arbitrary user input (spaces, unicode, long names) appears in stored keys and in URLs derived from them. Anything consuming a key must treat it as opaque and encode it for transport — not assume it is URL-safe.
  • If a future requirement does demand sanitized keys (a storage backend with key restrictions, say), the display name must be preserved separately so the user still sees the name they chose. Reopen this ADR rather than sanitizing in place.
  • sanitizeFileName and packages/storage/src/keys.ts are gone. Do not reintroduce them without revisiting this decision.
  • Supersedes the "wire the sanitizer in" candidate raised in issue #36.
  • The current organization isolation rule lives in the files gateway's keyPrefix and ADR-0003. The historical discussion in #32 deleted a second, contradictory key-building rule.
Edit on GitHubDocumentation is in English.