Managing Secrets

In Screenly/Playground, secrets are managed through environment variables and secure storage techniques. The following outlines the process of storing and accessing secrets in a production environment:

Step 1: Setting Environment Variables

Environment variables are a common method to manage configuration and sensitive information. In Docker, these variables can be defined in the Dockerfile or through external configuration files for added security.

Example

To set an environment variable in a Docker container, you can use the ENV directive in the Dockerfile. For instance, to manage a database connection string safely:

FROM python:3-alpine

WORKDIR /usr/src/app

# Set environment variables
ENV DATABASE_URL="your_production_database_url"
ENV SECRET_KEY="your_secure_secret_key"

COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

COPY app.py .

CMD python app.py

Step 2: Accessing Secrets in Code

In your application code (e.g., app.py), access the previously set environment variables using the os module in Python.

Example

Here’s how to retrieve the secrets defined in the Dockerfile:

import os

# Retrieve environment variables
DATABASE_URL = os.getenv('DATABASE_URL')
SECRET_KEY = os.getenv('SECRET_KEY')

def connect_to_database():
    # Implementation for connecting to the database with DATABASE_URL
    pass

def perform_sensitive_operation():
    # Use SECRET_KEY for encryption or sensitive operations
    pass

Step 3: Storing Sensitive Information Securely

It is crucial to avoid hardcoding sensitive information directly within the source code. Instead, leverage Docker secrets or a dedicated secret management tool like HashiCorp Vault or AWS Secrets Manager.

Example: Using Docker Secrets

When running in a Docker Swarm or other orchestrated environments, use Docker secrets for sensitive information:

  1. Create a secret:

    echo "your_secure_database_password" | docker secret create db_password -
    
  2. Reference the secret in your docker-compose.yml:

    version: '3.1'
    
    services:
      app:
        image: your_app_image
        secrets:
          - db_password
    
    secrets:
      db_password:
        external: true
    
  3. Accessing the secret in your app.py:

with open('/run/secrets/db_password', 'r') as file:
    DB_PASSWORD = file.read().strip()

Best Practices

  1. Avoid hardcoding secrets: Always pull secrets from environment variables or secret management tools.

  2. Limit scope: Only provide secrets to the components that need them.

  3. Rotate secrets regularly: Implement a strategy for secret rotation to minimize the risk of exposure.

  4. Use least privilege principle: Ensure your application has the minimal permissions necessary to operate.

By following these steps and best practices for managing secrets, applications within Screenly/Playground can maintain higher security standards in production environments.

Source: Dockerfile Configuration.