14 Commits
0.0.1 ... 0.0.6

Author SHA1 Message Date
4fbda91e15 dockerize goal, 4
Some checks are pending
ci/woodpecker/tag/woodpecker Pipeline is pending
2025-06-04 13:46:16 +02:00
50248acefb dockerize goal, 3
Some checks are pending
ci/woodpecker/tag/woodpecker Pipeline is pending
2025-06-04 13:40:05 +02:00
c9c57445b9 dockerize goal, 2
Some checks are pending
ci/woodpecker/tag/woodpecker Pipeline is pending
2025-06-04 13:37:56 +02:00
18631dc02a dockerize goal
Some checks are pending
ci/woodpecker/tag/woodpecker Pipeline is pending
2025-06-04 13:34:45 +02:00
ea90b8b8b0 fix defectdojo goal 1
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2025-06-04 13:26:35 +02:00
15b2e69960 next goal 2025-06-04 13:25:22 +02:00
9f6f769486 add gitlab ci 2025-06-04 13:22:16 +02:00
784b41f762 new upstream image
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2025-06-02 18:36:04 +02:00
bcbca70496 typo fixed
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2025-05-22 17:31:14 +02:00
e5fd8709a9 trivy dojo report operator
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2025-05-22 17:30:10 +02:00
dbf2ca3507 encrypted secrets
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2025-05-22 17:08:52 +02:00
83d6a7bd64 trivy-operator integration
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2025-05-21 22:08:24 +02:00
035da3fdca add sbom upload option
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2025-05-21 15:56:16 +02:00
8d56fcf7c2 md
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2025-05-16 18:47:10 +02:00
7 changed files with 271 additions and 23 deletions

1
.gitignore vendored
View File

@ -3,4 +3,5 @@ defs/
*/.venv/
__pycache__/
.*.swp
tmp/

124
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,124 @@
stages:
- generate-api-clients
- dockerize
variables:
REGISTRY: devnexus.krohne.com:18079/repository/docker-krohne
IMAGE_NAME: $REGISTRY/$CI_PROJECT_NAME
generate-dtrack-api:
stage: generate-api-clients
image: openapitools/openapi-generator-cli:v7.12.0
tags:
- linux
- docker
- bash
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
- if: '$CI_COMMIT_TAG'
artifacts:
paths:
- dtrack-api-client.tgz
expire_in: 1 week
script:
- curl https://dtrack-api.hottis.de/api/openapi.json > dependencytrack-openapi.json
- |
docker-entrypoint.sh \
author template \
-g python \
-o dependencytrack-openapi-custom-template
- sed -i 's/import re/import regex as re/' dependencytrack-openapi-custom-template/model_anyof.mustache
- sed -i 's/import re/import regex as re/' dependencytrack-openapi-custom-template/model_generic.mustache
- |
docker-entrypoint.sh \
generate \
-i dependencytrack-openapi.json \
-g python \
-o dependencytrack-client \
--package-name dependencytrack_api \
-t dependencytrack-openapi-custom-template
- tar -czvf dtrack-api-client.tgz dependencytrack-client
generate-defectdojo-api:
stage: generate-api-clients
image: openapitools/openapi-generator-cli:v7.12.0
tags:
- linux
- docker
- bash
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
- if: '$CI_COMMIT_TAG'
artifacts:
paths:
- defectdojo-api-client.tgz
expire_in: 1 week
script:
- curl https://defectdojo.hottis.de/api/v2/oa3/schema/?format=json > defectdojo-openapi.json
- |
docker-entrypoint.sh \
generate \
-i defectdojo-openapi.json \
-g python \
-o defectdojo-client \
--package-name defectdojo_api
- tar -czvf defectdojo-api-client.tgz defectdojo-client
dockerize:
stage: dockerize
image: devnexus.krohne.com:18079/repository/docker-krohne/krohnedockerbash:0.5
tags:
- linux
- docker
- bash
rules:
- if: '$CI_COMMIT_TAG'
script:
- tar -xzf defectdojo-api-client.tgz
- tar -xzf dtrack-api-client.tgz
- docker build --tag $IMAGE_NAME:latest
--tag $IMAGE_NAME:$CI_COMMIT_SHA
--tag $IMAGE_NAME:$CI_COMMIT_TAG
.
- docker login -u $NEXUS_DOCKER_USER -p $NEXUS_DOCKER_PASSWORD $REGISTRY
- docker push $IMAGE_NAME:latest
- docker push $IMAGE_NAME:$CI_COMMIT_SHA
- docker push $IMAGE_NAME:$CI_COMMIT_TAG
#
# build:
# image: plugins/kaniko
# settings:
# repo: ${FORGE_NAME}/${CI_REPO}
# registry:
# from_secret: container_registry
# tags: latest,${CI_COMMIT_SHA},${CI_COMMIT_TAG}
# username:
# from_secret: container_registry_username
# password:
# from_secret: container_registry_password
# dockerfile: Dockerfile
# when:
# - event: [ push, tag ]
#
# build-for-quay:
# image: plugins/kaniko
# settings:
# repo: quay.io/wollud1969/${CI_REPO_NAME}
# registry: quay.io
# tags:
# - latest
# - ${CI_COMMIT_TAG}
# username:
# from_secret: quay_username
# password:
# from_secret: quay_password
# dockerfile: Dockerfile
# when:
# - event: [tag]
#

View File

@ -1,4 +1,4 @@
FROM python:3.12.10-alpine3.21
FROM python:3.12.10-alpine3.22
ENV DTRACK_API_URL=""
ENV DTRACK_TOKEN=""

9
src/ENV.asc Normal file
View File

@ -0,0 +1,9 @@
-----BEGIN PGP MESSAGE-----
jA0ECQMIapWTXVBqXIb+0sAdAaPkf/oMhzDAm6T4mEFScMs5BJa444hJEkLgYSAS
upN+QQSY5/x0OdoghQmaUXmRcu17kaFyzFsS+EaHymru4mpmOpwS/+YerHrhpfNF
j3YfhW/sM6v2wYJAq+8utkPhATC36LxwgTZRbGBFGgFCG7fUHlldPO1DeVJvoQNe
idpfg5irM+x78XC7tDJOdYYrvDcz0EELBuwB7V78ZHUfjLcvKek1exhLOq8+V60A
nZhsoaELIEfCQx52ayF1TbvNdqOTCXpWHfgE9A9aw2eqRbMn9P+HOdeRz1t0+1s=
=rEHE
-----END PGP MESSAGE-----

View File

@ -44,6 +44,7 @@ def generateSBOM(target='.', name='dummyName', version='0.0.0'):
logger.error(f"SBOM scanner failed: {e.stderr}")
raise MyLocalException(e)
# ---- main starts here with preparation of config -----------------------------------------------------------------------
try:
DTRACK_API_URL = os.environ["DTRACK_API_URL"]
@ -70,37 +71,58 @@ parser.add_argument('--type', '-t',
required=True)
parser.add_argument('--classifier', '-c',
help='Project Classifier from DependencyTrack',
choices=['APPLICATION', 'FRAMEWORK', 'LIBRARY', 'CONTAINER', 'OPERATING_SYSTEM', 'DEVICE', 'FIRMWARE', 'FILE', 'PLATFORM', 'DEVICE_DRIVER', 'MACHINE_LEARNING_MODEL', 'DATA'],
choices=['APPLICATION', 'FRAMEWORK', 'LIBRARY', 'CONTAINER', 'OPERATING_SYSTEM', 'DEVICE',
'FIRMWARE', 'FILE', 'PLATFORM', 'DEVICE_DRIVER', 'MACHINE_LEARNING_MODEL', 'DATA'],
required=True)
parser.add_argument('--uploadsbom', '-U',
help='Upload a already existing SBOM instead of generating it. Give the SBOM file at -F instead of a target',
required=False,
action='store_true',
default=False)
parser.add_argument('--sbomfile', '-F',
help='Filename of existing SBOM file to upload, use together with -U, do not use together with -T',
required=False)
parser.add_argument('--target', '-T',
help='Target to scan, either path name for sources or docker image tag',
required=True)
required=False)
args = parser.parse_args()
projectName = args.name
projectVersion = args.version
projectDescription = args.description
productType = args.type
projectClassifier = args.classifier
target = args.target
uploadSbomFlag = args.uploadsbom
if uploadSbomFlag:
sbomFileName = args.sbomfile
else:
target = args.target
logger.info(f"Generating SBOM for {target}")
sbom = generateSBOM(target, projectName, projectVersion)
logger.info("Done.")
# ---- main starts here --------------------------------------------------------------------------------------------------
if uploadSbomFlag:
# ------- read uploaded SBOM -------------
logger.info(f"Reading SBOM from file {sbomFileName}")
with open(sbomFileName, 'r') as sbomFile:
sbom = sbomFile.read()
logger.info("Done.")
else:
# ------- generate SBOM ------------
logger.info(f"Generating SBOM for {target}")
sbomJson = generateSBOM(target, projectName, projectVersion)
sbom = json.dumps(sbomJson)
logger.info("Done.")
# ------- create product and engagement in DefectDojo -------
defectdojo_configuration = defectdojo_api.Configuration(
host = DEFECTDOJO_URL
)
defectdojo_configuration.api_key['tokenAuth'] = DEFECTDOJO_TOKEN
defectdojo_configuration.api_key_prefix['tokenAuth'] = 'Token'
dependencytrack_configuration = dependencytrack_api.Configuration(
host = f"{DTRACK_API_URL}/api"
)
dependencytrack_configuration.debug = False
dependencytrack_configuration.api_key['ApiKeyAuth'] = DTRACK_TOKEN
with defectdojo_api.ApiClient(defectdojo_configuration) as defectdojo_api_client:
print("Create product in DefectDojo")
productName = f"{projectName}:{projectVersion}"
@ -134,6 +156,14 @@ with defectdojo_api.ApiClient(defectdojo_configuration) as defectdojo_api_client
engagement_id = engagement_response.id
print(f"{engagement_id=}")
# ------- create project in DependencyTrack, connect project to engagement in DefectDojo, upload SBOM --------
dependencytrack_configuration = dependencytrack_api.Configuration(
host = f"{DTRACK_API_URL}/api"
)
dependencytrack_configuration.debug = False
dependencytrack_configuration.api_key['ApiKeyAuth'] = DTRACK_TOKEN
with dependencytrack_api.ApiClient(dependencytrack_configuration) as dependencytrack_api_client:
project_response = \
executeApiCall(
@ -149,9 +179,12 @@ with dependencytrack_api.ApiClient(dependencytrack_configuration) as dependencyt
print(f"{project_uuid=}")
properties = [
{ 'group_name': "integrations", 'property_name': "defectdojo.engagementId", 'property_value': str(engagement_id), 'property_type': "STRING" },
{ 'group_name': "integrations", 'property_name': "defectdojo.doNotReactivate", 'property_value': "true", 'property_type': "BOOLEAN" },
{ 'group_name': "integrations", 'property_name': "defectdojo.reimport", 'property_value': "true", 'property_type': "BOOLEAN" }
{ 'group_name': "integrations", 'property_name': "defectdojo.engagementId",
'property_value': str(engagement_id), 'property_type': "STRING" },
{ 'group_name': "integrations", 'property_name': "defectdojo.doNotReactivate",
'property_value': "true", 'property_type': "BOOLEAN" },
{ 'group_name': "integrations", 'property_name': "defectdojo.reimport",
'property_value': "true", 'property_type': "BOOLEAN" }
]
for property in properties:
executeApiCall(
@ -170,6 +203,6 @@ with dependencytrack_api.ApiClient(dependencytrack_configuration) as dependencyt
dependencytrack_api.BomApi.upload_bom,
None,
None,
[ None, False, projectName, projectVersion, None, None, None, None, True, json.dumps(sbom) ]
[ None, False, projectName, projectVersion, None, None, None, None, True, sbom ]
)

14
todo.md
View File

@ -1,11 +1,13 @@
- 2025-04-04
- Dirk K.
- DefectDojo - Jira Integration
- Monitor SLA expiry on DefectDojo
- Workflow for review of assessments in DefectDojo
- Trivy-Deployment in cluster shall be integrated with DefectDojo
- [ ] DefectDojo - Jira Integration
- [ ] Monitor SLA expiry on DefectDojo
- [ ] Workflow for review of assessments in DefectDojo
- [x] Trivy-Deployment in cluster shall be integrated with DefectDojo
- [Import Trivy Operator reports into DefectDojo](https://medium.com/@alexander.murylev/implementing-centralized-security-scanning-across-multiple-kubernetes-clusters-with-trivy-and-989f3d5b0f4a)
- [Trivy Dojo Report Operator by Telekom](https://github.com/telekom-mms/trivy-dojo-report-operator)
- Thomas O.
- DefectDojo and/or DependencyTrack shall notify via mail in case of new vulnerabilities
- add switch to glue logic to disable integrated SBOM generator and read externally
- [ ] DefectDojo and/or DependencyTrack shall notify via mail in case of new vulnerabilities
- [x] add switch to glue logic to disable integrated SBOM generator and read externally
generated SBOM from file

View File

@ -0,0 +1,79 @@
# Integration of the Trivy Operator in Kubernetes with DefectDojo
## Installation of the Trivy Operator
*namespace*
```
security
```
*install.sh*
```
#!/bin/bash
NAMESPACE=$(cat namespace)
VERSION=0.28.1
helm repo add aqua https://aquasecurity.github.io/helm-charts/
helm repo update
helm upgrade --install trivy-operator aqua/trivy-operator \
-f values.yml \
--namespace $NAMESPACE \
--version $VERSION
```
*values.yml*
```
trivy:
timeout: "10m0s"
operator:
scanJobTimeout: 10m
targetNamespaces: "homea"
```
If `targetNamespaces` is skipped, all namespaces will be scanned. If only a limited set of namespaces shall be scanned, put those namespace comma-separated into this option.
## Installation of the Trivy Dojo Report Operator
*namespace*
```
security
```
*install.sh*
```
#!/bin/bash
NAMESPACE=$(cat namespace)
VERSION=0.8.8
helm repo add trivy-dojo-report-operator https://telekom-mms.github.io/trivy-dojo-report-operator/
helm repo update
helm install chart-name trivy-dojo-report-operator/trivy-dojo-report-operator \
-f values.yml \
--namespace $NAMESPACE \
--version $VERSION
```
*values.yml*
```
defectDojoApiCredentials:
apiKey: "geheim"
url: "https://defectdojo.hottis.de"
operator:
trivyDojoReportOperator:
env:
defectDojoEvalEngagementName: "true"
defectDojoEngagementName: "body['report']['artifact']['tag']"
defectDojoEvalProductName: "true"
defectDojoProductName: "meta['namespace']+':'+meta['name']"
```
Make sure to set the correct apiKey. And make sure not to store it in a repo. A secure approach will be provided.
Details on this operator can be found [here](https://medium.com/@alexander.murylev/implementing-centralized-security-scanning-across-multiple-kubernetes-clusters-with-trivy-and-989f3d5b0f4a) and [here](https://github.com/telekom-mms/trivy-dojo-report-operator).