# MongoDB Authentication (/docs/configuration/mongodb/mongodb_auth)

This guide will demonstrate how to use the `docker-compose.override.yml` file to allows us to enable explicit authentication for MongoDB.

For more info about the override file, please consult: [Docker Compose Override](/docs/configuration/docker_override)

**Notes:**

- The default configuration is secure by blocking external port access, but we can take it a step further with access credentials.
- As noted by the developers of MongoDB themselves, authentication in MongoDB is fairly complex. We will be taking a simple approach that will be good enough for most cases, especially for existing configurations of LibreChat. To learn more about how mongodb authentication works with docker, see here: https://hub.docker.com/_/mongo/
- This guide focuses exclusively on terminal-based setup procedures.
- While the steps outlined may also be applicable to Docker Desktop environments, or with non-Docker, local MongoDB, or other container setups, details specific to those scenarios are not provided.

**There are 3 basic steps:**

- Create an admin user within your mongodb container
- Enable authentication and create a "readWrite" user for "LibreChat"
- Configure the MONGO_URI with newly created user

## TL;DR

These are all the necessary commands if you'd like to run through these quickly or for reference:

<Callout type="abstract" title="TL;DR - All Commands" emoji='💻' collapsible>

```bash filename="Shut down container initially"
docker compose down
```

```bash filename="Start MongoDB container"
docker compose up -d mongodb
```

```bash filename="Open MongoDB shell on 'chat-mongodb' container"
docker exec -it chat-mongodb mongosh
```

```bash filename="Switch to admin database"
use admin
```

```bash filename="Create new admin user"
db.createUser({ user: "adminUser", pwd: "securePassword", roles: ["userAdminAnyDatabase", "readWriteAnyDatabase"] })
```

```bash filename="Exit MongoDB shell"
exit
```

```bash filename="Shut down container after setup"
docker compose down
```

```bash filename="Restart MongoDB container with authentication"
docker compose up -d mongodb
```

```bash filename="Log into MongoDB shell with credentials"
docker exec -it chat-mongodb mongosh -u adminUser -p securePassword --authenticationDatabase admin
```

```bash filename="Switch to LibreChat database"
use LibreChat
```

```bash filename="Create user in LibreChat database"
db.createUser({ user: 'user', pwd: 'userpasswd', roles: [ { role: "readWrite", db: "LibreChat" } ] });
```

```bash filename="Exit MongoDB shell after creating user"
exit
```

```bash filename="Shut down container after user creation"
docker compose down
```

```bash filename="Start all services with final settings"
docker compose up
```
</Callout>

### Example

Example `docker-compose.override.yml` file using the [`librechat.yaml` config file](/docs/configuration/librechat_yaml), [MongoDB Authentication](/docs/configuration/mongodb/mongodb_auth), and `mongo-express` for [managing your MongoDB database](/blog/2023-11-30_mongoexpress):

<Callout type="example" title="Example `docker-compose.override.yml` file" collapsible>

```yaml filename="docker-compose.override.yml"
version: '3.4'

services:
  api:
    volumes:
      - ./librechat.yaml:/app/librechat.yaml
    environment:
      - MONGO_URI=mongodb://user:userpasswd@mongodb:27017/LibreChat
  mongodb:
    command: mongod --auth
  mongo-express:
    image: mongo-express
    container_name: mongo-express
    environment:
      ME_CONFIG_MONGODB_SERVER: mongodb
      ME_CONFIG_BASICAUTH_USERNAME: admin
      ME_CONFIG_BASICAUTH_PASSWORD: password
      ME_CONFIG_MONGODB_URL: 'mongodb://adminUser:securePassword@mongodb:27017'
      ME_CONFIG_MONGODB_ADMINUSERNAME: adminUser
      ME_CONFIG_MONGODB_ADMINPASSWORD: securePassword
    ports:
      - '8081:8081'
    depends_on:
      - mongodb
    restart: always
```
</Callout>

## Step 1: Creating an Admin User

First, we must stop the default containers from running, and only run the mongodb container.

```bash filename="Stop all running containers"
docker compose down
```

```bash filename="Start mongodb container in detached mode"
docker compose up -d mongodb
```

> Note: The `-d` flag detaches the current terminal instance as the container runs in the background. If you would like to see the mongodb log outputs, omit it and continue in a separate terminal.

Once running, we will enter the container's terminal and execute `mongosh`:

```bash filename="Connect to the MongoDB shell"
docker exec -it chat-mongodb mongosh
```
You should see the following output:

```bash filename="Output"
~/LibreChat$ docker exec -it chat-mongodb mongosh
Current Mongosh Log ID: 65bfed36f7d7e3c2b01bcc3d
Connecting to:          mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+2.1.1
Using MongoDB:          7.0.4
Using Mongosh:          2.1.1

For mongosh info see: https://docs.mongodb.com/mongodb-shell/

test> 
```

Optional: While we're here, we can disable telemetry for mongodb if desired, which is anonymous usage data collected and sent to MongoDB periodically:

Execute the command below.

> Notes:
> - All subsequent commands should be run in the current terminal session, regardless of the environment (Docker, Linux, `mongosh`, etc.)
> - I will represent the actual terminal view with # example input/output or simply showing the output in some cases

Command:

```bash filename="Disable Telemetry"
disableTelemetry()
```

Example input/output:

```bash filename="example input/output"
test> disableTelemetry()
Telemetry is now disabled.
```

Now, we must access the admin database, which mongodb creates by default to create our admin user:

```bash filename="Switch to Admin Database"
use admin
```

> switched to db admin

Replace the credentials as desired and keep in your secure records for the rest of the guide.

Run command to create the admin user:

```bash filename="Create Admin User"
db.createUser({ user: "adminUser", pwd: "securePassword", roles: ["userAdminAnyDatabase", "readWriteAnyDatabase"] })
```

You should see an "ok" output.

You can also confirm the admin was created by running `show users`:

```bash filename="example input/output"
admin> show users
[
  {
    _id: 'admin.adminUser',
    userId: UUID('86e90441-b5b7-4043-9662-305540dfa6cf'),
    user: 'adminUser',
    db: 'admin',
    roles: [
      { role: 'userAdminAnyDatabase', db: 'admin' },
      { role: 'readWriteAnyDatabase', db: 'admin' }
    ],
    mechanisms: [ 'SCRAM-SHA-1', 'SCRAM-SHA-256' ]
  }
]
```

:warning: **Important:** if you are using `mongo-express` to [manage your database (guide here)](../../features/manage_your_database.md), you need the additional permissions for the `mongo-express` service to run correctly:

```bash filename="Grant Roles to Admin User"
db.grantRolesToUser("adminUser", ["clusterAdmin", "readAnyDatabase"])
```

Exit the Mongosh/Container Terminal by running `exit`:
```bash filename="Exit the Mongosh/Container Terminal"
admin> exit
```

And shut down the running container:
```bash filename="Shut down the running container"
docker compose down
```

## Step 2: Enabling Authentication and Creating a User with `readWrite` Access

We must now create/edit the `docker-compose.override.yml` file to enable authentication for our mongodb container. You can use this configuration to start or reference:

```yaml filename="docker-compose.override.yml"
version: '3.4'

services:
  api:
    volumes:
      - ./librechat.yaml:/app/librechat.yaml # Optional for using the librechat config file.
  mongodb:
    command: mongod --auth # <--- Add this to enable authentication
```

After configuring the override file as above, run the mongodb container again:

```bash filename="Start the MongoDB container"
docker compose up -d mongodb
```

And access mongosh as the admin user:

```bash filename="Connect to MongoDB container using mongo shell"
docker exec -it chat-mongodb mongosh -u adminUser -p securePassword --authenticationDatabase admin
```

Confirm you are authenticated:
```bash filename="Check MongoDB Connection Status Command"
db.runCommand({ connectionStatus: 1 })
```

```bash filename="example input/output"
test> db.runCommand({ connectionStatus: 1 })
{
  authInfo: {
    authenticatedUsers: [ { user: 'adminUser', db: 'admin' } ],
    authenticatedUserRoles: [
      { role: 'readWriteAnyDatabase', db: 'admin' },
      { role: 'userAdminAnyDatabase', db: 'admin' }
    ]
  },
  ok: 1
}
test>
```

Switch to the "LibreChat" database

> Note: This the default database unless you changed it via the MONGO_URI; default URI: `MONGO_URI=mongodb://mongodb:27017/LibreChat`

```bash filename="Switch to the LibreChat database"
use LibreChat
```

Now we'll create the actual credentials to be used by our Mongo connection string, which will be limited to read/write access of the "LibreChat" database. As before, replace the example with your desired credentials:

`db.createUser({ user: 'user', pwd: 'userpasswd', roles: [ { role: "readWrite", db: "LibreChat" } ] });`

You should see an "ok" output again.

You can verify the user creation with the `show users` command.

Exit the Mongosh/Container Terminal again with `exit`, and bring the container down:

```bash filename="End the current shell session"
exit
```

```bash filename="Stop the current Docker Compose services"
docker compose down
```

I had an issue where the newly created user would not persist after creating it. To solve this, I simply repeated the steps to ensure it was created. Here they are for your convenience:

```bash filename="Shut down container"
docker compose down
```

```bash filename="Start Mongo container"
docker compose up -d mongodb
```

```bash filename="Access MongoDB shell as admin"
docker exec -it chat-mongodb mongosh -u adminUser -p securePassword --authenticationDatabase admin
```

```bash filename="Switch to LibreChat database"
use LibreChat
```

```bash filename="Show current users in LibreChat database"
show users
```

```bash filename="Create a new user in LibreChat database"
db.createUser({ user: 'user', pwd: 'userpasswd', roles: [ { role: "readWrite", db: "LibreChat" } ] });
```

If it's still not persisting, you can try running the commands with all containers running, but note that the `LibreChat` container will be in an error/retrying state.

## Step 3: Update the `MONGO_URI` to Use the New Credentials

Finally, we add the new connection string with our newly created credentials to our `docker-compose.override.yml` file under the `api` service:

```yaml filename="docker-compose.override.yml"
    environment:
      - MONGO_URI=mongodb://user:userpasswd@mongodb:27017/LibreChat
```

So our override file looks like this now:

```yaml filename="docker-compose.override.yml"
version: '3.4'

services:
  api:
    volumes:
      - ./librechat.yaml:/app/librechat.yaml
    environment:
      - MONGO_URI=mongodb://user:userpasswd@mongodb:27017/LibreChat
  mongodb:
    command: mongod --auth
```

You should now run `docker compose up` successfully authenticated with read/write access to the LibreChat database

Example successful connection:
```bash filename="successful connection example"
LibreChat         | 2024-02-04 20:59:43 info: Server listening on all interfaces at port 3080. Use http://localhost:3080 to access it
chat-mongodb      | {"t":{"$date":"2024-02-04T20:59:53.880+00:00"},"s":"I",  "c":"NETWORK",  "id":22943,   "ctx":"listener","msg":"Connection accepted","attr":{"remote":"192.168.160.4:58114","uuid":{"uuid":{"$uuid":"027bdc7b-a3f4-429a-80ee-36cd172058ec"}},"connectionId":17,"connectionCount":10}}
```

If you're having Authentication errors, run the last part of Step 2 again. I'm not sure why it's finicky but it will work after a few tries.

