Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1e849976aa | |||
| 35ad38dda7 | |||
| 78f30b9608 | |||
| 749afaebf7 |
@@ -29,7 +29,16 @@ Install these separately in your cluster before using this chart:
|
|||||||
- DefectDojo, if you want report ingestion enabled
|
- DefectDojo, if you want report ingestion enabled
|
||||||
- MinIO or another S3-compatible store, if you want raw report uploads enabled
|
- MinIO or another S3-compatible store, if you want raw report uploads enabled
|
||||||
|
|
||||||
You will also need the corresponding credentials for Socket.dev, Pulumi, AWS or MinIO, and DefectDojo.
|
You will also need the corresponding credentials for Socket.dev, Pulumi, S3-compatible object storage, and DefectDojo.
|
||||||
|
|
||||||
|
## Reading the chart
|
||||||
|
|
||||||
|
If the Helm templates start to feel too abstract, use these two files together:
|
||||||
|
|
||||||
|
- [`helm/values.schema.json`](helm/values.schema.json) documents the expected shape and meaning of the values file.
|
||||||
|
- [`docs/rendered/default-clusterworkflowtemplate.yaml`](docs/rendered/default-clusterworkflowtemplate.yaml) shows the default rendered `ClusterWorkflowTemplate` without Helm directives in the way.
|
||||||
|
|
||||||
|
The rendered reference reflects the default values in `helm/values.yaml`, so optional storage, DefectDojo, and Infisical resources are intentionally omitted there.
|
||||||
|
|
||||||
## Validation workflow
|
## Validation workflow
|
||||||
|
|
||||||
@@ -84,7 +93,7 @@ defectdojo:
|
|||||||
|
|
||||||
Keep `storage.enabled` and `defectdojo.enabled` disabled until those services are actually installed and reachable. Keep `infisical.enabled` disabled until the operator is installed and your project identifiers are ready.
|
Keep `storage.enabled` and `defectdojo.enabled` disabled until those services are actually installed and reachable. Keep `infisical.enabled` disabled until the operator is installed and your project identifiers are ready.
|
||||||
|
|
||||||
If you do not use Infisical, create the `amp-security-pipeline-secrets` secret yourself before running the workflow.
|
If you do not use Infisical, create the `amp-security-pipeline-secrets` secret yourself before running the workflow. For storage uploads, the secret should contain `S3_ACCESS_KEY_ID` and `S3_SECRET_ACCESS_KEY`.
|
||||||
|
|
||||||
### 3. Deploy the chart
|
### 3. Deploy the chart
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
parameters:
|
parameters:
|
||||||
- name: fail-on-cvss
|
- name: fail-on-cvss
|
||||||
container:
|
container:
|
||||||
image: "{{ .Values.pipeline.toolsImage.repository }}:{{ .Values.pipeline.toolsImage.tag }}"
|
image: {{ include "template.tools-image" . | quote }}
|
||||||
imagePullPolicy: {{ .Values.pipeline.toolsImage.pullPolicy }}
|
imagePullPolicy: {{ .Values.pipeline.toolsImage.pullPolicy }}
|
||||||
command:
|
command:
|
||||||
- node
|
- node
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{{- define "template.tools-image" -}}
|
||||||
|
{{- printf "%s:%s" .Values.pipeline.toolsImage.repository .Values.pipeline.toolsImage.tag -}}
|
||||||
|
{{- end }}
|
||||||
@@ -4,23 +4,13 @@
|
|||||||
parameters:
|
parameters:
|
||||||
- name: working-dir
|
- name: working-dir
|
||||||
container:
|
container:
|
||||||
image: {{ .Values.images.pulumiCrossguard | quote }}
|
image: {{ .Values.images.pulumiCrossguard }}
|
||||||
env:
|
env:
|
||||||
- name: PULUMI_ACCESS_TOKEN
|
- name: PULUMI_ACCESS_TOKEN
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: amp-security-pipeline-secrets
|
name: amp-security-pipeline-secrets
|
||||||
key: PULUMI_ACCESS_TOKEN
|
key: PULUMI_ACCESS_TOKEN
|
||||||
- name: AWS_ACCESS_KEY_ID
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: amp-security-pipeline-secrets
|
|
||||||
key: AWS_ACCESS_KEY_ID
|
|
||||||
- name: AWS_SECRET_ACCESS_KEY
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: amp-security-pipeline-secrets
|
|
||||||
key: AWS_SECRET_ACCESS_KEY
|
|
||||||
command:
|
command:
|
||||||
- sh
|
- sh
|
||||||
- -c
|
- -c
|
||||||
@@ -29,7 +19,7 @@
|
|||||||
set -eu
|
set -eu
|
||||||
mkdir -p /workspace/reports
|
mkdir -p /workspace/reports
|
||||||
cd "/workspace/{{ `{{inputs.parameters.working-dir}}` }}"
|
cd "/workspace/{{ `{{inputs.parameters.working-dir}}` }}"
|
||||||
pulumi preview --policy-pack "{{ .Values.pulumi.policyPackPath }}" > /workspace/reports/pulumi-crossguard.json 2>&1 || true
|
pulumi preview --policy-pack {{ .Values.pulumi.policyPackPath | quote }} > /workspace/reports/pulumi-crossguard.json 2>&1 || true
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: workspace
|
- name: workspace
|
||||||
mountPath: /workspace
|
mountPath: /workspace
|
||||||
|
|||||||
@@ -1,19 +1,12 @@
|
|||||||
{{- define "template.upload-defectdojo" -}}
|
{{- define "template.upload-defectdojo" -}}
|
||||||
- name: upload-defectdojo
|
- name: upload-defectdojo
|
||||||
container:
|
container:
|
||||||
image: "{{ .Values.pipeline.toolsImage.repository }}:{{ .Values.pipeline.toolsImage.tag }}"
|
image: {{ include "template.tools-image" . | quote }}
|
||||||
imagePullPolicy: {{ .Values.pipeline.toolsImage.pullPolicy }}
|
imagePullPolicy: {{ .Values.pipeline.toolsImage.pullPolicy }}
|
||||||
|
envFrom:
|
||||||
|
- secretRef:
|
||||||
|
name: amp-security-pipeline-secrets
|
||||||
env:
|
env:
|
||||||
- name: DEFECTDOJO_URL
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: amp-security-pipeline-secrets
|
|
||||||
key: DEFECTDOJO_URL
|
|
||||||
- name: DEFECTDOJO_API_TOKEN
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: amp-security-pipeline-secrets
|
|
||||||
key: DEFECTDOJO_API_TOKEN
|
|
||||||
- name: DEFECTDOJO_PRODUCT_TYPE_NAME
|
- name: DEFECTDOJO_PRODUCT_TYPE_NAME
|
||||||
value: {{ .Values.defectdojo.productTypeName | quote }}
|
value: {{ .Values.defectdojo.productTypeName | quote }}
|
||||||
- name: DEFECTDOJO_PRODUCT_NAME
|
- name: DEFECTDOJO_PRODUCT_NAME
|
||||||
|
|||||||
@@ -1,28 +1,11 @@
|
|||||||
{{- define "template.upload-storage" -}}
|
{{- define "template.upload-storage" -}}
|
||||||
- name: upload-storage
|
- name: upload-storage
|
||||||
container:
|
container:
|
||||||
image: {{ .Values.images.awsCli | quote }}
|
image: {{ .Values.images.awsCli }}
|
||||||
|
envFrom:
|
||||||
|
- secretRef:
|
||||||
|
name: amp-security-pipeline-secrets
|
||||||
env:
|
env:
|
||||||
- name: AWS_ACCESS_KEY_ID
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: amp-security-pipeline-secrets
|
|
||||||
key: AWS_ACCESS_KEY_ID
|
|
||||||
- name: AWS_SECRET_ACCESS_KEY
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: amp-security-pipeline-secrets
|
|
||||||
key: AWS_SECRET_ACCESS_KEY
|
|
||||||
- name: MINIO_ROOT_USER
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: amp-security-pipeline-secrets
|
|
||||||
key: MINIO_ROOT_USER
|
|
||||||
- name: MINIO_ROOT_PASSWORD
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: amp-security-pipeline-secrets
|
|
||||||
key: MINIO_ROOT_PASSWORD
|
|
||||||
- name: REPORTS_BUCKET
|
- name: REPORTS_BUCKET
|
||||||
value: {{ .Values.storage.reportsBucket | quote }}
|
value: {{ .Values.storage.reportsBucket | quote }}
|
||||||
- name: REPO_NAME
|
- name: REPO_NAME
|
||||||
@@ -35,6 +18,8 @@
|
|||||||
args:
|
args:
|
||||||
- |
|
- |
|
||||||
set -eu
|
set -eu
|
||||||
|
export AWS_ACCESS_KEY_ID="${S3_ACCESS_KEY_ID:-}"
|
||||||
|
export AWS_SECRET_ACCESS_KEY="${S3_SECRET_ACCESS_KEY:-}"
|
||||||
commit_sha="${GIT_COMMIT_SHA:-unknown}"
|
commit_sha="${GIT_COMMIT_SHA:-unknown}"
|
||||||
report_date="$(date -u +%F)"
|
report_date="$(date -u +%F)"
|
||||||
sync_target="s3://${REPORTS_BUCKET}/${REPO_NAME}/${report_date}/${commit_sha}/"
|
sync_target="s3://${REPORTS_BUCKET}/${REPO_NAME}/${report_date}/${commit_sha}/"
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
{{- define "template.workflow.security-pipeline.tasks" -}}
|
||||||
|
- name: clone
|
||||||
|
template: clone-repo
|
||||||
|
arguments:
|
||||||
|
parameters:
|
||||||
|
- name: repo-url
|
||||||
|
value: {{ `{{workflow.parameters.repo-url}}` | quote }}
|
||||||
|
- name: git-revision
|
||||||
|
value: {{ `{{workflow.parameters.git-revision}}` | quote }}
|
||||||
|
- name: scanners
|
||||||
|
dependencies:
|
||||||
|
- clone
|
||||||
|
template: parallel-scanners
|
||||||
|
arguments:
|
||||||
|
parameters:
|
||||||
|
- name: working-dir
|
||||||
|
value: {{ `{{workflow.parameters.working-dir}}` | quote }}
|
||||||
|
- name: enforce-policy
|
||||||
|
dependencies:
|
||||||
|
- scanners
|
||||||
|
template: enforce-policy
|
||||||
|
arguments:
|
||||||
|
parameters:
|
||||||
|
- name: fail-on-cvss
|
||||||
|
value: {{ `{{workflow.parameters.fail-on-cvss}}` | quote }}
|
||||||
|
{{- if .Values.storage.enabled }}
|
||||||
|
- name: upload-storage
|
||||||
|
dependencies:
|
||||||
|
- scanners
|
||||||
|
template: upload-storage
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.defectdojo.enabled }}
|
||||||
|
- name: upload-defectdojo
|
||||||
|
dependencies:
|
||||||
|
- scanners
|
||||||
|
template: upload-defectdojo
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- define "template.workflow.parallel-scanners.tasks" -}}
|
||||||
|
{{- /* Scanner fan-out is data-driven from pipeline.scanners in values.yaml. */ -}}
|
||||||
|
{{- range $scanner := .Values.pipeline.scanners }}
|
||||||
|
- name: {{ $scanner }}
|
||||||
|
template: scan-{{ $scanner }}
|
||||||
|
arguments:
|
||||||
|
parameters:
|
||||||
|
- name: working-dir
|
||||||
|
value: {{ `{{inputs.parameters.working-dir}}` | quote }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- define "template.workflow.named-templates" -}}
|
||||||
|
{{- /* Keep the main workflow file focused on orchestration; implementations are included here. */ -}}
|
||||||
|
{{- range $scanner := .Values.pipeline.scanners }}
|
||||||
|
{{ include (printf "template.scan-%s" $scanner) $ }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.storage.enabled }}
|
||||||
|
{{ include "template.upload-storage" . }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.defectdojo.enabled }}
|
||||||
|
{{ include "template.upload-defectdojo" . }}
|
||||||
|
{{- end }}
|
||||||
|
{{ include "template.enforce-policy" . }}
|
||||||
|
{{- end }}
|
||||||
@@ -2,9 +2,9 @@
|
|||||||
apiVersion: argoproj.io/v1alpha1
|
apiVersion: argoproj.io/v1alpha1
|
||||||
kind: ClusterWorkflowTemplate
|
kind: ClusterWorkflowTemplate
|
||||||
metadata:
|
metadata:
|
||||||
name: {{ .Values.pipeline.name | quote }}
|
name: {{ .Values.pipeline.name }}
|
||||||
spec:
|
spec:
|
||||||
serviceAccountName: {{ .Values.pipeline.serviceAccountName | quote }}
|
serviceAccountName: {{ .Values.pipeline.serviceAccountName }}
|
||||||
entrypoint: security-pipeline
|
entrypoint: security-pipeline
|
||||||
onExit: pipeline-exit-hook
|
onExit: pipeline-exit-hook
|
||||||
volumeClaimTemplates:
|
volumeClaimTemplates:
|
||||||
@@ -15,7 +15,7 @@ spec:
|
|||||||
- ReadWriteOnce
|
- ReadWriteOnce
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
storage: {{ .Values.pipeline.workspace.storage | quote }}
|
storage: {{ .Values.pipeline.workspace.storage }}
|
||||||
arguments:
|
arguments:
|
||||||
parameters:
|
parameters:
|
||||||
- name: working-dir
|
- name: working-dir
|
||||||
@@ -26,52 +26,20 @@ spec:
|
|||||||
- name: git-revision
|
- name: git-revision
|
||||||
value: {{ .Values.pipeline.gitRevision | quote }}
|
value: {{ .Values.pipeline.gitRevision | quote }}
|
||||||
templates:
|
templates:
|
||||||
|
# Top-level DAG wiring lives here so the workflow flow stays readable.
|
||||||
- name: security-pipeline
|
- name: security-pipeline
|
||||||
dag:
|
dag:
|
||||||
tasks:
|
tasks:
|
||||||
- name: clone
|
{{ include "template.workflow.security-pipeline.tasks" . | nindent 10 }}
|
||||||
template: clone-repo
|
|
||||||
arguments:
|
# Concrete task implementations stay below.
|
||||||
parameters:
|
|
||||||
- name: repo-url
|
|
||||||
value: {{ `{{workflow.parameters.repo-url}}` | quote }}
|
|
||||||
- name: git-revision
|
|
||||||
value: {{ `{{workflow.parameters.git-revision}}` | quote }}
|
|
||||||
- name: scanners
|
|
||||||
dependencies:
|
|
||||||
- clone
|
|
||||||
template: parallel-scanners
|
|
||||||
arguments:
|
|
||||||
parameters:
|
|
||||||
- name: working-dir
|
|
||||||
value: {{ `{{workflow.parameters.working-dir}}` | quote }}
|
|
||||||
- name: enforce-policy
|
|
||||||
dependencies:
|
|
||||||
- scanners
|
|
||||||
template: enforce-policy
|
|
||||||
arguments:
|
|
||||||
parameters:
|
|
||||||
- name: fail-on-cvss
|
|
||||||
value: {{ `{{workflow.parameters.fail-on-cvss}}` | quote }}
|
|
||||||
{{- if .Values.storage.enabled }}
|
|
||||||
- name: upload-storage
|
|
||||||
dependencies:
|
|
||||||
- scanners
|
|
||||||
template: upload-storage
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.defectdojo.enabled }}
|
|
||||||
- name: upload-defectdojo
|
|
||||||
dependencies:
|
|
||||||
- scanners
|
|
||||||
template: upload-defectdojo
|
|
||||||
{{- end }}
|
|
||||||
- name: clone-repo
|
- name: clone-repo
|
||||||
inputs:
|
inputs:
|
||||||
parameters:
|
parameters:
|
||||||
- name: repo-url
|
- name: repo-url
|
||||||
- name: git-revision
|
- name: git-revision
|
||||||
container:
|
container:
|
||||||
image: {{ .Values.images.git | quote }}
|
image: {{ .Values.images.git }}
|
||||||
command:
|
command:
|
||||||
- sh
|
- sh
|
||||||
- -c
|
- -c
|
||||||
@@ -80,23 +48,18 @@ spec:
|
|||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: workspace
|
- name: workspace
|
||||||
mountPath: /workspace
|
mountPath: /workspace
|
||||||
|
|
||||||
- name: parallel-scanners
|
- name: parallel-scanners
|
||||||
inputs:
|
inputs:
|
||||||
parameters:
|
parameters:
|
||||||
- name: working-dir
|
- name: working-dir
|
||||||
dag:
|
dag:
|
||||||
tasks:
|
tasks:
|
||||||
{{- range $scanner := list "trufflehog" "semgrep" "kics" "socketdev" "syft-grype" "pulumi-crossguard" }}
|
{{ include "template.workflow.parallel-scanners.tasks" . | nindent 10 }}
|
||||||
- name: {{ $scanner }}
|
|
||||||
template: scan-{{ $scanner }}
|
|
||||||
arguments:
|
|
||||||
parameters:
|
|
||||||
- name: working-dir
|
|
||||||
value: {{ `{{inputs.parameters.working-dir}}` | quote }}
|
|
||||||
{{- end }}
|
|
||||||
- name: pipeline-exit-hook
|
- name: pipeline-exit-hook
|
||||||
container:
|
container:
|
||||||
image: {{ .Values.images.curl | quote }}
|
image: {{ .Values.images.curl }}
|
||||||
command:
|
command:
|
||||||
- sh
|
- sh
|
||||||
- -c
|
- -c
|
||||||
@@ -104,17 +67,5 @@ spec:
|
|||||||
- |
|
- |
|
||||||
set -eu
|
set -eu
|
||||||
echo "Pipeline completed with status: {{ `{{workflow.status}}` }}"
|
echo "Pipeline completed with status: {{ `{{workflow.status}}` }}"
|
||||||
{{ include "template.scan-trufflehog" . | nindent 4 }}
|
{{ include "template.workflow.named-templates" . | nindent 4 }}
|
||||||
{{ include "template.scan-semgrep" . | nindent 4 }}
|
|
||||||
{{ include "template.scan-kics" . | nindent 4 }}
|
|
||||||
{{ include "template.scan-socketdev" . | nindent 4 }}
|
|
||||||
{{ include "template.scan-syft-grype" . | nindent 4 }}
|
|
||||||
{{ include "template.scan-pulumi-crossguard" . | nindent 4 }}
|
|
||||||
{{- if .Values.storage.enabled }}
|
|
||||||
{{ include "template.upload-storage" . | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.defectdojo.enabled }}
|
|
||||||
{{ include "template.upload-defectdojo" . | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
{{ include "template.enforce-policy" . | nindent 4 }}
|
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|||||||
@@ -16,18 +16,12 @@ spec:
|
|||||||
- secretKey: PULUMI_ACCESS_TOKEN
|
- secretKey: PULUMI_ACCESS_TOKEN
|
||||||
remoteRef:
|
remoteRef:
|
||||||
key: PULUMI_ACCESS_TOKEN
|
key: PULUMI_ACCESS_TOKEN
|
||||||
- secretKey: AWS_ACCESS_KEY_ID
|
- secretKey: S3_ACCESS_KEY_ID
|
||||||
remoteRef:
|
remoteRef:
|
||||||
key: AWS_ACCESS_KEY_ID
|
key: S3_ACCESS_KEY_ID
|
||||||
- secretKey: AWS_SECRET_ACCESS_KEY
|
- secretKey: S3_SECRET_ACCESS_KEY
|
||||||
remoteRef:
|
remoteRef:
|
||||||
key: AWS_SECRET_ACCESS_KEY
|
key: S3_SECRET_ACCESS_KEY
|
||||||
- secretKey: MINIO_ROOT_USER
|
|
||||||
remoteRef:
|
|
||||||
key: MINIO_ROOT_USER
|
|
||||||
- secretKey: MINIO_ROOT_PASSWORD
|
|
||||||
remoteRef:
|
|
||||||
key: MINIO_ROOT_PASSWORD
|
|
||||||
- secretKey: DEFECTDOJO_URL
|
- secretKey: DEFECTDOJO_URL
|
||||||
remoteRef:
|
remoteRef:
|
||||||
key: DEFECTDOJO_URL
|
key: DEFECTDOJO_URL
|
||||||
|
|||||||
@@ -8,6 +8,14 @@ pipeline:
|
|||||||
workspace:
|
workspace:
|
||||||
storage: 1Gi
|
storage: 1Gi
|
||||||
repoName: agentguard-ci
|
repoName: agentguard-ci
|
||||||
|
# Order here matches the scanner fan-out in the workflow DAG.
|
||||||
|
scanners:
|
||||||
|
- trufflehog
|
||||||
|
- semgrep
|
||||||
|
- kics
|
||||||
|
- socketdev
|
||||||
|
- syft-grype
|
||||||
|
- pulumi-crossguard
|
||||||
toolsImage:
|
toolsImage:
|
||||||
repository: agentguard-tools
|
repository: agentguard-tools
|
||||||
tag: latest
|
tag: latest
|
||||||
|
|||||||
Reference in New Issue
Block a user