Skip to main content

Files

File upload, download, metadata management, and deletion using a local filesystem storage backend.

Overview

Files are associated with a project and stored on the server's local filesystem. Every file record exposes a public id; the internal database primary key is never returned. Files are organized in a project-scoped directory structure and tracked in PostgreSQL.

See the Permissions Reference for the IAM action strings for this module.

Data Model

FieldTypeDescription
idstringPublic identifier
pathstring | nullLogical path within the project (e.g. /assets/logo.png). Also used as the resource ID segment in path-based SRNs.
filenamestringOriginal filename
content_typestringMIME type
sizenumberFile size in bytes
storage_typelocal | s3 | gcsStorage backend (currently local)
storage_pathstringAbsolute path on disk
metadatastringArbitrary JSON string for custom metadata
project_idstringID of the owning project
created_atstringISO 8601 creation timestamp
updated_atstringISO 8601 last-updated timestamp

The optional path field is a logical, project-scoped identifier for a file — similar to a filesystem path. It must be absolute (start with /) and is normalized at write time. The combination of project_id + path is unique within a project.

Key Concepts

Storage Layout

Files are organized in a project-scoped directory structure on disk:

{FILES_STORAGE_DIR}/{projectPublicId}/{category}/{fileId}{ext}
SegmentDescription
FILES_STORAGE_DIRRoot directory from the environment variable
projectPublicIdPublic project ID (e.g. proj_ABC) — isolates files by project
categoryDerived from the first segment of the file's logical path (e.g., /traces/foo.jsontraces/)
fileIdThe file's public ID
extFile extension from the original filename

If a file has no path, the category defaults to files/. Examples:

/data/files/proj_1a123a/traces/agt_trace_abc123.json
/data/files/proj_1a123a/documents/doc_xyz.md
/data/files/proj_1a123a/files/file_plain123.png

Path-Based SRNs

Policies can target files by their logical path rather than their id. When a file has a path set, the server evaluates both the id-based SRN and the path-based SRN:

SRN formMatches
soat:proj_ABC:file:file_XYZSpecific file by ID
soat:proj_ABC:file:/assets/logo.pngFile at the exact path /assets/logo.png
soat:proj_ABC:file:/exports/*All files under /exports/
soat:proj_ABC:file:*All files in the project (id wildcard)

The list endpoint applies policy filters at the SQL level — the database returns only rows the caller is permitted to see. See IAM for full SRN syntax and policy authoring guidance.

Configuration

Environment VariableRequiredDescription
FILES_STORAGE_DIRYesAbsolute path to the directory where uploaded files are stored. Must be writable by the server process.

When running via Docker, mount a volume at this path to persist files across container restarts:

services:
server:
image: soat-server
environment:
FILES_STORAGE_DIR: /data/files
volumes:
- files-data:/data/files

volumes:
files-data:

Examples

Upload a file (base64)

soat upload-file-base64 \
--project-id proj_ABC \
--filename logo.png \
--content-base64 "iVBORw0KGgo..." \
--path /assets/logo.png

List files in a project

soat list-files --project-id proj_ABC