This documentation outlines the mechanisms employed by the docker/genai-stack project to securely manage production secrets using environment variables and Docker configurations. The focus is on ensuring secrets are handled with care and not hardcoded into the codebase, promoting best practices in security.

Secret Management Strategy

The primary method for managing secrets in this project is through the use of environment variables, which are injected into the Docker containers at runtime. This approach minimizes the risk of exposing sensitive information in version control and allows for greater flexibility during deployment.

Step 1: Utilizing .env Files

Environment variables can be defined in a .env file located in the root directory of the project. This file should not be committed to version control. Create a .env file with the following sample configuration:

# .env
NEO4J_USERNAME=your_neo4j_username
NEO4J_PASSWORD=your_neo4j_password
OPENAI_API_KEY=your_openai_api_key
GOOGLE_API_KEY=your_google_api_key
OLLAMA_BASE_URL=http://host.docker.internal:11434
AWS_ACCESS_KEY_ID=your_aws_access_key_id
AWS_SECRET_ACCESS_KEY=your_aws_secret_access_key
AWS_DEFAULT_REGION=your_aws_default_region

Step 2: Referencing Environment Variables in docker-compose.yml

In the docker-compose.yml file, the services (e.g., bot, loader, api, database) reference the defined environment variables. These variables are populated from the .env file when starting the containers.

Here is an example snippet from the docker-compose.yml file that shows how the environment variables are utilized:

services:
  database:
    image: neo4j:5.11
    environment:
      - NEO4J_AUTH=${NEO4J_USERNAME-neo4j}/${NEO4J_PASSWORD-password}

  api:
    build:
      context: .
      dockerfile: api.Dockerfile
    environment:
      - NEO4J_URI=${NEO4J_URI-neo4j://database:7687}
      - NEO4J_USERNAME=${NEO4J_USERNAME-neo4j}
      - OPENAI_API_KEY=${OPENAI_API_KEY}

In this example, both the database and api services reference environment variables, which allows for secure and flexible configuration.

Step 3: Docker Secrets for Sensitive Information

For even more security, Docker secrets can be used with Docker Swarm. Secrets are encrypted during transit and at rest, providing a secure way to handle sensitive configurations.

To set up Docker secrets, use the following command:

echo "your_openai_api_key" | docker secret create openai_api_key -

Access the secret in your docker-compose.yml as follows:

version: '3.1'

services:
  api:
    image: your_image
    secrets:
      - openai_api_key

secrets:
  openai_api_key:
    external: true

In the container, the openai_api_key will be available at /run/secrets/openai_api_key, which your application can then read at runtime.

Step 4: Best Practices for Secrets Management

  1. Avoid Hardcoding Secrets: Never hardcode credentials or sensitive information in your source code. Use environment variables or secrets management tools.

  2. Restrict Environment Variable Access: Limit access to environment variables only to services that require them.

  3. Use Strong Keys and Passwords: Ensure that all secrets (API keys, passwords) are complex and not easily guessable.

  4. Regularly Rotate Secrets: Implement a policy for regularly rotating secret keys and passwords to mitigate potential exposure.

  5. Monitor Secret Usage: Keep track of where and how secrets are used and accessed within your services.

Conclusion

By employing environment variables and, when necessary, Docker secrets, the docker/genai-stack project secures sensitive information throughout its lifecycle. Following these practices minimizes the risk of exposure and helps maintain a secure production environment.

Source: docker-compose.yml provided in the documentation.