diff --git a/README.md b/README.md
index e92be665a6eebc707ae7415e847c7fb614ef2986..3e229f18514e30e5b9180bbc02a760ca989aceb9 100644
--- a/README.md
+++ b/README.md
@@ -397,6 +397,18 @@ In addition to a textual report in the console, this job produces the following
 | `reports/docker-trivy-*.native.json` | native Trivy report format (json) | [DefectDojo integration](https://defectdojo.github.io/django-DefectDojo/integrations/parsers/#trivy)<br/>_This report is generated only if DefectDojo template is detected_ |
 | `reports/docker-trivy-*.gitlab.json` | [Trivy report format for GitLab](https://aquasecurity.github.io/trivy/v0.30.4/docs/integrations/gitlab-ci/) format | [GitLab integration](https://docs.gitlab.com/ee/ci/yaml/artifacts_reports.html#artifactsreportscontainer_scanning) |
 
+### `docker-sbom` job
+
+This job generates a [SBOM](https://cyclonedx.org/) file listing installed packages using [syft](https://github.com/anchore/syft).
+
+It is bound to the `package-test` stage, and uses the following variables:
+
+| Name                  | description                            | default value     |
+| --------------------- | -------------------------------------- | ----------------- |
+| `DOCKER_SBOM_DISABLED` | Set to `true` to disable this job | _none_ |
+| `DOCKER_SBOM_IMAGE` | The docker image used to emit SBOM | `anchore/syft:debug` |
+| `DOCKER_SBOM_OPTS` | Options for syft used for SBOM analysis | `--catalogers rpm-db-cataloger,alpmdb-cataloger,apkdb-cataloger,dpkgdb-cataloger,portage-cataloger` |
+
 ### `docker-publish` job
 
 This job pushes (_promotes_) the built image as the _release_ image [skopeo](https://github.com/containers/skopeo).
diff --git a/kicker.json b/kicker.json
index df8d72d95839f4c17b339571bc4c8f7e027f370a..f1f9aaa09b96dd3cb2159cb4931e63a91c154499 100644
--- a/kicker.json
+++ b/kicker.json
@@ -174,6 +174,24 @@
           "advanced": true
         }
       ]
+    },
+    {
+      "id": "sbom",
+      "name": "Software Bill of Materials",
+      "description": "This job generates a file listing all dependencies using [syft](https://github.com/anchore/syft)",
+      "disable_with": "DOCKER_SBOM_DISABLED",
+      "variables": [
+        {
+          "name": "DOCKER_SBOM_IMAGE",
+          "default": "anchore/syft:debug"
+        },
+        {
+          "name": "DOCKER_SBOM_OPTS",
+          "description": "Options for syft used for SBOM analysis",
+          "default": "--catalogers rpm-db-cataloger,alpmdb-cataloger,apkdb-cataloger,dpkgdb-cataloger,portage-cataloger",
+          "advanced": true
+        }
+      ]
     }
   ],
   "variants": [
diff --git a/templates/gitlab-ci-docker.yml b/templates/gitlab-ci-docker.yml
index e7525a9361f7cc3887c04e82e62d0e983d81baca..745c73d96b797661455b08aa951f0df38d1baf10 100644
--- a/templates/gitlab-ci-docker.yml
+++ b/templates/gitlab-ci-docker.yml
@@ -69,6 +69,10 @@ variables:
   DOCKER_TRIVY_IMAGE: "aquasec/trivy:latest"
   DOCKER_TRIVY_ARGS: "--ignore-unfixed --vuln-type os"
 
+  # SBOM genenration image and arguments
+  DOCKER_SBOM_IMAGE: anchore/syft:debug
+  DOCKER_SBOM_OPTS: "--catalogers rpm-db-cataloger,alpmdb-cataloger,apkdb-cataloger,dpkgdb-cataloger,portage-cataloger"
+
   # by default: DevOps pipeline
   PUBLISH_ON_PROD: "true"
 
@@ -677,6 +681,31 @@ docker-trivy:
       when: never
     - !reference [.test-policy, rules]
 
+docker-sbom:
+  extends: .docker-base
+  stage: package-test
+  image:
+    name: $DOCKER_SBOM_IMAGE
+    entrypoint: [""]
+  # force no dependency
+  dependencies: []
+  script:
+    - mkdir -p -m 777 reports
+    - dockerfile_hash=$(md5sum "$DOCKER_FILE" | cut -d" " -f1)
+    - /syft packages $DOCKER_SNAPSHOT_IMAGE $DOCKER_SBOM_OPTS -o cyclonedx-json=reports/docker-sbom-${dockerfile_hash}.cyclonedx.json
+    - chmod a+r reports/docker-sbom-${dockerfile_hash}.cyclonedx.json
+  artifacts:
+    name: "SBOM for docker from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG"
+    expire_in: 1 week
+    when: always
+    paths:
+      - "reports/docker-sbom-*.cyclonedx.json"
+  rules:
+    # exclude if disabled
+    - if: '$DOCKER_SBOM_DISABLED == "true"'
+      when: never
+    - !reference [.test-policy, rules]
+
 # ==================================================
 # Stage: publish
 # ==================================================