Offsite patient document storage for OpenEMR using Amazon S3. Supports access keys (encrypted at rest), EC2 instance profiles, and the AWS default credential chain.
Module Manager name: AWS Simple Storage Solution v1.1.0
Package version: 1.1.0 (version.php)
Namespace: Juggernaut\SimpleStorageSolution\Module
Author: Sherwin Gaddis
| Target | Status |
|---|---|
| OpenEMR 8.0+ (including 8.2.x) | Supported — uses SessionWrapperFactory / session-aware CSRF |
| OpenEMR 7.0.x | Not the primary target; may work partially but is not certified |
- PHP 8.1+
- Dependency:
aws/aws-sdk-php^3.231 (install with Composer in the module directory) - Composer conflict:
openemr/openemr< 8.0.0
- Hooks OpenEMR offsite document events to upload/retrieve objects in S3
- Settings UI with connection test and bucket discovery/manual entry
- Auth modes: DEFAULT provider chain, IP instance profile, KS key/secret (
CryptoGenencrypted in DB) - Menu: Modules → AWS S3
- Presigned GET helper and staff-only upload probe
-
Clone into custom modules:
cd /path/to/openemr/interface/modules/custom_modules git clone https://github.com/juggernautsei/oe-simple-storage-solution.git cd oe-simple-storage-solution composer install --no-dev
-
In OpenEMR Module Manager: register, install (
table.sql), enable. -
Open Modules → AWS S3 (requires
patients/docsor admin super). -
Configure region + auth mode, test connection, select bucket.
table.sql creates module_s3_credentials (encrypted key/secret columns, region, bucket, bucket_type).
Upgrade script: sql/1_0_0-to1_1_0_upgrade.sql adds bucket_type.
Unregister drops the credentials table.
- AWS secrets encrypted with OpenEMR
CryptoGenbefore DB storage; never re-displayed in the UI - Settings, credential POST, upload test, and presign helper require ACL
- CSRF on credential save and bucket AJAX
- Upload temp files use
$OE_SITE_DIR/documents/temp(not a hardcoded host path) - Prefer instance profile or default chain on AWS over long-lived access keys
- Enable S3 SSE, block public access, least-privilege IAM
- After
composer install, ensure the web user can readvendor/ - Offsite document events require OpenEMR core support for remote document store/retrieve
- Presigned links:
public/getObjectFromBucket.php?key=relative/object-key(5 minutes) - Manual probe:
public/index.phpuploads bundledtext.txt
This module connects OpenEMR to Amazon S3 for secure, scalable cloud storage of patient files and documents.
OpenEMR's S3 Storage Solution module supports two authentication methods for connecting to Amazon S3:
- AWS Access Key ID and Secret Access Key - Direct credential authentication
- IAM Instance Profile - For OpenEMR installations running on AWS EC2 instances
This guide explains how to set up both methods.
- Log in to the AWS Management Console
- Navigate to the IAM service
- In the left navigation pane, choose "Users" and then "Add user"
- Enter a username (e.g.,
openemr-s3-user) - Select "Programmatic access" as the access type
- Click "Next: Permissions"
- Choose "Attach existing policies directly"
- You can either:
- Create and attach a custom policy (recommended, see below)
- Use the built-in
AmazonS3FullAccesspolicy (less secure, not recommended for production)
- In the IAM service, go to "Policies" in the left navigation
- Click "Create policy"
- Select the JSON tab and paste the following policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": [
"arn:aws:s3:::YOUR-BUCKET-NAME"
]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::YOUR-BUCKET-NAME/*"
]
}
]
}- Replace
YOUR-BUCKET-NAMEwith your actual S3 bucket name - Click "Review policy", give it a name (e.g.,
OpenEMR-S3-Policy), and create it - Attach this policy to your IAM user
- Click through the "Tags" page (optional)
- Review the user details and click "Create user"
- IMPORTANT: This is the only time you'll see the Secret Access Key. Download the CSV file or copy both the Access Key ID and Secret Access Key to a secure location.
- In OpenEMR, navigate to Modules > Manage Modules
- Enable the "S3 Storage Solution" module if not already enabled
- Go to Modules > S3 Module
- Enter the following information:
- AWS Region (e.g.,
us-east-1) - AWS Key: Your Access Key ID
- AWS Secret: Your Secret Access Key
- Select "Key and Secret" for the authentication type
- AWS Region (e.g.,
- Click "Test Connection" to verify your settings
- Select your S3 bucket from the dropdown
- Save your settings
This method is more secure as it doesn't require storing AWS credentials in the database. It only works when OpenEMR is hosted on an AWS EC2 instance.
- Log in to the AWS Management Console
- Navigate to the IAM service
- In the left navigation pane, choose "Roles" and then "Create role"
- Select "AWS service" as the trusted entity
- Choose "EC2" as the service that will use this role
- Click "Next: Permissions"
- Attach the same S3 permissions as described in Method 1 (either custom policy or
AmazonS3FullAccess) - Click through "Tags" (optional)
- Give the role a name (e.g.,
OpenEMR-EC2-S3-Role) and description - Click "Create role"
- Go to the EC2 service in the AWS Console
- Select your instance running OpenEMR
- Choose "Actions" > "Security" > "Modify IAM role"
- Select the role you created
- Click "Save"
- In OpenEMR, navigate to Modules > Manage Modules
- Enable the "S3 Storage Solution" module if not already enabled
- Go to Modules > S3 Module
- Enter the following information:
- AWS Region (e.g.,
us-east-1) - this is still required - Select "Instance Profile" for the authentication type
- Leave the Key and Secret fields blank
- AWS Region (e.g.,
- Click "Test Connection" to verify your settings
- Select your S3 bucket from the dropdown
- Save your settings
If you haven't created an S3 bucket yet:
- Go to the S3 service in the AWS Console
- Click "Create bucket"
- Enter a unique bucket name (e.g.,
openemr-files-{your-organization}) - Select the appropriate region (should match the region in your OpenEMR settings)
- Configure bucket settings:
- Enable versioning (recommended)
- Enable server-side encryption (recommended)
- Block all public access (recommended for healthcare data)
- Click "Create bucket"
- Least Privilege: Give your IAM user or role only the permissions it needs
- Use Instance Profiles: When running on EC2, use IAM roles instead of access keys
- Rotate Keys: If using access keys, rotate them regularly
- Enable MFA: Require multi-factor authentication for the AWS account
- Enable S3 Encryption: Always use server-side encryption for S3 buckets containing PHI
- Enable S3 Versioning: Helps protect against accidental deletion or corruption
- Enable Access Logging: Monitor all access to your S3 bucket
- Connection Failed: Verify your region, credentials, and internet connectivity
- Access Denied: Check that your IAM permissions include the necessary S3 actions
- No Buckets Listed: Ensure your IAM policy includes the
s3:ListAllMyBucketspermission - Cannot Upload/Download: Verify bucket permissions and that your policy includes the appropriate object actions
- OpenEMR error logs:
/var/log/openemr/errors.log - AWS CloudTrail logs (for auditing AWS API calls)
- S3 Access Logs (if enabled on your bucket)
If you need assistance with AWS configuration, please consult: