Skip to content

Commit

Permalink
Completing feature for Signing
Browse files Browse the repository at this point in the history
- Added ACS Policy for Signing Violation
- Added Quay to store signed Artifacts
- Added Tekton Chaining for build pipeline violation
- Added Cosign Signing
-Updated Readme to reflect feature changes
  • Loading branch information
MoOyeg committed Jul 11, 2022
1 parent 25446d0 commit 7282206
Show file tree
Hide file tree
Showing 30 changed files with 486 additions and 62 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
argocd/tmp-argocd-app-patch.yaml
bootstrap/test.yaml
bootstrap/test.yaml
install.sh
59 changes: 46 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ DevSecOps CICD pipeline demo using several technologies such as:

Vulnerability and configuration management methods included in this demo are the following:

* **Static application security testing (SAST)**, which analyzes code under development for vulnerabilities and quality issues.
* **Software composition analysis (SCA)**, which examines dependent packages included with applications, looking for known vulnerabilities and licensing issues.
* **Interactive application security testing (IAST)** and **dynamic application security testing (DAST)** tools, which analyze running applications to find execution vulnerabilities.
* **Configuration management** with analysis and management of application and infrastructure configurations in DevOps. Traditionally this was not used as a way to improve security. But properly managing configurations in a GitOps process can strengthen security by improving change controls, identifying configuration defects that can reduce the attack surface, and signing and tracking authorship for better accountability and opportunities to improve.
* **Image risk** is any risk associated with a container image. This includes vulnerable dependencies, embedded secrets, bad configurations, malware, or images that are not trusted.
- **Static application security testing (SAST)**, which analyzes code under development for vulnerabilities and quality issues.
- **Software composition analysis (SCA)**, which examines dependent packages included with applications, looking for known vulnerabilities and licensing issues.
- **Interactive application security testing (IAST)** and **dynamic application security testing (DAST)** tools, which analyze running applications to find execution vulnerabilities.
- **Configuration management** with analysis and management of application and infrastructure configurations in DevOps. Traditionally this was not used as a way to improve security. But properly managing configurations in a GitOps process can strengthen security by improving change controls, identifying configuration defects that can reduce the attack surface, and signing and tracking authorship for better accountability and opportunities to improve.
- **Image risk** is any risk associated with a container image. This includes vulnerable dependencies, embedded secrets, bad configurations, malware, or images that are not trusted.

This pipeline also improve security adding the following Open Source components:

Expand Down Expand Up @@ -95,6 +95,38 @@ These policies notification can be enabled by each system policy enabled in our

NOTE: By now the integration is manual. WIP to automate it.

## 6. Image Signing and Pipeline Signing

