16 KiB
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
- Administrator logs into the application.
- Administrator navigates to the user management page.
- Administrator creates a new user by entering at least an email address.
- System creates a pending user record and a time-limited invitation token.
- System sends an invitation email through Resend.
- Email contains a secure link to the onboarding page.
2. User Accepts Invite and Creates Credentials
- User clicks the invitation link.
- System validates the invitation token.
- User is prompted to set a strong password.
- User is required to enroll a TOTP authenticator before activation completes.
- User confirms setup by entering a valid TOTP code.
- System activates the account and marks the invitation as consumed.
3. User Logs In
- User enters email address and password.
- System validates credentials.
- User is prompted for a TOTP code.
- System issues a JWT after successful second-factor verification.
- User is redirected to the main application.
4. User Operates on a Bucket
- User logs in successfully.
- User sees a sidebar listing assigned buckets.
- User selects a bucket.
- System displays the bucket name and endpoint at the top of the page.
- System shows a paginated file list with 15 items per page.
- User uploads, downloads, or deletes files.
- System records an audit log entry for each file operation.
5. Administrator Manages Bucket Credentials for a User
- Administrator navigates to a user detail page.
- Administrator adds a bucket credential set for that user.
- Administrator enters:
- AWS access key ID
- AWS secret access key
- AWS region
- bucket name
- S3-compatible endpoint
- System stores those credentials securely in SQLite.
- User gains access to that bucket after next authorized fetch or session refresh.
- 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
- role
- status
- password_hash
- totp_secret
- totp_enabled
- invited_at
- activated_at
- last_login_at
- created_at
- updated_at
invitations
- id
- user_id
- 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/loginPOST /api/auth/totp/verifyPOST /api/auth/logoutGET /api/auth/me
Invitations
POST /api/admin/users/inviteGET /api/invitations/:tokenPOST /api/invitations/:token/accept
Administration
GET /api/admin/usersGET /api/admin/users/:userIdDELETE /api/admin/users/:userIdPOST /api/admin/users/:userId/bucketsDELETE /api/admin/users/:userId/buckets/:bucketCredentialIdGET /api/admin/audit-logs
User bucket access
GET /api/me/bucketsGET /api/me/buckets/:bucketCredentialId/files?page=1&pageSize=15POST /api/me/buckets/:bucketCredentialId/filesGET /api/me/buckets/:bucketCredentialId/files/:keyDELETE /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