How to Implement Keyfile Authentication for a Secure MongoDB Sharded Cluster
Generate a 756-byte base64 keyfile, bake it into a custom MongoDB 6.0.2 Docker image with restrictive permissions, and launch every node with the --keyFile flag to enable internal cluster authentication and admin user access.
This guide walks you through implementing keyfile authentication in a containerized MongoDB sharded cluster using the minhhungit/mongodb-cluster-docker-compose repository. Keyfile authentication secures intra-cluster communication by requiring each mongod and mongos instance to authenticate using a shared secret before joining replica sets, creating the foundation for client authentication and production-ready security.
What Is Keyfile Authentication in MongoDB?
Keyfile authentication is MongoDB's built-in method for enabling internal authentication between cluster members. Each node presents a shared keyfile—containing a base64-encoded secret—to prove its identity when joining a replica set or sharded cluster. Once internal authentication is active, you can create user credentials for client applications, effectively securing both server-to-server and client-to-server communication.
Prerequisites and File Structure
Before implementing keyfile authentication, ensure you have Docker, Docker Compose, and OpenSSL installed. Clone the minhhungit/mongodb-cluster-docker-compose repository and navigate to the with-keyfile-auth/ directory, which contains the secure configuration files:
with-keyfile-auth/mongodb-build/Dockerfile– Custom image definition that embeds the keyfilewith-keyfile-auth/docker-compose.yml– Service orchestration with--keyFileflags for all nodeswith-keyfile-auth/scripts/auth.js– Admin user creation script executed against replica set members
Step-by-Step Implementation
Generate the Keyfile
Create a 756-byte base64-encoded keyfile using OpenSSL. This size meets MongoDB's minimum requirement for keyfile authentication.
openssl rand -base64 756 > mongodb-keyfile
chmod 400 mongodb-keyfile
Move the generated file to with-keyfile-auth/mongodb-build/auth/mongodb-keyfile. The restrictive chmod 400 permissions ensure only the file owner can read the key, satisfying MongoDB's security requirements documented in the repository's README.
Build the Custom Docker Image
The with-keyfile-auth/mongodb-build/Dockerfile embeds the keyfile into the MongoDB 6.0.2 image with the correct ownership and permissions.
# with-keyfile-auth/mongodb-build/Dockerfile
FROM mongo:6.0.2
COPY /auth/mongodb-keyfile /data
RUN chmod 400 /data/mongodb-keyfile
RUN chown 999:999 /data/mongodb-keyfile
The chown 999:999 command sets ownership to the mongo user (UID 999) inside the official Docker image, preventing permission denied errors when the server attempts to read the keyfile at startup.
Configure the Docker Compose Services
Every service in with-keyfile-auth/docker-compose.yml must include the --keyFile parameter in its command. This applies to config servers, shard replicas, and mongos routers.
# with-keyfile-auth/docker-compose.yml (router01 excerpt)
router01:
build:
context: mongodb-build
image: jin-mongo:6.0.2
container_name: router-01
command: mongos --port 27017 \
--configdb rs-config-server/configsvr01:27017,configsvr02:27017,configsvr03:27017 \
--bind_ip_all --keyFile /data/mongodb-keyfile
ports:
- 27117:27017
The --keyFile /data/mongodb-keyfile flag forces MongoDB to use the shared secret for internal authentication. Without this flag, nodes cannot join the replica sets, and the cluster will fail to initialize.
Initialize Replica Sets and Create Admin User
Start the cluster and initialize the config server replica set and shard replica sets using the provided scripts. Then create the admin user by executing auth.js against each member.
# Initialize config servers
docker-compose exec configsvr01 bash "/scripts/init-configserver.js"
# Initialize shards
docker-compose exec shard01-a bash "/scripts/init-shard01.js"
docker-compose exec shard02-a bash "/scripts/init-shard02.js"
docker-compose exec shard03-a bash "/scripts/init-shard03.js"
# Create admin user on each member
docker-compose exec configsvr01 bash "/scripts/auth.js"
docker-compose exec shard01-a bash "/scripts/auth.js"
# Repeat for shard02-a, shard03-a, and other members
The auth.js script located at with-keyfile-auth/scripts/auth.js executes db.createUser() with the root role on the admin database, granting full administrative privileges.
Connect with Authentication
Once the admin user exists, connect through the mongos router using the authentication database.
docker-compose exec router01 mongosh --port 27017 \
-u "your_admin" -p "your_password" --authenticationDatabase admin
All subsequent client connections must provide these credentials. The keyfile itself is used only for internal server-to-server authentication and should never be used for client connections or exposed to application layers.
Security Best Practices for Keyfile Authentication
When implementing keyfile authentication in production environments, adhere to these guidelines:
- Restrict keyfile permissions: Always set
chmod 400and ensure the file is owned by the MongoDB user (UID 999 in official Docker images). Never commit a production keyfile to source control. - Use strong base64 encoding: Generate keys with
openssl rand -base64 756to meet MongoDB's length requirements and ensure cryptographic randomness. - Automate user creation: Execute
auth.jsagainst every replica set member immediately after initialization to prevent unsecured windows where the cluster accepts connections without authentication. - Rotate keys periodically: While MongoDB does not support online keyfile rotation, plan maintenance windows to update the shared secret across all nodes.
Summary
Implementing keyfile authentication in a MongoDB sharded cluster requires generating a secure shared secret, embedding it into a custom Docker image with strict permissions, and configuring every node to use the --keyFile parameter. The minhhungit/mongodb-cluster-docker-compose repository demonstrates this pattern by:
- Generating a 756-byte base64 keyfile with
openssl rand -base64 756 - Building a custom MongoDB 6.0.2 image that copies the keyfile to
/data/mongodb-keyfilewithchmod 400and ownership999:999 - Launching config servers, shards, and
mongosrouters with the--keyFile /data/mongodb-keyfileflag - Creating a root admin user via
with-keyfile-auth/scripts/auth.jsexecuted against each replica set member
Frequently Asked Questions
What is the minimum keyfile size for MongoDB authentication?
MongoDB requires keyfiles to contain at least 756 bytes of base64-encoded content (approximately 1024 characters when encoded). The openssl rand -base64 756 command generates exactly this amount, satisfying the minimum length requirement while ensuring cryptographic randomness suitable for production environments.
Why does MongoDB require specific file permissions on the keyfile?
MongoDB enforces strict file permission checks for security reasons. The keyfile must be readable only by the user running the mongod or mongos process (typically UID 999 in official Docker images). Setting chmod 400 and chown 999:999 prevents unauthorized users from reading the shared secret, which would compromise the entire cluster's authentication mechanism and allow unauthorized nodes to join the replica set.
Can I add keyfile authentication to an existing running MongoDB cluster?
No, you cannot enable keyfile authentication on a running cluster without downtime. MongoDB requires the --keyFile parameter at startup to initialize internal authentication. To secure an existing cluster, you must generate the keyfile, update your Docker images or volume mounts to include it, restart all nodes with the --keyFile flag, and re-initialize replica sets. Plan a maintenance window for this operation, as the cluster will be unavailable during the transition.
How do I connect to a MongoDB cluster that uses keyfile authentication?
Once keyfile authentication is enabled and an admin user is created, clients must authenticate using valid credentials against the admin database. Use the mongosh command with the -u, -p, and --authenticationDatabase flags:
mongosh --host router01 --port 27017 \
-u "your_admin" -p "your_password" --authenticationDatabase admin
All client connections, including application drivers, must provide these credentials. The keyfile itself is used only for internal server-to-server authentication and should never be used for client connections or exposed to application layers.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →