Python agent with Docker

  • Updated

Agent installation guide 

 

Overview

This guide offers examples for using Contrast Security’s Python agent with Docker. We encourage you to take this guide, make it your own, and distribute it to teams who both need to instrument Python applications and manage them through Docker. 

The main portion of the guide details the most popular methods customers use to instrument Python applications contained in Docker and see security data in Contrast.

There is also a lab section that describes how to instrument a sample python application called DjanGoat. It’s a good way to learn before proceeding with your own applications. You can instrument DjanGoat with Docker and see security data for this application in Contrast using the source code samples section at the end of this guide.

 

Main steps

Update the application’s Dockerfile:

  1. Add the Contrast Python agent
  2. Configure the agent
  3. Add authentication credentials for your environment

Instrument your application

  1. Run the containerized application with Contrast enabled and verify it works

Supported technologies

Before you begin, please be sure Contrast supports your preferred tools and environments for Python: Supported technologies for the Python agent

This guide assumes you have:

  • Some familiarity with DevOps practices and how Docker works
  • Access to the pypi repository for the Contrast agent

The information to instrument applications with the Python agent and see results in Contrast:
Install the Python agent

As a reminder, starting with version 2.3.0 of the agent, the package installation step requires the compilation of C extensions. This process is automatic, but it requires that certain software is installed in the target environment:
gcc, make, automake and autoconf. The package names may be different on different platforms. Installing your platform's version of build-essentialor installing system headers may be necessary. If running an agent on Alpine OS, libtool is required. Some base OS images, already come with these installed, but if not, they must be installed in the container prior to installation.

 

Instructions

To begin, update the Dockerfile for your application.

 


1) Add the Contrast Python agent

Here are two options to add the Contrast agent and basic configuration to a Docker image. Choose the one that works best for you.

 

Option 1: Add to the Dockerfile

In this approach, you add the Contrast agent to the application’s Dockerfile. You can add the most recent agent:

RUN pip install contrast-agent

OR target a specific version: 

RUN pip install contrast-agent==5.17.1

 

Example: Dockerfile configuration

FROM python:2.7-buster
# Install packages
RUN apt-get update -qq
RUN apt-get install -y build-essential
# Add application components
ADD ./app /myapp/app
# Install application and dependencies
RUN make install
# Add Contrast Agent and YAML Configuration
ADD ./contrast_security.yaml /myapp/contrast_security.yaml
RUN pip install contrast-agent
# Run the Application
ENTRYPOINT ["make","run"]

 

Option 2: Add to the requirements.txt

In this approach, you add the agent to the requirements.txt file. To do this:

  • Add the Contrast agent to the application’s requirements.txt file. Specify the agent version, if desired.
  • Add the requirements install to the docker file if not already present. 

Example: adding the agent to requirements.txt

contrast-agent==3.3.1
pip install -r requirements.txt

 

Configure the middleware

See Contrast documentation for the complete listing of framework specific configurations: Configure middleware

Example: updating settings.py in Django middleware

MIDDLEWARE = [
  'contrast.agent.middlewares.django_middleware.DjangoMiddleware'
]

 


2) Configure the agent

There are different values you can use to configure Contrast agents. This is the order of precedence, and each level overrides the next: 1 is highest.

  1. Corporate rule (e.g., expired license overrides assess.enable)
  2. Environment variable value
  3. YAML configuration file value
  4. Contrast UI value
  5. Default value

Order of precedence is explained more here:
Order of precedence

We recommend a mixed approach:

  • Keep the common configuration in the YAML file so it can be placed in the base image. 
  • Use environment variables for authentication and application-specific settings.

Common configuration

This approach keeps a core set of configurations in the YAML file. These can be added to a base image and overridden by environment variables when needed. 

 

To do this:

  1. Add a base service and logging configuration:
agent:
 logger:
   path: /proc/1/fd/1
   level: INFO
   progname: Contrast Agent
 security_logger:
   path: /proc/1/fd/1
   level: ERROR
 service: 
   host: localhost
   port: 30555
   logger: 
     path: /proc/1/fd/1
     level: INFO
application:
  path: /myapp

 

  1. Copy the edited YAML into the base image Dockerfile:

This can be copied into any of the following locations in the container:

  • <approot>/contrast_security.yaml
  • /etc/contrast_security.yaml
  • /etc/contrast/python/contrast_security.yaml

For more options, see Contrast documentation:

Order of precedence

Example:

COPY WORKSPACE/contrast_security.yaml approot/contrast_security.yaml

 

Application-specific configuration

To set an application-specific configuration, use the environment variables in the application’s container. These are some common configuration options. NOTE: use double-underscores here.

For more, see Contrast documentation: Python-specific configuration

  • Application name: Specify the application name reported to Contrast
    CONTRAST__APPLICATION__NAME
  • Application group: Specify the application access group for this application during onboarding. NOTE: Application access groups have to be created first in Contrast.
    CONTRAST__APPLICATION__GROUP
  • Application tags: Add labels to an application
    CONTRAST__APPLICATION__TAGS
  • Server name: Specify the server name reported to Contrast
    CONTRAST__SERVER__NAME
  • Server environment: specify in which environment the application is running. Valid values for this configuration are: Development, QA and Production. CONTRAST__SERVER__ENVIRONMENT
  • Server tag: Add labels to the server
    CONTRAST__SERVER__TAG


