Apache Fineract document storage on Amazon S3

Move Fineract client documents and images from the local file system into Amazon S3 or an S3-compatible store, with the FINERACT_AWS settings, credentials, encryption and backup controls worked out before go-live.

On this page

How Apache Fineract document storage on Amazon S3 changes your deployment

**Fineract can store client documents and images in Amazon S3 or an S3-compatible store instead of the local file system, through its S3ContentStoreService and the FINERACT_AWS_* settings.** For a team running a containerized Fineract deployment, this matters because KYC scans and client photos written to a container volume or node disk are tied to that host. Scaling, rescheduling a pod, or losing a node can separate the files from the database rows that reference them. Moving content to object storage changes where the files live, who can reach them, and how they are backed up, so it belongs in the deployment design rather than being added after go-live.

The supported method is configuration, not custom code. The fineract-document module contains the S3ContentStoreService, and the documentation lists FINERACT_AWS_* properties for endpoint, region and credentials, including instance profile credentials. Your work is to choose the bucket layout, decide between instance profile credentials and explicitly provided keys, set the endpoint if you use an S3-compatible store, and then verify the result in a non-production build. Read the S3ContentStoreService source against the release you plan to run, because property names and behavior should be confirmed for that version before you write runbooks.

Treat the first build as a verification exercise. Upload a KYC document and a client image through the API, confirm the objects appear in the expected bucket and prefix, confirm the file is retrieved correctly, and confirm no new copies are created on local disk. Ask your storage provider which S3-compatible features your product supports before you assume parity with Amazon S3. Record these checks as the acceptance evidence for the storage change, because they become the baseline for the encryption, backup and access reviews covered later in this page.

What you need in place before enabling S3 storage for Fineract

Enabling S3 document storage touches the Fineract release you run, the cloud account that owns the bucket, the network path from Fineract pods to the storage endpoint, and the certificates that secure that path. Work through these cards before changing any Fineract configuration, so the storage switch does not become the first time these pieces meet.

Confirm the Fineract 1.x release

Fineract 1.15.0 is the current stable release on the project site, and official releases are created quarterly under the ASF release policy. Before you plan configuration, confirm in the source of your chosen release branch that the S3ContentStoreService class and the Amazon S3 configuration classes exist in the fineract-document module. Record the exact tag you will deploy, because the FINERACT_AWS_* property names are part of what you test and must match that build.

Bucket and region plan

Decide the bucket name, region, and whether client documents and images share one bucket with other data. Separate buckets make access policies, lifecycle rules and backup scopes easier to reason about. Confirm which region satisfies your data residency obligations, since moving documents later means copying objects and reconciling the references stored in Fineract's database.

IAM role or instance profile

Prefer an instance profile or pod identity over long-lived access keys. The documentation lists instance profile credentials among the FINERACT_AWS_* options. The role should allow only the object actions Fineract needs on the document prefix, and nothing on other buckets. Ask your cloud team to confirm how the role reaches Kubernetes pods in your cluster, since node-level roles are shared by every workload on that node.

Network path to the endpoint

Map every route from the Fineract pods to the S3 endpoint, including NAT gateways, VPC endpoints, egress firewall rules and any proxy. For an S3-compatible store such as Ceph, confirm the endpoint host name resolves inside the cluster and that the port is open from every Fineract pod, including read and batch instances. A timeout in the uploader usually points to this layer, not to Fineract.

TLS certificates for the endpoint

The Fineract documentation strongly encourages HTTPS only. If your S3-compatible endpoint uses an internal certificate authority, the Java truststore in the Fineract image must trust that CA before the first upload. Confirm certificate expiry dates and the renewal process, because an expired certificate breaks document uploads without changing any Fineract setting.

Existing documents and the local file system

Count the documents already stored on the local file system, and confirm with your team whether they will be copied, left in place or linked. Switching the storage backend does not move existing files by itself. Agree the cutover approach, and keep the old volume readable until you have verified the new store, so no client document becomes unreachable during the change.

Configuring the FINERACT_AWS settings in sequence

This sequence moves Fineract client documents from local disk to an S3 or S3-compatible bucket in a controlled order, so each layer is proven before the next one depends on it. The end state is a test tenant that stores, returns and lists documents in the bucket, followed by a planned migration of existing files.

  1. Confirm the S3 content store exists in your release

    Before changing any setting, check out the exact Fineract tag you run in production and confirm that the fineract-document module contains S3ContentStoreService and its Amazon S3 configuration classes. The platform documentation at the Fineract docs site describes the FINERACT_AWS_* properties, so cross-check the names against your release. Do this in a non-production environment with the same image or build. Done means you can point to the class and the property names for that version in writing, which goes into your change record.

  2. Set endpoint, region and bucket properties

    The platform team sets the FINERACT_AWS_* environment variables that cover the endpoint, region and bucket for the non-production deployment, using the names confirmed in the previous step. For an S3-compatible store such as Ceph, the endpoint value points at that store's gateway, and the region value must match what that service expects. Store these values in your configuration management, not in an image. Done means the running Fineract instance starts cleanly and the logs show no configuration errors for the document store.

  3. Choose instance profile or static keys

    The security owner and the platform team decide how Fineract authenticates to the bucket. Instance profile credentials, where the runtime supplies temporary credentials through its IAM role, avoid long-lived keys in environment variables and are the preferred option where the platform supports them. Static access keys need a rotation owner, a secret store and a documented revocation step. Confirm which credential source your chosen S3-compatible store supports. Done means the decision and the credential owner are recorded, and the chosen method is the only one configured.

  4. Point a test tenant at S3

    Configure one non-production tenant to use the S3 document store and leave the other tenants on local storage for now. This isolates any failure to a single tenant and keeps the rest of the test environment usable. The client or document configuration for that tenant should be reviewed by the product owner so the test reflects a real document type, such as an identity scan. Done means the test tenant reports the S3 store as active and other tenants still behave as before.

  5. Upload and retrieve a test document

    A tester attaches a non-sensitive synthetic document to a test client through the Fineract API, then retrieves it through the same API. The retrieval should return the file with the expected content and type, and the response should not depend on any local copy. This confirms the full path of write, store and read, not just that the service started. Record the request, the response status and the document identifier. Done means the document is readable through the API with matching content.

  6. Verify the object in the bucket

    The storage administrator lists the bucket with the tool your platform provides and confirms that an object for the test document exists under the expected key prefix. The administrator also checks that the object size matches the uploaded file and that the bucket's encryption and access settings are the ones your security standard requires. Confirm with your storage vendor how the key prefix is built, since this matters for backup and restore. Done means the object is visible in the bucket with the expected size and settings.

  7. Migrate existing local files after sign-off

    Only after the test tenant passes the write, read and bucket checks, plan the move of existing local documents. Copy files to the bucket, then retrieve a sample through the API for each tenant and compare it with the source. Keep the local copies until the sample and reconciliation checks pass and your retention rules allow removal. Confirm the exact migration approach for your release with the platform documentation, since the import mechanism for existing files is not covered by the properties themselves. Done means a signed-off reconciliation for every tenant, with local copies kept under the agreed retention rule.

How Fineract hands documents to the S3 content store

The key point for this section is that Fineract splits a document into two parts. The file content goes to the content store that is configured for the deployment, while the document metadata (name, description, parent entity, file name, content type, and the storage location that identifies the stored object) stays in the Fineract database. The document module chooses the store at runtime through its content store service layer, so the same API calls for uploading, listing and downloading a client's documents work whether the bytes sit on the local file system or in an S3 bucket. Verify the routing in the content store service classes of the fineract-document module, starting with the S3 implementation in the S3ContentStoreService source. Confirm the behavior against the release you deploy, since the code path may differ between versions.

Because metadata remains in PostgreSQL, the database and the bucket are two halves of one record. A restore of the database without the matching objects produces documents that appear in the client's file list but fail on download. A restore of the bucket without the database leaves orphaned objects that no screen can reach. Plan the two backups together: take the database snapshot and the bucket state from the same point in time, or document the acceptable skew and the reconciliation query you will run after a restore. Ask whether your S3-compatible platform supports versioning or object lock, because those settings decide whether a deleted object can be recovered when metadata still points to it. The practical consequence is that the storage decision reaches into operations. The bucket name, region, endpoint and credentials are read from configuration, so a change of bucket or endpoint is a configuration change that must be tested against existing metadata, not a simple file copy. Confirm with your Fineract platform team how the storage location is recorded for each document, and run a restore drill that downloads a sample of documents from each client category before go-live.

Choosing between instance profile credentials and static keys

