External Storage lets you keep your app builds and attachments in your own cloud storage account instead of TestApp.io's storage. You own the bucket, the keys and the data.
Why use External Storage?
- Data location. Choose where your files are kept (Amazon S3 lets you pick the AWS region).
- Company policy. Some teams must keep build artifacts in an account they control.
- Retention and access. You set your own retention, logging and billing on the bucket.
Plan requirement
External Storage is available on the Pro plan. On Free and Starter, the Add New button is disabled. See testapp.io/pricing for plan details.
If your team downgrades to a plan without External Storage, or a payment fails, your external storages are set to Inactive.
Supported providers
- Amazon S3
- Google Cloud Storage
- Wasabi
- DigitalOcean Spaces
- Vultr Object Storage
- IBM Cloud Object Storage
- Backblaze B2 (beta)
For every provider you enter an access key and a secret for an S3-compatible API. For Google Cloud Storage, use an HMAC key (Cloud Storage "interoperability" access key), not a service account JSON file.
TestApp.io creates the bucket for you. You do not enter a bucket name. The bucket is named testappio- followed by a random ID. You can see it on the storage card in the Portal.
Only Amazon S3 lets you choose the region. For the other providers TestApp.io uses a fixed region, shown as Region when you edit the storage.
Amazon S3
Choose a region
When you pick Amazon S3, a Region list appears. Your bucket is created in the region you choose. You cannot change the region later. To use another region, add a new storage.
The list covers the standard AWS regions. GovCloud and China regions are not supported.
Opt-in regions
AWS keeps some regions turned off until you enable them. The Portal marks these with "opt-in". Enable the region in your AWS account first: Account settings > AWS Regions. If you do not, bucket creation fails.
Opt-in regions: Africa (Cape Town), Asia Pacific (Hong Kong, Taipei, Hyderabad, Jakarta, Melbourne, Malaysia, New Zealand, Thailand), Canada West (Calgary), Europe (Zurich, Milan, Spain), Israel (Tel Aviv), Middle East (Bahrain, UAE) and Mexico (Central).
Create an IAM user and policy
Create a dedicated IAM user for TestApp.io and an access key for it. Attach a policy like the one below. It limits the user to buckets whose names start with testappio-, which is the name TestApp.io gives the buckets it creates.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "TestAppIoBuckets",
"Effect": "Allow",
"Action": [
"s3:CreateBucket",
"s3:DeleteBucket",
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:GetBucketLocation",
"s3:PutBucketOwnershipControls",
"s3:PutBucketPublicAccessBlock"
],
"Resource": "arn:aws:s3:::testappio-*"
},
{
"Sid": "TestAppIoObjects",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl",
"s3:GetObject",
"s3:DeleteObject",
"s3:AbortMultipartUpload",
"s3:ListMultipartUploadParts"
],
"Resource": "arn:aws:s3:::testappio-*/*"
}
]
}What each permission is for:
s3:CreateBucket: creates the bucket when you add the storage.s3:PutBucketOwnershipControlsands3:PutBucketPublicAccessBlock: set up the bucket so uploads work (see below).s3:PutObjectands3:PutObjectAcl: upload builds and attachments as public-read objects. They also upload the check file.s3:DeleteObject: delete the check file, and delete builds when you delete a release or app.s3:ListBucket,s3:GetBucketLocationands3:GetObject: check access when you update credentials or reactivate a storage, and read objects.s3:ListBucketMultipartUploads,s3:ListMultipartUploadPartsands3:AbortMultipartUpload: large builds are uploaded in parts.s3:DeleteBucket: removes the bucket when you remove the storage in the Portal.
If you already have an older policy, the two new permissions are s3:PutBucketOwnershipControls and s3:PutBucketPublicAccessBlock.
What TestApp.io changes on the bucket, and why
New Amazon S3 buckets reject object ACLs and block all public access by default. TestApp.io stores builds as public-read objects so that install links work for your testers. So right after it creates the bucket, TestApp.io changes these settings on that bucket only:
- Object Ownership: set to "Bucket owner preferred".
- Block Public Access: the two ACL options are turned off ("Block public access to buckets and objects granted through new access control lists (ACLs)" and "...through any access control lists (ACLs)").
- Block Public Access, kept on: the two policy options stay on. Public bucket policies remain blocked.
Then TestApp.io uploads a small file named testappio-storage-check.txt with a public-read ACL, and deletes it right away. This proves real uploads will work. If you see this file in the bucket, it is safe to delete.
If any step fails, TestApp.io deletes the bucket it just created, so nothing is left behind, and shows an error.
Uploaded builds and attachments are public-read objects. Anyone who has a file's URL can download it. The bucket itself cannot be listed publicly.
Account-level Block Public Access
AWS also has a Block Public Access setting for the whole account, and organizations can add policies on top. If either blocks public ACLs, bucket-level changes are not enough and connecting fails with the "Amazon S3 rejected a test upload" error (see Troubleshooting). To fix it, open S3 > Block Public Access settings for this account and turn off the two ACL options. You can leave the two policy options on. Then add the storage again.
Set up External Storage
- Sign in to the TestApp.io Portal and open Team, then the Storage tab. You need permission to manage storage.
- Click Add New. The Add Storage panel opens.
- Select a Provider.
- For Amazon S3, select a Region.
- Enter the Key and the Secret. Each must be at least 10 characters.
- Click Add. TestApp.io creates the bucket and checks it. This can take several seconds.
- When it succeeds, you see "Storage successfully added" and the storage appears under External Storage Providers with the status Active.
There is no separate Validate button. The checks run when you click Add.
To use the storage, select it in the Storage field when you create an app. New builds and attachments for that app go to your bucket.
You cannot add the same key twice. If an active storage already uses the key, you see "You already created a storage with this key".
Manage your storage
On the storage card, click the three-dot menu, then Edit or Remove.
Deactivate and reactivate
In Edit, open the Status tab, choose Active or Inactive, and click Update. While a storage is inactive, it cannot be used for new apps or releases, and existing apps and releases that use it are not accessible. Your data stays in your bucket. Reactivating needs a plan that includes External Storage.
TestApp.io can also set a storage to Inactive on its own, for example when your plan changes or when it loses access to the bucket. Hover over the Inactive badge to see the reason.
Update credentials
In Edit, open the Credentials tab, enter the new Access Key and Secret Key, and click Update. TestApp.io first checks that the new key can access the bucket. If the storage was inactive and the check passes, it becomes active again.
The new key needs the same permissions as the old one.
The region, endpoint and bucket cannot be edited. They are shown read-only.
Remove a storage
Click Remove, then Yes, Remove. This cannot be undone. Removing a storage:
- deletes the bucket and everything in it, using your key (the key needs
s3:DeleteBucketands3:DeleteObject), and - deletes every app that uses this storage, with its releases and attachments.
The dialog shows how many apps and releases will be removed. If you want to keep your files, copy them out of the bucket first. Deactivating instead of removing keeps everything in place.
Troubleshooting
These are the messages you may see in the Add Storage panel.
"You need to upgrade your team's plan to use this feature"
Your plan does not include External Storage. Upgrade to Pro.
"Unable to create bucket, please check the key/secret again and make sure that this key has the permission to create & delete bucket, upload, read, list and delete objects in [region] region"
The key is wrong, or the policy does not allow s3:CreateBucket. For an opt-in region, the message continues: "[region] is an opt-in region, so you must also enable the region in your AWS account (Account settings > AWS Regions) before using it". Enable the region and try again.
"Unable to prepare the bucket in [region] region, please make sure that this key also has the s3:PutBucketOwnershipControls and s3:PutBucketPublicAccessBlock permissions..."
The key could create the bucket but cannot change its ownership or public access settings. Add the two permissions from the policy above. TestApp.io has already removed the new bucket, so you can try again.
"Amazon S3 rejected a test upload that is publicly readable in [region] region, so uploads would fail..."
Block Public Access is on for the whole AWS account, or an organization policy forbids public ACLs. See "Account-level Block Public Access" above. Also check that the key has s3:PutObject, s3:PutObjectAcl and s3:DeleteObject.
"Unable to configure the bucket in [region] region, please try again. If this keeps happening, contact us"
The setup failed for a reason other than permissions. Try again. If it keeps happening, contact us.
"Unsupported AWS region" or "This storage provider does not support choosing a region"
Pick a region from the list. Only Amazon S3 supports choosing a region.
"Unable to access bucket with provided credentials..."
Shown when you update credentials. The new key cannot access the bucket. Check the key, the secret and the policy.
"Unable to delete bucket, please check the key/secret again and make sure that this key has the permission to delete [bucket] bucket..."
Shown when you remove a storage. Make sure the key still has s3:DeleteBucket and s3:DeleteObject on the bucket. If you already deleted the bucket in your cloud account, contact us.
"This storage is inactive. Please activate it before use."
Open Team > Storage, click Edit and set the status to Active. If it cannot be reactivated, update the credentials.
Installs or downloads return "Access Denied"
Someone may have changed the bucket's Block Public Access or Object Ownership settings, or turned on account-level Block Public Access after setup. Restore the settings described above.
Security notes
- Use a dedicated IAM user or key for TestApp.io. Do not reuse keys from other services.
- Scope the policy to
testappio-*buckets, as shown above. - TestApp.io stores your key and secret so it can upload and manage files. The Portal never shows the secret again.
- Rotate the key from time to time. Use Edit > Credentials to give TestApp.io the new one.
- Files are public-read, so anyone with a file's URL can download it. Do not store anything in these buckets that must stay private.
- Turn on access logging on the bucket if you want an audit trail.
Need help? Contact us and we'll get back to you shortly.