3) Add authentication credentials for your environment

For the Python agent to send data to Contrast, it needs an API URL and agent credentials for authentication to the server. This is sensitive data and should be treated carefully.

CONTRAST__API__URL=https://app.contrastsecurity.com/Contrast
CONTRAST__API__API_KEY={Your API KEY}
CONTRAST__API__SERVICE_KEY={Your Service key}
CONTRAST__API__USER_NAME={Your agent user}

You can get API values (agent keys) from Contrast or by downloading a YAML file for the Python agent. For more, see Contrast documentation: Find the agent keys

 


4) Instrument your application

You can now run the application image with Contrast enabled. Contrast will instrument your application during startup and begin reporting security vulnerabilities to Contrast.

 

You can verify that Contrast is running by checking the container log. You should see messages such as:

web_1  | Django version 1.11.1, using settings 'pygoat.settings'
web_1  | Starting development server at http://0.0.0.0:8000/
web_1  | Quit the server with CONTROL-C.
web_1  | 2020-08-28T14:43:02+0000 [Contrast Security] (base_middleware.py:log_initialize:541) - INFO - Initializing Contrast Agent DjangoMiddleware [id=140453305847952]
web_1  | 2020-08-28T14:43:02+0000 [Contrast Security] (base_middleware.py:log_initialize:544) - INFO - Contrast Python Agent Version: 3.3.1
web_1  |
web_1  | 2020-08-28T14:43:02+0000 [Contrast Security] (configuration_utils.py:load_yaml_config:59) - INFO - Loading configuration file: /myapp/contrast_security.yaml
web_1  | 2020-08-28T14:43:02+0000 [Contrast Security] (settings_state.py:init:74) - INFO - Contrast Agent finished loading settings.
web_1  | 2020-08-28T14:43:02+0000 [Contrast Agent] (service_client.py:start_service:90) - INFO - Attempted to start bundled Contrast Service for application DjanGoat-Test.
web_1  | 2020-08-28T14:43:02+0000 [Contrast Agent] (service_client.py:start_service:94) - INFO - If socket already exists at ('127.0.0.1', 30555), will attempt to connect to that instead
web_1  | 2020-08-28T14:43:02+0000 [Contrast Agent] (service_client.py:initialize_and_send_messages:132) - INFO - Will communicate with Contrast Service
web_1  | 2020-08-28T14:43:02.406Z       INFO    Initializing working directory  {"dir": "/myapp"}
web_1  | 2020-08-28T14:43:02.406Z       INFO    Config: loading file    {"path": "contrast_security.yaml"}
web_1  | setting logger level to: INFO
web_1  | 2020-08-28T14:43:02.407Z       INFO    contrast-service: BUILD {"progname": "Contrast Service", "version": "2.11.1", "buildTime": ""}
web_1  | 2020-08-28T14:43:02.407Z       INFO    Building timer for orphan request cleanup       {"progname": "Contrast Service", "cleanupMs": 5000}
web_1  | 2020-08-28T14:43:02.407Z       INFO    Building timer for orphan app cleanup   {"progname": "Contrast Service", "time": 5000}
web_1  | 2020-08-28T14:43:03.384Z       INFO    Creating New Application Server {"progname": "Contrast Service", "uuid": "c7189c0d-fd0b-4c12-98d7-bc8ce7d33ba7", "serverName": "Docker", "clientId": "DjanGoat-Test-8", "pid": 10}
web_1  | 2020-08-28T14:43:03.908Z       INFO    setting new server features for context {"progname": "Contrast Service", "uuid": "c7189c0d-fd0b-4c12-98d7-bc8ce7d33ba7", "serverName": "Docker"}
web_1  | 2020-08-28T14:43:03.908Z       INFO    starting event scanner  {"progname": "Contrast Service", "report": {}}
web_1  | 2020-08-28T14:43:03.910Z       INFO    Creating new application        {"progname": "Contrast Service", "uuid": "c7189c0d-fd0b-4c12-98d7-bc8ce7d33ba7", "serverName": "Docker", "appName": "DjanGoat-Test", "language": "Python", "clientId": "DjanGoat-Test-8", "pid": 10}
web_1  | 2020-08-28T14:43:03.910Z       INFO    AppCreate: creating and initializing new application    {"progname": "Contrast Service", "uuid": "c7189c0d-fd0b-4c12-98d7-bc8ce7d33ba7", "server_name": "Docker", "app_name": "DjanGoat-Test", "app_lang": "Python", "client_id": "DjanGoat-Test-8", "pid": 10}

 

Source code example: djangoat

Use this GitHub repository to learn how first. It contains a lab that walks you through different ways to instrument Python applications via Docker for security monitoring with Contrast.
https://github.com/marklacasse/DjanGoat/tree/docker

 

Known Issues

 

 

 

Was this article helpful?

0 out of 0 found this helpful

Have more questions? Submit a request