On AWS, the preferred pattern is to let the runtime obtain temporary credentials from an IAM role instead of storing a long-lived access key. On EC2, an instance profile supplies the credentials. On Kubernetes, the team must confirm whether pods inherit the node role or receive a role through their service account. Either way, the FINERACT_AWS_* properties for region and endpoint are set in configuration, and the credential fields are left unset so the default provider chain resolves the role. Review the Fineract platform documentation for the exact property names in the release you deploy.

  • Rotation: Temporary role credentials rotate automatically. Confirm that no static key exists in a Kubernetes secret, environment file or image layer from an earlier test.
  • Permission scope: Confirm the role allows only the bucket and prefix Fineract uses, with the object actions the content store needs and no bucket administration rights.
  • Node sharing: If a node role is shared by other workloads, confirm whether those workloads can also reach the document bucket, and separate them if they should not.
  • Injection path: Confirm the cluster's mechanism for role assignment and record who can change it.
  • Encryption settings: Confirm the bucket's default encryption and whether a customer-managed key is required, since the key policy then becomes part of the access model.

Check that a test upload and download succeed using only the role, and that the same test fails from a workstation with no role attached.

Mapping FINERACT_AWS settings to your storage model

This table maps each group of Fineract S3 settings to its source of truth, owner, secret store location and the environment where it is set. Read each row as a question to answer before go-live, and use the tenant and prefix row to confirm how documents from different tenants stay apart in the bucket.

Setting groupSource of truth and ownerSecret store locationWhere it is set
Endpoint (FINERACT_AWS_* endpoint)Platform team records the S3 or S3-compatible endpoint URL per environment; blank or default for native AWSNot secret; keep in environment configuration and version controlDeployment manifest or container environment for each write and read instance
Region (FINERACT_AWS_* region)Cloud or storage team, matching the bucket's region and data residency decisionNot secret; record in the architecture registerEnvironment configuration for every Fineract instance that stores or reads documents
Bucket and prefixApplication owner defines bucket naming; prefix carries the tenant identifier and document typeNot secret; document the naming scheme in the storage designEnvironment configuration; confirm the tenant prefix pattern in the S3ContentStoreService source before relying on it
Access key and secret keySecurity team issues a dedicated IAM user or equivalent with bucket-scoped permissionsVault or cloud secrets manager, injected at runtime, never in images or GitRuntime secret injection on write and batch instances; read instances only if they serve documents
Instance profile credentialsCloud platform team attaches an IAM role to the compute nodes running FineractNo static secret; trust policy and role permissions are the controlNode or pod identity configuration; confirm with the platform documentation which profile source Fineract uses
Tenant separationData owner decides between one bucket with prefixes or one bucket per tenant, based on isolation and access needsNot applicable; bucket policies and IAM conditions carry the controlBucket policy and prefix design, reviewed with each new tenant onboarding
Encryption and key settingsSecurity team sets bucket encryption and key ownership; confirm which options Fineract supportsCustomer managed keys, if chosen, live in the key management service with restricted useBucket configuration and key policy, not Fineract properties, unless the documentation lists them

Securing encryption, credentials and bucket access

Client documents and KYC images are sensitive records, so the bucket, its encryption and the credentials Fineract uses to reach it need to be controlled together. The cards below cover access policy, encryption and key ownership, public access, transport, key rotation and keeping secrets out of images.

Least-privilege IAM policy for one bucket

Give the Fineract runtime identity only the object actions it needs on the document bucket, such as reading, writing and deleting objects under its prefix, and nothing on other buckets. Avoid wildcard actions and resources. Where Fineract runs on AWS with instance profile credentials, check that the role attached to the instance or pod cannot be assumed by other workloads. Ask your team to test the policy against each document operation Fineract performs before go-live, since a narrow policy that blocks uploads fails quietly for staff.

Server-side encryption and key ownership

Decide whether the bucket uses provider-managed keys or customer-managed keys held in your key service, and who may disable or rotate them. Customer-managed keys add a control point but also a dependency: if the key is disabled or access to it is lost, Fineract cannot read its documents. Confirm with your cloud provider or storage vendor which encryption modes the Fineract S3 path supports, and document where the key policy is defined.

Blocking public access on the bucket

Client documents should never be reachable by anonymous or cross-account requests. Enable the provider's block-public-access controls at the account and bucket level, and review bucket policies and access control lists for any grant to everyone. Confirm that Fineract serves documents through its own authorized API rather than through direct object links, so that a leaked URL does not expose a client file.

TLS to the storage endpoint

Fineract's documentation strongly encourages HTTPS only, and the same principle applies to traffic between Fineract and the object store. Use an HTTPS endpoint for the S3 or S3-compatible service, verify certificates against your trusted authority, and avoid disabling verification in client settings. For an internal Ceph or other S3-compatible store, confirm the TLS configuration with the storage vendor and test it from the Fineract runtime, not from an administrator workstation.

