Files
s3mover/docs/PRD.md
2026-03-26 11:46:30 +00:00

481 lines
16 KiB
Markdown

# Product Requirements Document
## Product
**Name:** S3 Mover
**Document version:** 0.1
**Date:** 2026-03-26
**Status:** Draft
## Overview
S3 Mover is a web application for securely managing files across one or more S3-compatible buckets. The system provides a React frontend and Go backend, with SQLite as the system of record for users, bucket access, invitations, audit logs, and authentication-related metadata.
The existing proof of concept demonstrated that a Go backend can enumerate files and perform upload, download, and delete operations against S3-compatible object storage. This product extends that proof of concept into a production-oriented multi-user application with user management, per-user bucket credentials, invitation-based onboarding, mandatory 2FA, audit logging, and Docker deployment.
## Problem Statement
The proof of concept is functionally viable, but it is not suitable for real users because:
- There is no user management or role-based access control.
- Storage credentials are configured globally instead of per user and per bucket.
- There is no secure onboarding flow.
- There is no multi-factor authentication.
- There is no audit trail for file operations.
- Sensitive bucket configuration is not yet modeled as protected server-side data.
The product must evolve into a secure internal application that allows administrators to manage users and user-specific bucket credentials, while allowing standard users to operate only on the buckets assigned to them.
## Goals
- Provide secure user authentication using email, password, and TOTP-based 2FA.
- Support administrator-led invitation onboarding via Resend email.
- Allow administrators to manage users and assign one or more bucket configurations to each user.
- Keep all sensitive bucket credentials server-side only.
- Provide file browsing and upload, download, and delete capabilities for the assigned bucket(s) of a logged-in user.
- Record auditable logs of bucket operations.
- Persist system data in SQLite.
- Package the application for Docker deployment.
## Non-Goals
- End-user self-registration.
- SSO, SAML, or OAuth identity providers in the first release.
- Bucket creation or infrastructure provisioning.
- Advanced IAM policy editing or credential rotation workflows.
- Object versioning, lifecycle management, or ACL management.
- Bulk file operations beyond single upload, download, and delete.
- Fine-grained per-prefix authorization within a bucket in the first release.
## Users and Roles
### Administrator
The administrator manages the system and has access to all administrative functions.
Capabilities:
- Log in with email, password, and TOTP
- View all registered users
- View details for an individual user
- Invite a new user by email
- Delete a user account
- Add one or more bucket credential sets to a user
- Remove a bucket credential set from a user
- View audit logs for all file operations
### Standard User
The standard user interacts only with buckets assigned to their account.
Capabilities:
- Complete invitation onboarding
- Set a strong password
- Enroll a TOTP authenticator during first-time setup
- Log in with email, password, and TOTP
- View the list of assigned buckets in a left sidebar
- Select a bucket and view its contents
- Upload, download, and delete files within assigned buckets
## Key User Journeys
### 1. Administrator Invites a User
1. Administrator logs into the application.
2. Administrator navigates to the user management page.
3. Administrator creates a new user by entering at least an email address.
4. System creates a pending user record and a time-limited invitation token.
5. System sends an invitation email through Resend.
6. Email contains a secure link to the onboarding page.
### 2. User Accepts Invite and Creates Credentials
1. User clicks the invitation link.
2. System validates the invitation token.
3. User is prompted to set a strong password.
4. User is required to enroll a TOTP authenticator before activation completes.
5. User confirms setup by entering a valid TOTP code.
6. System activates the account and marks the invitation as consumed.
### 3. User Logs In
1. User enters email address and password.
2. System validates credentials.
3. User is prompted for a TOTP code.
4. System issues a JWT after successful second-factor verification.
5. User is redirected to the main application.
### 4. User Operates on a Bucket
1. User logs in successfully.
2. User sees a sidebar listing assigned buckets.
3. User selects a bucket.
4. System displays the bucket name and endpoint at the top of the page.
5. System shows a paginated file list with 15 items per page.
6. User uploads, downloads, or deletes files.
7. System records an audit log entry for each file operation.
### 5. Administrator Manages Bucket Credentials for a User
1. Administrator navigates to a user detail page.
2. Administrator adds a bucket credential set for that user.
3. Administrator enters:
- AWS access key ID
- AWS secret access key
- AWS region
- bucket name
- S3-compatible endpoint
4. System stores those credentials securely in SQLite.
5. User gains access to that bucket after next authorized fetch or session refresh.
6. Administrator may remove a bucket configuration from the user later.
## Functional Requirements
## FR-1 Authentication
- The system shall support login using email address and password.
- The system shall require TOTP as a second factor for all users.
- The system shall issue JWTs for authenticated API access.
- The system shall reject access to protected routes without a valid JWT.
- The system shall support logout by invalidating the client session.
## FR-2 Invitation and Onboarding
- Only an administrator may create a new user.
- Creating a user shall generate an invite email sent through Resend.
- The invite shall contain a secure, time-limited, single-use token.
- The invite flow shall require the user to set a strong password.
- The invite flow shall require TOTP setup before account activation.
- An invited user shall not be able to log in until onboarding is complete.
## FR-3 User Management
- The administrator shall have a page listing all users.
- The user list shall include at minimum email address, status, role, created date, and last login date if available.
- The administrator shall be able to click into a user detail page.
- The administrator shall be able to delete a user account.
- Deleting a user shall revoke future access immediately.
## FR-4 Bucket Assignment
- A user shall be assigned at least one bucket credential set to access storage.
- A user may have multiple bucket credential sets.
- Each bucket credential set shall be unique to the user and shall not be shared by design.
- The administrator shall be able to create, view metadata for, and remove bucket assignments for a user.
- Sensitive values such as access keys and secrets shall not be shown back to the browser after creation, except where explicitly required for a masked administrative UX.
## FR-5 Bucket Browsing and File Operations
- A logged-in user shall see assigned buckets in a left sidebar.
- Selecting a bucket shall show:
- bucket name
- endpoint
- paginated file listing
- Pagination shall be fixed at 15 items per page.
- The system shall support upload, download, and delete operations for files in the selected bucket.
- The system shall support S3-compatible providers, not just AWS S3.
## FR-6 Audit Logging
- The system shall log all user file operations.
- Each log entry shall include at minimum:
- timestamp
- user ID
- user email
- bucket identifier
- file key
- operation type
- The operation type shall support at minimum:
- upload
- download
- delete
- Only administrators shall be able to view logs.
## FR-7 Administrative Access Control
- Only administrators shall be able to:
- invite users
- view all users
- view user details
- manage user bucket assignments
- delete users
- view audit logs
## FR-8 Deployment and Runtime
- The application shall run in Docker.
- The backend shall be implemented in Go.
- The frontend shall be implemented in React.
- SQLite shall be the primary application database.
## Security Requirements
- Sensitive bucket credentials shall never be sent to the browser.
- Sensitive bucket credentials shall never be included in JWT payloads.
- JWTs shall be signed server-side with a configurable secret or private key.
- Passwords shall be stored only as strong salted hashes.
- TOTP secrets shall be stored securely server-side.
- Invite tokens shall be stored hashed or otherwise protected server-side and shall expire.
- The application shall enforce HTTPS in deployed environments.
- The application shall implement CSRF protections if JWTs are stored in cookies.
- The application shall implement rate limiting or equivalent brute-force protection for authentication endpoints.
- All sensitive configuration shall be provided through environment variables or secret injection at runtime.
- Administrative and user actions shall be authorized server-side for every request.
## UX Requirements
### Authentication
- The application shall provide:
- login page
- TOTP challenge page
- invitation acceptance page
- password setup form
- TOTP enrollment page with QR code and manual key fallback
### Main User Application
- The main authenticated layout shall include:
- left sidebar for bucket selection
- top area showing selected bucket name and endpoint
- file listing view
- pagination controls
- upload action
- download action
- delete action
### Administration
- The administrator area shall include:
- user list page
- user detail page
- add bucket assignment flow
- audit log page
## Data Model Requirements
The following logical entities are required.
### users
- id
- email
- role
- status
- password_hash
- totp_secret
- totp_enabled
- invited_at
- activated_at
- last_login_at
- created_at
- updated_at
### invitations
- id
- user_id
- email
- token_hash
- expires_at
- consumed_at
- created_by_user_id
- created_at
### user_bucket_credentials
- id
- user_id
- display_name
- aws_access_key_id
- aws_secret_access_key
- aws_region
- s3_bucket
- aws_endpoint_url
- use_path_style
- created_at
- updated_at
### audit_logs
- id
- user_id
- user_email
- bucket_credential_id
- bucket_name
- endpoint
- file_key
- operation
- created_at
- request_ip
- user_agent
### sessions or token metadata
Implementation may use stateless JWTs only, but the design should allow optional storage for token revocation, refresh sessions, or login tracking if needed.
## Recommended Status Values
### User status
- invited
- active
- disabled
### Role
- admin
- user
### Audit operation
- upload
- download
- delete
## API Requirements
The final API shape may change, but the following resources are expected.
### Authentication
- `POST /api/auth/login`
- `POST /api/auth/totp/verify`
- `POST /api/auth/logout`
- `GET /api/auth/me`
### Invitations
- `POST /api/admin/users/invite`
- `GET /api/invitations/:token`
- `POST /api/invitations/:token/accept`
### Administration
- `GET /api/admin/users`
- `GET /api/admin/users/:userId`
- `DELETE /api/admin/users/:userId`
- `POST /api/admin/users/:userId/buckets`
- `DELETE /api/admin/users/:userId/buckets/:bucketCredentialId`
- `GET /api/admin/audit-logs`
### User bucket access
- `GET /api/me/buckets`
- `GET /api/me/buckets/:bucketCredentialId/files?page=1&pageSize=15`
- `POST /api/me/buckets/:bucketCredentialId/files`
- `GET /api/me/buckets/:bucketCredentialId/files/:key`
- `DELETE /api/me/buckets/:bucketCredentialId/files/:key`
## Business Rules
- Every non-admin user must authenticate with password plus TOTP.
- An invitation may only be used once.
- A bucket credential set belongs to exactly one user.
- A user may have zero bucket assignments during setup or after administrative changes, but a user must have at least one assignment to perform storage operations.
- The server shall resolve storage access from the selected bucket credential ID and not from any client-supplied raw credential values.
- The browser may know a bucket display name, bucket name, and endpoint, but not secret credentials.
## Technical Requirements
### Backend
- Go HTTP API
- SQLite persistence
- JWT authentication middleware
- Password hashing using a modern algorithm such as Argon2id or bcrypt
- TOTP support using a standard authenticator-compatible implementation
- Resend integration for invitation emails
- S3-compatible client abstraction for storage operations
- Audit log persistence for all storage mutations and downloads
### Frontend
- React application
- Authenticated routing
- Admin-only views and user views
- Sidebar bucket navigation
- Paginated bucket file list with page size fixed to 15
- Forms for onboarding, login, TOTP verification, user management, and bucket assignment
### Infrastructure and Deployment
- Single Docker image or Docker Compose-based local runtime
- Persistent storage volume for SQLite database
- Environment-based configuration for JWT secret, Resend API key, and bootstrap admin settings
## Reporting and Logging Requirements
- Application logs shall capture authentication failures, invitation events, administrative changes, and storage operation failures.
- Audit logs shall be queryable by administrators.
- Audit log views should support filtering by:
- date range
- user
- bucket
- operation
## Constraints
- SQLite is the required datastore for the initial production-ready version.
- The frontend must not directly communicate with S3-compatible storage using raw bucket credentials.
- All storage operations must be proxied through the Go backend.
- Sensitive settings must remain server-side.
## Assumptions
- The first release supports one administrator bootstrap path via environment configuration, migration seed, or initial setup command.
- Invitation emails will be transactional emails sent through Resend.
- TOTP apps such as 1Password, Google Authenticator, or Authy are acceptable authenticators.
- The application is intended for trusted organizational users rather than open public sign-up.
## Open Questions
- How should the first administrator account be bootstrapped?
- Should administrators also be able to perform bucket operations, or only manage users and logs?
- Should deleted users be hard-deleted or soft-deleted for audit retention?
- Should bucket secrets be encrypted at rest in SQLite using an application-level encryption key?
- Should JWTs be short-lived access tokens only, or should the system also support refresh tokens?
- What are the password strength rules beyond “strong password”?
- What is the invite expiration window?
- Should audit logs include failed file operations in addition to successful ones?
- Is account disablement required in addition to deletion?
- Are per-user bucket display names needed in the UI, or is raw bucket name sufficient?
## Success Criteria
- Administrators can invite, onboard, and manage users without manual database changes.
- Standard users can access only their assigned buckets.
- Bucket credentials never appear in browser network payloads or rendered UI.
- Users must complete TOTP enrollment before account activation.
- All file uploads, downloads, and deletes are auditable by administrators.
- The application runs successfully in Docker with SQLite persistence.
## Proposed Delivery Phases
### Phase 1: Identity and Administration Foundation
- SQLite schema and migrations
- bootstrap administrator
- login, password hashing, JWT issuance
- TOTP enrollment and verification
- invite flow with Resend
- admin user list and user detail pages
### Phase 2: Bucket Assignment and Secure Access
- per-user bucket credential storage
- admin create and remove bucket credentials
- authenticated bucket list API
- user sidebar and selected-bucket view
- secure server-side storage operations using assigned credentials
### Phase 3: Auditability and Production Hardening
- audit log persistence and admin log viewer
- Docker packaging
- operational logging and error handling
- rate limiting and security hardening
- UX polish and edge-case handling