Production Secrets

Managing Production Secrets in Screenly/Anthias

In the Screenly/Anthias project, management of production secrets is achieved primarily through the use of environment variables and dedicated storage mechanisms which ensure the security and integrity of sensitive information during deployment.

1. Environment Variables

Environment variables play a crucial role in storing sensitive data such as API keys, database credentials, and secret keys. This approach avoids hardcoding sensitive information within the codebase.

Within the settings.py file of the Django framework, an example is provided for managing the Django secret key:

DEBUG = getenv('ENVIRONMENT', 'production') in ['development', 'test']

if not device_settings.get('django_secret_key'):
    secret_key = secrets.token_urlsafe(50)
    device_settings['django_secret_key'] = secret_key
    device_settings.save()

SECRET_KEY = device_settings.get('django_secret_key')

In this snippet:

  • The getenv function retrieves the environment variable ENVIRONMENT to set the debug level based on deployment.
  • If a django_secret_key does not exist in the device settings, a new secret key is generated using secrets.token_urlsafe to ensure its randomness and security.
  • The generated secret key is then saved in the device_settings, ensuring that the application uses this key in a secure manner.

2. Configuration Management

Configuration files are utilized to separate environment-specific settings from the code itself. For instance, the settings.conf file is leveraged to store configuration for various aspects of the application. This way, sensitive information can be amended without the need for deployment or code changes.

Example configuration loading might occur through a function implementing a fake settings environment for testing or operational purposes:

def fake_settings(raw):
    with open(CONFIG_FILE, mode='w+') as f:
        f.write(raw)

    try:
        import settings
        yield (settings, settings.settings)
        del sys.modules['settings']
    finally:
        os.remove(CONFIG_FILE)

In the above function:

  • A temporary settings file is created and written with the desired configuration.
  • The settings are temporarily loaded into the Django settings module for runtime use, thereby allowing easy manipulation and testing of various configurations in a controlled environment.

3. Using Docker Secrets and Environment Variables

When deploying Screenly/Anthias in production via Docker, sensitive data can also be managed using Docker secrets. This mechanism provides an additional layer of security by ensuring sensitive data is not exposed in the environment variables directly.

In the .github/workflows/sbom.yaml file, an example outlines how secrets are accessed during workflow operations:

env:
  TOKEN: ${{ secrets.SBOMIFY_TOKEN }}

This line shows how GitHub Actions can utilize secret variables securely without exposing them within the code. The TOKEN environment variable is populated with a value stored securely in GitHub secrets, minimizing risk while maintaining operational integrity.

4. Database Storage for Assets

The screenly.db file contains current assets information and might also store sensitive data related to asset configurations and metadata. The frequent use of SQLite as a lightweight database enables quick, efficient access to required data while ensuring that access to sensitive configurations remains controlled and logged.

Overall, these strategies illustrate a robust framework for managing production secrets within the Screenly/Anthias project, ensuring that sensitive data remains secure while allowing for flexibility and scalability in application deployment.

Reference