Rotating static access keys

If you use static access keys rather than instance profile credentials, record who issued them, where they are stored and when they must change. Plan a rotation procedure that issues a new key, updates the secret store, restarts or reloads Fineract, confirms uploads and downloads work, and then deactivates the old key. Ask your team to confirm how the Fineract version you run reads these credentials, so rotation does not require a rebuild.

Keeping secrets out of images

Do not bake storage credentials, the development login or the default mifos account password into the Fineract container image or its build layers. Pass credentials at runtime from a secret manager or orchestrator secret, and change the default login before any real deployment. Scan built images and their history for stray keys, and confirm that logs and configuration dumps do not print the credential values.

Common failures when Fineract cannot write or read documents in S3

This table pairs each symptom an operator sees when Fineract document handling breaks against S3 with the most likely cause and the first check to run. Read it in order of symptom, starting with the logs and configuration before changing credentials or network rules. The main takeaway is that most failures trace to configuration values or to local storage still being in use, and both can be confirmed within minutes.

SymptomLikely causeFirst check
Upload error when creating a client documentBucket name, endpoint or region property does not match the bucket, or the S3 client cannot reach the endpointCompare the FINERACT_AWS_* values with the bucket's actual region and endpoint, then test connectivity from the Fineract pod
Access denied on upload or downloadCredentials or instance profile lack s3:PutObject or s3:GetObject permission on the bucket or prefixReview the IAM policy attached to the identity Fineract uses and confirm the bucket and key prefix in the resource ARN
Access denied only for some filesBucket policy or KMS key policy denies the caller, often after encryption settings changedCheck whether the bucket uses SSE-KMS and confirm the Fineract role has permission to use that key
Requests fail with a signature or region mismatch errorRegion property differs from the bucket region, or clock skew on the hostConfirm the region in configuration matches the bucket and verify the node time is synchronized
TLS or certificate trust failure with an S3-compatible storeStore uses a private or internal certificate authority that the Fineract JVM does not trustConfirm the endpoint certificate chain and import the CA into the Java truststore used by the Fineract container
Connection timeout or unknown hostEndpoint URL points at the wrong host, the store is not reachable from the cluster network, or DNS does not resolveResolve the endpoint from inside the pod and test the port with the network policy in place
Documents missing after a pod restartDocuments were written to the local file system, which is ephemeral in the container, so S3 storage was never activeConfirm the S3 storage setting is active in the running configuration and check the bucket for newly created objects
Older documents not visible after switching to S3Existing files remain on the local volume and were not copied to the bucketInventory existing document records and the local path, then plan a one-time copy and verify object counts

Backing up Fineract metadata and S3 documents together

A restore of a Fineract deployment that stores documents in Amazon S3 needs two sets of data that must match: the PostgreSQL database, which holds the client, loan and document metadata that points to each object, and the S3 objects themselves. Restoring one without the other produces broken references. A database restored to a point in time can name objects that no longer exist, and objects restored from a later snapshot can be left without a record that points to them. Plan the two backups as one recovery unit, with a agreed recovery point that both sides can reach, and write down which system is the source of truth if they disagree.

Confirm three controls before go-live. First, whether bucket versioning is enabled, so that overwritten or deleted objects can be recovered, and how long noncurrent versions are kept. Second, whether objects are copied to a second bucket or region through replication, and whether that copy is encrypted with a key the restore team can use. Third, how the PostgreSQL backup schedule lines up with the replication lag and version history of the bucket, so that the database and object store can be restored to the same point. Set these values yourself based on your recovery objectives and your regulator's record retention rules. Also confirm with your storage provider how replication handles deletes, since a delete replicated quickly can remove the only copy.

Test the restore before you rely on it. A realistic exercise restores the database and bucket to a separate environment, then selects a sample of document records across several clients and document types and checks that each one resolves to an object with the expected content. Include documents uploaded just before the recovery point and documents uploaded earlier. Record the sample, the time each step took and every mismatch, and repeat the test after changes to the storage configuration. The Fineract documentation at Apache Fineract platform documentation is the place to confirm how the content store is configured in the release you run.

Questions teams ask about Fineract S3 document storage

Does the Apache Fineract version we run include the S3 document storage classes?

