Skip to main content

Agent Operator walkthrough

Before you begin

This topic provides a complete walk-through of installing the Contrast Agent Operator and injecting an example workload as a cluster administrator using vanilla Kubernetes.

To follow this example using OpenShift, the Kubernetes commands will need to be converted to their OpenShift equivalents. All commands are expected to execute within a Bash-like terminal.

You should have a basic understanding of how Kubernetes and related software work. You may need to adjust the instructions to meet your specific circumstances.

Step 1: Install the operator

To install the operator, the operator manifests must be applied to the cluster. Contrast provides a single-file installation YAML that can be directly applied to a cluster and provides reasonable defaults. Additional modifications may be desired based on your specific circumstances, in which case, a configuration management framework, such as Kustomize, is recommended.

Note

This single-file installation YAML will create and install into the contrast-agent-operator namespace. This namespace will be used later.

After waiting for cluster convergence, the operator should be ready in the Running status.

% kubectl -n contrast-agent-operator get pods

Output:

NAME                                      READY   STATUS    RESTARTS   AGE
contrast-agent-operator-57f5cfbf7-9svtt   1/1     Running   0          27s
contrast-agent-operator-57f5cfbf7-fp4vp   1/1     Running   0          39s

The operator is ready to be configured.

Step 2: Configure the operator

The operator must first be configured before injecting cluster workloads.

Kubernetes secrets are used to store connection authentication keys. Note that the name of the Secret created in the next part is  default-agent-connection-secret and is created in the contrast-agent-operator namespace.

% kubectl -n contrast-agent-operator \
        create secret generic default-agent-connection-secret \
        --from-literal=apiKey=TODO \
        --from-literal=serviceKey=TODO \
        --from-literal=userName=TODO

Output:

secret/default-agent-connection-secret created

Note

Replace TODO with the equivalent values for your Contrast server instance. Find the agent keys describes how to retrieve agent keys from the Contrast UI.

To complete the connection configuration, a ClusterAgentConnection is needed. Note that ClusterAgentConnection created in the next part is created in the contrast-agent-operator namespace and refers to the Secret's key values used above.

% kubectl apply -f - <<EOF
apiVersion: agents.contrastsecurity.com/v1beta1
kind: ClusterAgentConnection
metadata:
  name: default-agent-connection
  namespace: contrast-agent-operator
spec:
  template:
    spec:
      url: https://app.contrastsecurity.com/Contrast
      apiKey:
        secretName: default-agent-connection-secret
        secretKey: apiKey
      serviceKey:
        secretName: default-agent-connection-secret
        secretKey: serviceKey
      userName:
        secretName: default-agent-connection-secret
        secretKey: userName
EOF

Output:

clusteragentconnection.agents.contrastsecurity.com/default-agent-connection created

Note

The name of the ClusterAgentConnection is not important and can be named anything.

The operator is now configured and can inject agents into existing workloads.

Step 3: Inject workloads

This example will focus on injecting the Contrast Java agent into the Java sample application using a Deployment workload.

First, deploy the sample application to the cluster. Note that the Deployment created in the next part is created in the default namespace.

% kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-petclinic
  namespace: default
  labels:
    arbitrary-label: arbitrary-value
spec:
  selector:
    matchLabels:
      app: spring-petclinic
  template:
    metadata:
      labels:
        app: spring-petclinic
    spec:
      containers:
        - image: contrastsecuritydemo/spring-petclinic:1.5.1
          name: spring-petclinic
EOF

Output:

deployment.apps/spring-petclinic created

After waiting for cluster convergence, the deployed workload should be ready in the Running status.

% kubectl -n default get pods

Output:

NAME                                READY   STATUS    RESTARTS   AGE
spring-petclinic-77d97bdbd5-ts2cz   1/1     Running   0          15d

Next, the operator can be configured to inject the Java agent using an AgentInjector configuration entity. Note that the AgentInjector needs to be created in the same namespace that the previous Deployment was deployed into, default in this case.

% kubectl apply -f - <<EOF
apiVersion: agents.contrastsecurity.com/v1beta1
kind: AgentInjector
metadata:
  name: spring-petclinic-injector
  namespace: default
spec:
  type: java
  selector:
    labels:
      - name: arbitrary-label
        value: arbitrary-value
EOF

Output:

agentinjector.agents.contrastsecurity.com/spring-petclinic-injector configured

Checking the logs of the spring-petclinic-app Pod shows that the Contrast Java agent is now instrumenting the application.

