As noted in the Container Lifecycle documentation, Containers on Aptible are fundamentally ephemeral, and you should never use the filesystem for long-term file or data storage.

The best approach for storing files uploaded by your customers (or, more broadly speaking, any blob data generated by your app, such as PDFs, etc.) is to use a third-party object store, such as AWS S3.

You can store data in an Aptible database, but often at a performance cost.

Using AWS S3 for PHI

❗️ If you are storing regulated or sensitive information, ensure you have the proper agreements with your storage provider. For example, you’ll need to execute a BAA with AWS and use encryption (client-side or server-side) to store PHI in AWS S3.

For storing PHI on Amazon S3, you must get a separate BAA with Amazon Web Services. This BAA will require that you encrypt all data stored on S3. You have three options for implementing encryption, ranked from best to worst based on the combination of ease of implementation and security:

  1. Server-side encryption with customer-provided keys (SSE-C): You specify the key when uploading and downloading objects to/from S3. You are responsible for remembering the encryption key but don’t have to choose or maintain an encryption library.

  2. Client-side encryption (CSE): This approach is the most challenging but also gives you complete control. You pick an encryption library and implement the encryption/decryption logic.

  3. Server-side encryption with Amazon-provided keys (SSE): This is the most straightforward approach but the least secure. You need only specify that encryption should occur on PUT, and you never need to keep track of encryption keys. The downside is that if any of your privileged AWS accounts (or access keys) are compromised, your S3 data may be compromised and unprotected by a secondary key.

There are two ways to serve S3 media files:

  1. Generate a pre-signed URL so that the client can access them directly from S3 (note: this will not work if you’re using client-side encryption)

  2. Route all media requests through your app, fetch the S3 file within your app code, then re-serve it to the client.

The first approach is superior from a performance perspective. However, if these are PHI-sensitive media files, we recommend the second approach due to the control it gives you concerning audit logging, as you can more easily connect specific S3 file access to individual users in your system.