The original demo can be extended to use Cosign to Sign Image artifacts and also to sign the Tekton Build Pipeline via Tekton [Chaining](https://github.com/tektoncd/chains).

To extend the pipeline run the extend.sh script

```sh
./extend.sh
```

This will install Noobaa(Object Storage), Quay, and create a pod for cosign secret generation and verification.It will also install the tekton chains operator and integrate with ACS policies to generate violations for non signed images.

After installation the pipeline will build images to quay and have a task that signs the image.
<img align="center" width="750" src="docs/pics/pipeline-with-sign-task.png">

We also create a policy in ACS that will generate a violation for every unsigned image
<img align="center" width="750" src="docs/pics/acs-trusted-signature-violation.png">

Pipeline can be run normally via the Run the demo Instructions below.

After Pipeline is run Quay will show the image signed by Cosign
<img align="center" width="750" src="docs/pics/quay-with-signatures.png">

Since we have Tekton Chaining enabled, successfully completed Taskruns will also be annotated with cosign signatures and payload information.
<img align="center" width="750" src="docs/pics/taskrun.png">

And we can verify the signature and payload information of our last successful pipelinerun using the below command.

```sh
./demo.sh sign-verify
```

## Security Policies and CI Violations

In this demo, we can control the security policies applied into our pipelines, scanning the images and analysing the different deployments templates used for deploy our applications.
Expand All @@ -114,9 +146,10 @@ This ensures that we have the total control of our pipelines, and no image is pu
To show a complete demo and show the transition from a "bad image" to an image that passes the build enforcement, we can update the Tekton task of the image build and fix the image. In this example, we will be enabling the enforcement of the "Red Hat Package Manager in Image" policy in ACS, which will fail our pipeline at the image-check as both `yum` and `rpm` package managers are present in our base image.

Update the tekton task:

1. Delete the `s2i-java-11` task
1. With the UI: From the OpenShift UI, make sure you are in the cicd project and then go to Pipelines > Tasks and delete the `s2i-java-11` task.
2. With the Tekton cli `tkn task delete s2i-java-11`
1. With the UI: From the OpenShift UI, make sure you are in the cicd project and then go to Pipelines > Tasks and delete the `s2i-java-11` task.
2. With the Tekton cli `tkn task delete s2i-java-11`
2. Apply the new update task: `kubectl apply -f fix-image/s2ijava-mgr.yaml`
3. Re-run the pipeline, your deployment now succeeds.

Expand Down Expand Up @@ -188,20 +221,20 @@ NOTE: This pipeline will fail if you don't [disable the "Fixable at least Import

## Quick Video with the Demo

* [Option I - Complete CICD End2End process (Success)](https://youtu.be/uA7nUYchY5Q)
- [Option I - Complete CICD End2End process (Success)](https://youtu.be/uA7nUYchY5Q)

* [Option II - Failure CICD pipeline due to the ACS violation policy](https://youtu.be/jTRImofd6wQ?t=380)
- [Option II - Failure CICD pipeline due to the ACS violation policy](https://youtu.be/jTRImofd6wQ?t=380)

* [Openshift Coffee Break - ACS for Kubernetes - DevSecOps Way](https://youtu.be/43Mr30mXq0I?t=1955)
- [Openshift Coffee Break - ACS for Kubernetes - DevSecOps Way](https://youtu.be/43Mr30mXq0I?t=1955)

## Promote Pipeline and Triggers

* [Promote Pipeline](docs/promote.md)
* [Triggers in Dev Pipeline](doc/triggers.md)
- [Promote Pipeline](docs/promote.md)
- [Triggers in Dev Pipeline](doc/triggers.md)

# Troubleshooting

* [Check the Tshoot section](docs/tshoot.md)
- [Check the Tshoot section](docs/tshoot.md)

# Credits

Expand Down
12 changes: 0 additions & 12 deletions bootstrap/deploy_image_sign.yaml

This file was deleted.

15 changes: 7 additions & 8 deletions bootstrap/deploy_signing.yaml
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
---
- name: 'Extend Original Demo to Image and TaskRun Signing'
- name: 'Extend Original Demo for Image and TaskRun Signing'
hosts: localhost
connection: local
tasks:
- name: 'Install NooBaa'
include_role:
name: "ocp4-install-noobaa"

# - name: 'Install NooBaa'
# include_role:
# name: "ocp4-install-noobaa"

# - name: 'Install and configure Quay'
# include_role:
# name: "ocp4-install-quay"
- name: 'Install and configure Quay'
include_role:
name: "ocp4-install-quay"

- name: 'Install and Enable the infra for Signing and Tekton Chaining'
include_role:
Expand Down
71 changes: 68 additions & 3 deletions bootstrap/roles/ocp4-install-noobaa/tasks/noobaa-create.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,75 @@
- name: Create OpenShift Objects to install Noobaa
- name: Get cluster version
k8s_info:
api_version: config.openshift.io/v1
kind: ClusterVersion
name: version
register: r_cluster_version

- name: Set ocp4_cluster_version fact
set_fact:
ocp4_cluster_version: "{{ r_cluster_version.resources[0].status.history[0].version }}"

- name: Obtain Channel from Version
set_fact:
ocp4_channel: "{{ ocp4_cluster_version.split('.') }}"

- name: Set Openshift Channel
set_fact:
ocp4_channel: "stable-{{ ocp4_channel[0] + '.' + ocp4_channel[1] }}"

- name: Print OpenShift version
debug:
msg: "{{ ocp4_channel }}"

- name: Adapt to the openshift_cluster_version LESS than 4.9
when: ocp4_cluster_version is version_compare('4.9', '<')
block:
- name: Create OpenShift Objects to install Noobaa
k8s:
state: present
definition: "{{ lookup('template', item ) | from_yaml }}"
loop:
- ./templates/odf-namespace.yaml.j2
- ./templates/operatorgroup-storage.yaml.j2
- ./templates/ocs-subscription.yaml.j2

- name: Wait for NooBaa CRD to exist
kubernetes.core.k8s_info:
api_version: "apiextensions.k8s.io/v1beta1"
kind: CustomResourceDefinition
name: "noobaas.noobaa.io"
register: crds
until: crds.resources|length > 0
retries: 30
delay: 10

- name: Adapt to the openshift_cluster_version MORE than 4.9
when: ocp4_cluster_version is version_compare('4.9', '>=')
block:
- name: Create OpenShift Objects to install Noobaa
k8s:
state: present
definition: "{{ lookup('template', item ) | from_yaml }}"
loop:
- ./templates/odf-namespace.yaml.j2
- ./templates/operatorgroup-storage.yaml.j2
- ./templates/odf-subscription.yaml.j2

- name: Wait for NooBaa CRD to exist
kubernetes.core.k8s_info:
api_version: "apiextensions.k8s.io/v1"
kind: CustomResourceDefinition
name: "noobaas.noobaa.io"
register: crds
until: crds.resources|length > 0
retries: 30
delay: 10

- name: Create Noobaa Object
k8s:
state: present
definition: "{{ lookup('template', item ) | from_yaml }}"
loop:
- ./templates/odf-subscription.yaml.j2
- ./templates/odf-namespace.yaml.j2
- ./templates/noobaa-object.yaml.j2

- name: Wait Until NooBaa Object is Ready
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
name: ocs-operator
namespace: openshift-storage
spec:
channel: {{ ocp4_channel }}
installPlanApproval: Automatic
name: ocs-operator
source: redhat-operators
sourceNamespace: openshift-marketplace
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ metadata:
name: odf-operator
namespace: openshift-storage
spec:
channel: stable-4.10
channel: {{ ocp4_channel }}
installPlanApproval: Automatic
name: odf-operator
source: redhat-operators
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: operators.coreos.com/v1
kind: OperatorGroup
metadata:
name: openshift-storage-test
namespace: openshift-storage
spec:
targetNamespaces:
- openshift-storage
Empty file.
9 changes: 7 additions & 2 deletions bootstrap/roles/ocp4-install-quay/defaults/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ quay_admin_email: quayadmin@redhat.com
quay_admin_password: quaypass123
quay_registry_name: demo-registry
quay_org_name: cicd-demo
quay_secret_name: quay-demo-secret
quay_secret_name: quay-robot-secret
quay_repositories:
- spring-petclinic-dev
- spring-petclinic-stage
quay_robot_account: demo_robot
pipeline_namespace: cicd
csrf_pattern: ".*window.__token\ =\ '(.*)';.*"
#Can obtain status codes from Swagger of quay route/api/v1/discovery
quay_user_found_success_status_code: 200
Expand All @@ -21,4 +22,8 @@ quay_repo_created_success_status_code: 201
quay_robot_not_found_error_code: 400
quay_robot_found_success_status_code: 200
quay_robot_created_success_status_code: 201
quay_perm_success_status_code: 200
quay_perm_success_status_code: 200
secret_required_namespaces:
- cicd
- devsecops-dev
- devsecops-qa
26 changes: 26 additions & 0 deletions bootstrap/roles/ocp4-install-quay/tasks/configure-quay.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -393,3 +393,29 @@
- quay_perm_response.status != quay_perm_success_status_code
when:
- "'Cannot initialize user in a non-empty database' in init_output_msg"

- name: Delete any Previously Existing Quay Secret
kubernetes.core.k8s:
state: absent
api_version: v1
kind: Secret
namespace: "{{ item }}"
name: "{{ quay_secret_name }}"
wait: yes
loop: "{{ secret_required_namespaces }}"

#Create Quay Secret so other roles can use
- name: Create Quay Secret in Namespaces that require secret
shell: |
oc create secret docker-registry "{{ quay_secret_name }}" --docker-server="{{ quay_route }}" --docker-username="{{ quay_org_name }}+{{ quay_robot_account }}" --docker-password="{{ quay_robot_token }}" --docker-email="" -n "{{ item }}"
loop: "{{ secret_required_namespaces }}"

- name: Confirm Quay Secret is Created
kubernetes.core.k8s:
state: present
api_version: v1
kind: Secret
namespace: "{{ item }}"
name: "{{ quay_secret_name }}"
wait: yes
loop: "{{ secret_required_namespaces }}"
10 changes: 10 additions & 0 deletions bootstrap/roles/ocp4-install-quay/tasks/install-quay.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@
# ansible.builtin.set_fact:
# NOOBAA_SECRET_KEY: "{{ noobaa_secret_key.stdout }}"

- name: Wait for QuayRegistry CRD to exist
kubernetes.core.k8s_info:
api_version: "apiextensions.k8s.io/v1"
kind: CustomResourceDefinition
name: "quayregistries.quay.redhat.com"
register: crds
until: crds.resources|length > 0
retries: 30
delay: 10

- name: Create Quay Registry Object
k8s:
state: present
Expand Down
14 changes: 13 additions & 1 deletion bootstrap/roles/ocp4-install-signing/defaults/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,23 @@ tekton_chain_keys:
"artifacts.oci.format": "simplesigning"
#tekton_operator_namespace: openshift-pipelines
pipeline_namespace: cicd
dev_namespace: devsecops-dev
qa_namespace: devsecops-qa
tekton_operator_namespace: tekton-chains
tekton_chain_version: 'v0.10.0'
tekton_install_type: manifest
cosign_image: "image-registry.openshift-image-registry.svc:5000/{{ pipeline_namespace }}/cosign-pod:latest"
#cosign_image: "gcr.io/projectsigstore/cosign:v1.9.0"
secret_generate_name: signing-secrets
stackrox_central_admin_password: stackrox

quay_secret_name: quay-robot-secret
quay_registry_name: demo-registry
quay_org_name: cicd-demo
quay_project_name: quay-demo
quay_repositories:
- spring-petclinic-dev
- spring-petclinic-stage
secret_required_namespaces:
- cicd
- devsecops-dev
- devsecops-qa
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"policies": [
{
"id": "c8fde2c3-980c-40e3-bc9d-6245b13ab81e",
"name": "Trusted_Signature_Image_Policy",
"description": "Alert on Images that have not been signed",
"rationale": "rationale",
"remediation": "All images should be signed by our cosign-demo signature",
"disabled": false,
"categories": [
"Security Best Practices"
],
"lifecycleStages": [
"BUILD",
"DEPLOY"
],
"severity": "HIGH_SEVERITY",
"enforcementActions": [],
"notifiers": [],
"SORTName": "",
"SORTLifecycleStage": "",
"SORTEnforcement": false,
"policyVersion": "1.1",
"policySections": [
{
"sectionName": "Policy Section 1",
"policyGroups": [
{
"fieldName": "Image Signature Verified By",
"booleanOperator": "OR",
"negate": false,
"values": [
{
"value": "io.stackrox.signatureintegration.f9352803-d5c9-45d6-abe0-e1361a24559a"
}
]
}
]
}
],
"mitreAttackVectors": [],
"criteriaLocked": false,
"mitreVectorsLocked": false,
"isDefault": false
}
]
}
Empty file.
Loading

0 comments on commit 7282206

Please sign in to comment.