% kubectl -n default logs Deployment/spring-petclinic             
Defaulted container "spring-petclinic" out of: spring-petclinic, contrast-init (init)
Picked up JAVA_TOOL_OPTIONS: -javaagent:/opt/contrast/contrast-agent.jar
[Contrast] Wed Dec 20 21:47:23 GMT 2023 Loading pre-packaged configuration
[Contrast] Wed Dec 20 21:47:23 GMT 2023 Couldn't find pre-packaged configuration.
[Contrast] Wed Dec 20 21:47:23 GMT 2023 Starting Contrast (build 6.1.1) Pat. 8,458,789 B2
[Contrast] Wed Dec 20 21:47:24 GMT 2023 Contrast logger configuration errors will be logged to stderr
[Contrast] Wed Dec 20 21:47:26 GMT 2023 Copyright: 2023 Contrast Security, Inc
[Contrast] Wed Dec 20 21:47:26 GMT 2023 Contact: support@contrastsecurity.com
[Contrast] Wed Dec 20 21:47:26 GMT 2023 License: Commercial
[Contrast] Wed Dec 20 21:47:26 GMT 2023 NOTICE: This Software and the patented inventions embodied within may only be used as part of
[Contrast] Wed Dec 20 21:47:26 GMT 2023 Contrast Security's commercial offerings. Even though it is made available through public
[Contrast] Wed Dec 20 21:47:26 GMT 2023 repositories, use of this Software is subject to the applicable End User Licensing Agreement
[Contrast] Wed Dec 20 21:47:26 GMT 2023 found at https://www.contrastsecurity.com/enduser-terms-0317a  or as otherwise agreed between
[Contrast] Wed Dec 20 21:47:26 GMT 2023 Contrast Security and the End User. The Software may not be reverse engineered, modified,
[Contrast] Wed Dec 20 21:47:26 GMT 2023 repackaged, sold, redistributed or otherwise used in a way not consistent with the End User
[Contrast] Wed Dec 20 21:47:26 GMT 2023 License Agreement.
[Contrast] Wed Dec 20 21:47:26 GMT 2023 The Contrast Java agent collects usage data in order to help us improve compatibility and security coverage.
[Contrast] Wed Dec 20 21:47:26 GMT 2023 The data is anonymous and does not contain application data. It is collected by Contrast and is never shared.
[Contrast] Wed Dec 20 21:47:26 GMT 2023 You can opt-out of telemetry by setting the CONTRAST_AGENT_TELEMETRY_OPTOUT environment variable to 'true' or '1'
[Contrast] Wed Dec 20 21:47:26 GMT 2023 Read more about Contrast Java agent telemetry: https://docs.contrastsecurity.com/en/java-telemetry.html 
[Contrast] Wed Dec 20 21:47:27 GMT 2023 Effective instructions: Assess=true, Protect=false, Observe=false
[Contrast] Wed Dec 20 21:47:27 GMT 2023 Contrast logger configuration errors will be logged to stderr
[Contrast] Wed Dec 20 21:47:41 GMT 2023 Starting JVM [18888ms]
              |\      _,,,--,,_
             /,`.-'`'   ._  \-;;,_
  _______ __|,4-  ) )_   .;.(__`'-'__     ___ __    _ ___ _______
|       | '---''(_/._)-'(_\_)   |   |   |   |  |  | |   |       |
|    _  |    ___|_     _|       |   |   |   |   |_| |   |       | __ _ _
|   |_| |   |___  |   | |       |   |   |   |       |   |       | \ \ \ \
|    ___|    ___| |   | |      _|   |___|   |  _    |   |      _|  \ \ \ \
|   |   |   |___  |   | |     |_|       |   | | |   |   |     |_    ) ) ) )
|___|   |_______| |___| |_______|_______|___|_|  |__|___|_______|  / / / /
==================================================================/_/_/_/
:: Built with Spring Boot :: 1.5.4.RELEASE
2023-12-20 21:47:45.651  INFO 1 --- [           main] o.s.s.petclinic.PetClinicApplication     : Starting PetClinicApplication v1.5.1 on spring-petclinic-77d97bdbd5-ts2cz with PID 1 (/spring-petclinic/spring-petclinic-1.5.1.jar started by root in /spring-petclinic)

Step 4: Uninstall the operator (optional)

To restore the original state of the cluster, first remove existing AgentInjectors.

% kubectl -n default delete agentinjector spring-petclinic-injector 

Output:

agentinjector.agents.contrastsecurity.com "spring-petclinic-injector" deleted

After which, the operator will restore all injected workloads to their previous non-instrumented state. Once the cluster converges, the operator can be safely removed.

% kubectl delete -f https://github.com/Contrast-Security-OSS/agent-operator/releases/latest/download/install-prod.yaml

Output:

namespace "contrast-agent-operator" deleted
customresourcedefinition.apiextensions.k8s.io "agentconfigurations.agents.contrastsecurity.com" deleted
customresourcedefinition.apiextensions.k8s.io "agentconnections.agents.contrastsecurity.com" deleted
customresourcedefinition.apiextensions.k8s.io "agentinjectors.agents.contrastsecurity.com" deleted
customresourcedefinition.apiextensions.k8s.io "clusteragentconfigurations.agents.contrastsecurity.com" deleted
customresourcedefinition.apiextensions.k8s.io "clusteragentconnections.agents.contrastsecurity.com" deleted
serviceaccount "contrast-agent-operator-service-account" deleted
clusterrole.rbac.authorization.k8s.io "contrast-agent-operator-service-role" deleted
clusterrolebinding.rbac.authorization.k8s.io "contrast-agent-operator-service-role-binding" deleted
service "contrast-agent-operator" deleted
deployment.apps "contrast-agent-operator" deleted
poddisruptionbudget.policy "contrast-agent-operator" deleted
mutatingwebhookconfiguration.admissionregistration.k8s.io "contrast-web-hook-configuration" deleted

See also