Storage¶
Totis uses S3-compatible object storage for build artifacts. Each workspace can use either the default shared storage or configure custom storage.
Storage Architecture¶
S3 Bucket
└── {workspace-slug}/
└── {project-slug}/
└── {build-id}/
├── app.ipa
├── app.apk
└── app.dSYM.zip
Storage Options¶
Default Storage¶
By default, workspaces use Totis's managed MinIO storage:
- Fully managed by Totis
- Included in subscription
- Subject to plan storage limits
Custom Storage¶
Workspaces can configure their own S3-compatible storage:
- Full control over your data
- No storage limits from Totis
- Requires S3-compatible service (AWS S3, MinIO, DigitalOcean Spaces, etc.)
Configuring Custom Storage¶
At Workspace Creation¶
{
"workspaceName": "My Company",
"storageConfig": {
"storageType": "CUSTOM",
"accessKey": "your-access-key",
"secretKey": "your-secret-key",
"bucket": "your-bucket-name",
"endpoint": "https://s3.amazonaws.com",
"region": "us-east-1"
}
}
Configuration Fields¶
| Field | Description |
|---|---|
storageType |
DEFAULT or CUSTOM |
accessKey |
S3 access key ID |
secretKey |
S3 secret access key |
bucket |
Target bucket name |
endpoint |
S3-compatible endpoint URL |
region |
AWS region (for AWS S3) |
Supported Providers¶
| Provider | Endpoint Example |
|---|---|
| AWS S3 | https://s3.amazonaws.com |
| MinIO | https://minio.example.com |
| DigitalOcean Spaces | https://nyc3.digitaloceanspaces.com |
| Backblaze B2 | https://s3.us-west-002.backblazeb2.com |
| Cloudflare R2 | https://accountid.r2.cloudflarestorage.com |
Storage Quotas¶
Each subscription plan includes a storage quota:
| Plan | Storage Limit |
|---|---|
| FREE | 5 GB |
| PRO | 50 GB |
| TEAM | 200 GB |
| ENTERPRISE | Custom |
Tracking Usage¶
Current storage usage is tracked per workspace:
Storage Enforcement¶
- File uploads check available storage before accepting
- Exceeding quota returns
STORAGE_LIMIT_EXCEEDEDerror - Deleting files decreases usage immediately
File Upload Flow¶
1. Request Signed URL¶
Response:
2. Upload to S3¶
Upload directly to the signed URL:
3. Confirm Upload¶
This step: - Verifies the file exists in S3 - Records file size and metadata - Updates workspace storage usage - Returns the file record
File Downloads¶
Authenticated Downloads¶
Request a signed download URL:
Returns a time-limited signed URL for download.
Public Downloads¶
Public links redirect to signed URLs:
Storage Security¶
Signed URLs¶
All S3 operations use pre-signed URLs:
- Upload URLs: 1-hour expiration
- Download URLs: 1-hour expiration
- Public link URLs: Same expiration
Access Control¶
- Files are never publicly accessible directly
- All access goes through signed URLs
- Signed tokens validate upload completions
Data Isolation¶
Custom storage credentials are:
- Stored encrypted in the database
- Never exposed in API responses
- Used only for that workspace's operations
Best Practices¶
For Custom Storage¶
- Use dedicated credentials: Create IAM users/keys specific to Totis
- Limit bucket permissions: Only grant required S3 permissions
- Enable versioning: Protect against accidental deletions
- Configure lifecycle rules: Automatically clean up old builds
Recommended S3 Policy¶
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::your-bucket",
"arn:aws:s3:::your-bucket/*"
]
}
]
}
Connection Verification¶
When configuring custom storage, Totis verifies the connection:
- Attempts to list bucket contents
- Checks write permissions
- Returns error if connection fails
Storage Migration¶
Not Currently Supported
Migrating from default to custom storage (or vice versa) is not currently supported. Plan your storage configuration before uploading builds.