Confirm it against the release you plan to deploy before you scope the work. The Fineract source includes an S3ContentStoreService in the fineract-document module and Amazon S3 configuration classes, so check that your version contains them and that the FINERACT_AWS_* properties appear in its documentation. Fineract 1.15.0 is the current stable release on the project website, and official releases are created quarterly. If you run an older 1.x release, check the source tree for the same classes rather than assuming they are present, and plan any upgrade as a separate, tested step.

What drives the cost of moving Fineract documents to Amazon S3?

The cost has four main parts: configuration and testing of the S3 path, migration of files already stored on the local file system, the security review of IAM roles, encryption and bucket policies, and ongoing storage and request charges from your cloud provider. The configuration work is usually small compared with the other three. The largest variables are the number and size of existing client documents and images, how many environments need separate buckets, and how many approval steps your security team requires. Ask any partner to separate one-time work from recurring cloud spend in the quote.

How long does an S3 document storage change usually take?

The duration depends on the size of the existing document store, the state of your cloud accounts and the speed of your security review, so no fixed timeline applies. Configuration in a test environment can proceed quickly once IAM roles and buckets exist. Migration of existing files, reconciliation of file paths and verification of retrieval typically take longer than configuration, and a security review can add time before production access is approved. Ask for a written schedule that shows each of these steps as a separate milestone.

What must our team supply before a partner can configure S3 storage?

You need working cloud accounts for each environment, named IAM owners who approve roles and policies, and a data classification for client documents and KYC images. Classification determines the bucket encryption, retention, access logging and backup rules. You should also supply the network path between Fineract and the S3 endpoint, including any VPC endpoint or private network requirements, and a decision on whether the instance profile or static credentials will be used. Without these inputs, the scope cannot be fixed in writing.

Can an in-house platform team set up Fineract S3 storage on its own?

A team with experience in Fineract configuration, AWS IAM and Java application operations can usually do the configuration itself. The harder parts are the migration of existing files, the verification that every document type is retrievable after the switch, and the evidence your compliance or audit function will ask for. If the team lacks one of these skills, or the document volume is large, a fixed-scope engagement can cover the gap. DeployOpen implements and hardens self-hosted platforms in your own cloud accounts and prepares evidence for assessments, but it does not issue audit reports or certifications.

Which credentials should Fineract use to reach Amazon S3?

Prefer instance profile credentials on AWS, because they avoid long-lived access keys stored in configuration. The documentation lists FINERACT_AWS_* properties for endpoint, region and credentials, including instance profile support, so confirm the exact keys in the version you run. If you use static keys, store them in a secrets manager, restrict them to one bucket and rotate them on a schedule. Any S3-compatible store, such as an on-premises object store, needs the endpoint property set explicitly and its own access policy review.

How do we back up client documents stored in S3?

Backups for document storage need their own plan, separate from the PostgreSQL backups. The database holds file references and metadata, while the files live in the bucket, so a restore must bring both back to the same point in time. Ask whether your cloud provider offers versioning, replication to another region or a separate backup vault, and test a restore that retrieves a sample of documents through Fineract. Confirm retention periods with your compliance owner before you choose lifecycle rules.

How DeployOpen scopes and delivers Fineract S3 storage

DeployOpen plans and delivers Apache Fineract document storage on Amazon S3 inside your own AWS accounts or S3-compatible store, with the configuration, credentials, encryption and backup design written down before any change reaches a production instance. Engagements are fixed-scope, so the storage boundary, deliverables and timelines are agreed in writing first.

How we scope

  • We confirm which client documents and images currently sit on the local file system and how much data each category holds.
  • We agree the bucket layout, endpoint, region and whether the target is AWS S3 or an S3-compatible store you run.
  • The written scope names the credential method, encryption settings, backup approach and the cutover plan for existing files.

How we build

  • We set the FINERACT_AWS_* properties for endpoint, region and credentials in non-production environments first.
  • We prefer instance profile credentials where the deployment runs on AWS, and document any static key handling separately.
  • We test upload, retrieval and deletion of client documents against the S3ContentStoreService path before any production change.

How we hand over

  • You receive the configuration record, bucket policy design, credential ownership map and the test evidence from each environment.
  • Runbooks describe how to rotate credentials, change buckets and restore document objects from your backup copies.
  • We walk your platform, security and compliance staff through the design so they can operate and audit the setup themselves.

How we support

  • Ongoing support, upgrades and continuous testing are available as a retainer after handover.
  • A retainer can cover checks on Fineract upgrades that affect the document module and on bucket permissions over time.
  • Changes to storage settings after go-live follow a documented change request and are tested before they reach production.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.