Add an SBOM (Software Bill of Materials) generation step to an existing Harness pipeline using Harness SCS SscaOrchestration (SBOM Orchestration). Supports container images and code repositories. Sources: docker, ECR, GCR, GAR, ACR, Harness AR (har), repository, and local workspace. Syft or cdxgen, SPDX or CycloneDX, optional SBOM attestation. Only works with existing pipelines. Use when asked to create an SBOM, generate a bill of materials, add SBOM to a pipeline, scan a container image or repo for components, or set up SBOM Orchestration. Trigger phrases: create SBOM, generate SBOM, add SBOM step, SBOM for image, SBOM for repo, scan for dependencies, SBOM Orchestration, add Generate SBOM step.
70
86%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Add an SBOM Orchestration (SscaOrchestration) step to an existing Harness pipeline for a
container image or code repository. This skill only works with existing pipelines — do not
create standalone SBOM pipelines.
Supported stages: SBOM Orchestration runs in CI, CD (Deployment), and Security
(Security) stages. Show stage type in Phase 2 and offer placement options that match the stage
type (see references/interactive-wizard-flow.md).
Guide the user through a step-by-step interactive wizard (same UX as /configure-repo-scan):
one decision per turn, recommended options marked, pipeline structure
shown after fetch, then confirm before harness_update.
references/interactive-wizard-flow.mdreferences/sbom-orchestration-step.mdreferences/cd-containerized-step-group.mdFollow this UX for every invocation. Do not dump all Pipeline Studio fields in one message.
AskQuestion tool when available. If unavailable, use a
numbered option list with (Recommended) on the default choice (same pattern as container scan).Pipeline · Placement · Method · Source · Details · Attestation · Submitharness_get (URL or id) before placement/source questions.harness_update only after user confirms.harness_update, provide a configuration summary and
point the user to /run-pipeline to execute. Do not call harness_execute, poll
executions, or run harness_diagnose in this skill (same pattern as /configure-repo-scan).AskQuestion for stage + position) before method/source/attestation, even when:
SscaOrchestration step already exists in CIDeployment stage (or asks for CD),
follow references/cd-containerized-step-group.md end to end (step group, <+artifact.image>,
infra). Do not place CD SBOM under execution.steps at the stage top level.Deployment stage and the user wants
CD, run the CD prerequisites sub-flow (service, environment, infrastructure, K8s connector
for stepGroupInfra) before harness_update. See CD edge case below.Full phase prompts and option ids: references/interactive-wizard-flow.md.
Run in order. Stop after each phase until the user answers.
| Phase | Breadcrumb | Action |
|---|---|---|
| 0 | Pipeline | AskQuestion: pipeline URL ready? |
| 1 | Pipeline | Collect URL or org/project/id → harness_get |
| 2 | Pipeline | Display pipeline structure (no question) |
| 3 | Placement | Mandatory AskQuestion: target stage (CI / Deployment / Security) + position; see CD edge case if no Deploy stage |
| 3b | Placement (CD only) | If no Deployment stage: service, environment, infra, stepGroupInfra connector — then add stage + SBOM |
| 4 | Method | AskQuestion: Syft/SPDX, CycloneDX, cdxgen, or ingestion |
| 5 | Source | AskQuestion: source tile (Third-Party, HAR, Repository, Local) |
| 6 | Source | AskQuestion: registry provider (Third-Party only) |
| 7 | Details | AskQuestion: connector (skip if obvious from YAML) |
| 8 | Details | Ask: image, repo URL, or local artifact (free text) |
| 9 | Attestation | AskQuestion: attest or not; keyless vs cosign |
| 10 | Submit | AskQuestion: confirm pipeline update |
After Phase 10 confirm → generate YAML, insert step, harness_update, then provide summary (do not run the pipeline).
| Stage type (YAML) | Module | SBOM placement notes |
|---|---|---|
CI | CI | End of stage or after build/push; repository source needs cloneCodebase: true + codebase |
Deployment | CD | Inside a containerized step group with stepGroupInfra; before deploy — see references/cd-containerized-step-group.md |
Security | STO / SCS | End of spec.execution.steps (alongside other security steps) |
When listing stages in Phase 2, include the stage type (CI, Deployment, Security, etc.).
For Deployment stages, label each stepGroup as containerized or not (presence of
stepGroupInfra). In Phase 3, only offer placement options valid for the chosen stage (see wizard
reference). Never insert SscaOrchestration at the top level of a CD stage execution.steps.
Use when Placement targets a Deployment stage, or the user wants SBOM at deploy time.
If the pipeline has only CI (or Security) stages and no type: Deployment stage, print:
This pipeline has no CD Deploy stage yet. SBOM in CD must run in a Deployment stage inside a containerized step group before the deploy step.
Then AskQuestion: add a new Deploy stage, use a different pipeline URL, or keep SBOM in CI only. Do not default to the existing CI stage without asking.
Even with a single Build CI stage, ask:
CI, Deployment, and Security stage by identifier.ci_*, cd_*, or security_* options per wizard reference.If SscaOrchestration already exists in CI, include options such as:
| Option | Meaning |
|---|---|
| Keep CI SBOM + add CD SBOM | New step (e.g. generate_sbom_cd) in Deploy stage |
| CD only | User will remove or skip CI SBOM (confirm in Phase 10) |
| Replace / move | Rare — confirm source and target stages explicitly |
Run one topic per turn (AskQuestion where possible):
| Step | Action |
|---|---|
| Service | harness_list / user pick → serviceRef (artifact connector drives registry SBOM connector) |
| Environment | User pick → environmentRef |
| Infrastructure | harness_list with params: { environment_id: "<env>" }; if none, harness_create (KubernetesDirect) per /create-infrastructure — never omit infrastructureDefinitions on the Deploy stage |
| Step group infra | AskQuestion: K8s cluster connector + namespace for stepGroupInfra (copy from stage infra when possible) |
| Deploy step type | Default K8sRollingDeploy for deploymentType: Kubernetes services |
Append a new stage after CI (typical):
- stage:
identifier: Deploy_Dev
name: Deploy Dev
type: Deployment
spec:
deploymentType: Kubernetes
service:
serviceRef: <service_id>
environment:
environmentRef: <environment_id>
deployToAll: false
infrastructureDefinitions:
- identifier: <infra_id>
execution:
steps:
- stepGroup:
identifier: scs_before_deploy
name: Supply Chain Security
stepGroupInfra:
type: KubernetesDirect
spec:
connectorRef: <k8s_cluster_connector>
namespace: <namespace>
steps:
- step:
identifier: generate_sbom_cd
name: Generate SBOM
type: SscaOrchestration
# ... wizard spec; image: <+artifact.image> for service artifacts ...
- step:
identifier: rolling_deployment
type: K8sRollingDeploy
spec:
skipDryRun: false
timeout: 10m
rollbackSteps:
- step:
identifier: rollback
type: K8sRollingRollback
spec: {}
timeout: 10m
failureStrategies:
- onFailure:
errors: [AllErrors]
action:
type: StageRollbackFull rules and examples: references/cd-containerized-step-group.md.
generate_sbom_cd) when CI already has generate_sbom.<+artifact.image> from the service primary artifact; literal tags only if
the user provides them in Phase 8.service.serviceDefinition.spec.artifacts or existing CI SBOM step.Container / Third-Party: connectorRef or connector in BuildAndPushDockerRegistry, Run,
Plugin, StoAgent, SscaOrchestration, SscaArtifactSigning.
Repository: v0 pipeline.properties.ci.codebase.connectorRef; v1 codebase connector →
spec.overrideConnectorRef.
If repository SBOM and no codebase connector → stop and explain. If container SBOM and no registry
connector → harness_search (connectors) or /create-connector.
Using only the options recorded in the wizard, generate native SscaOrchestration YAML — not a
Run: syft step. If the user chose the defaults shortcut, use Generation + Syft + SPDX +
Third-Party/docker + keyless attestation.
Third-Party — Docker Registry (default):
- step:
identifier: generate_sbom
name: Generate SBOM
type: SscaOrchestration
spec:
mode: generation
source:
type: docker
spec:
connector: <docker_registry_connector_from_step_2>
image: <repo/name:tag_or_digest>
tool:
type: Syft
spec:
format: spdx-json
attestation:
type: keyless
spec:
oidcProvider: harness
timeout: 15mRepository:
- step:
identifier: generate_sbom
name: Generate SBOM
type: SscaOrchestration
spec:
mode: generation
overrideConnectorRef: <git_connector_from_step_2>
source:
type: repository
spec:
url: <full_repo_url>
variant_type: branch
variant: <branch>
tool:
type: Syft
spec:
format: spdx-json
attestation:
type: keyless
spec:
oidcProvider: harness
timeout: 15mAmazon ECR (source.type: ecr):
source:
type: ecr
spec:
connector: <registry_connector>
image: <repo/name:tag_or_digest>
region: <aws_region>
account: <aws_account_id>Google GCR (source.type: gcr):
source:
type: gcr
spec:
connector: <docker_registry_connector>
host: gcr.io
project_id: <gcp_project_id>
image: <repo/name:tag_or_digest>Google GAR (source.type: gar):
source:
type: gar
spec:
connector: <docker_registry_connector>
host: <region>-docker.pkg.dev
project_id: <gcp_project_id>
image: <repo/name:tag_or_digest>Azure ACR (source.type: acr):
source:
type: acr
spec:
connector: <docker_registry_connector>
image: <registry>.azurecr.io/<repo>:<tag>
subscription_id: <azure_subscription_id>Harness Artifact Registry (source.type: har):
source:
type: har
spec:
registry: <harness_artifact_registry_identifier>
image: <image_name:tag_or_digest>Harness Local Stage (source.type: local):
source:
type: local
spec:
artifact_name: <artifact_name>
workspace: <optional_workspace_path>
version: <optional_version>Use when the artifact already exists in the stage workspace. For JAR/Helm/non-container artifacts without a registry image, users may need ingestion mode instead — see Harness ingest SBOM docs.
CycloneDX (when requested): change format to cyclonedx-json.
No attestation (when requested): omit the attestation block.
Full UI mapping and notes: references/sbom-orchestration-step.md.
Image formatting (docker / ecr / gcr / gar / acr / har):
lavakush07/myapp:v7 — no leading /, no https://, no docker.io/ unless requiredimage field for docker source — not split url + variantInsert at the placement chosen in Phase 3. Ensure proper indentation.
Key rules:
stage.spec.execution.steps (or inside a non-CD step group if user chose one)stepGroup.steps of a containerized group (stepGroupInfra set). See references/cd-containerized-step-group.mdcloneCodebase: true and properties.ci.codebase on the CI stageimage when possible (<+artifact.image>)cd_new_containerized_group (new stepGroup + stepGroupInfra) or stop and instruct user — do not use top-level execution.stepsexecution.steps; registry or repository per source choicegenerate_sbom in CI; use generate_sbom_cd (or suffix) in CD when CI already has generate_sbomCD containerized step group (summary):
- stepGroup:
identifier: <scs_step_group_id>
name: Supply Chain Security
stepGroupInfra:
type: KubernetesDirect
spec:
connectorRef: <k8s_cluster_connector>
namespace: <namespace>
steps:
- step:
identifier: generate_sbom
type: SscaOrchestration
# ... spec from wizard ...
- step:
identifier: <deploy_step>
type: K8sRollingDeploy # unchanged; SBOM group must appear BEFORE thisCopy stepGroupInfra from an existing containerized group in the pipeline when possible.
Create the full updated pipeline YAML string.
Call MCP tool: harness_update
Parameters:
resource_type: "pipeline"
resource_id: "<pipeline_identifier>"
org_id: "<organization>"
project_id: "<project>"
body: { yamlPipeline: "<updated pipeline YAML string>" }On validation errors, read the API message, fix the field, and retry.
Report the results to the user (same pattern as /configure-repo-scan — do not execute the pipeline):
## SBOM Orchestration Configured
**Pipeline:** <pipeline_name>
**Step:** Generate SBOM (SscaOrchestration)
**Location:** Stage "<stage_name>", <position description>
**Mode:** Generation
**Source:** Third-Party → Docker Registry (or Repository / HAR as configured)
**Connector:** <connector_identifier>
**Image / repo:** <image_or_repo_url>
**Tool / format:** Syft / SPDX (spdx-json)
**Attestation:** Keyless (Harness OIDC) — or as configured
**Pipeline URL:** https://app.harness.io/ng/account/<account_id>/module/ci/orgs/<org_id>/projects/<project_id>/pipelines/<pipeline_id>/pipeline-studio/
**Note:** Review the SBOM Orchestration step in Pipeline Studio to adjust Advanced settings
(resources, SBOM drift, expressions on image field).
### Next Steps
1. Run the pipeline via `/run-pipeline` to verify the SBOM Orchestration step executes successfully
2. If the run fails, diagnose with `/debug-pipeline`
3. View the SBOM on the **Supply Chain** tab of the execution and in SCS **Artifacts**
4. Download SBOM via Artifacts UI or [SBOM API](https://apidocs.harness.io/sbom/downloadsbomforartifact)
5. Enforce SBOM policies via `/enforce-sbom` (pipeline step) and `/create-policy` (OPA rules)
6. For automatic runs on push/PR, add a trigger via `/create-trigger`CD pipelines: note in the summary if runtime inputs (service artifact, environment, infrastructure)
will be required at run time — the user provides those via /run-pipeline or Harness UI Run.
/create-sbom
Add SBOM generation to my backend-api pipeline in the platform project for lavakush07/myapp:v7/create-sbom
Add Generate SBOM to my PR pipeline — repository source, branch main/create-sbom
Configure SBOM Orchestration on ci-build-deploy after docker push — Syft, SPDX, keyless attest/create-sbom
Add SBOM step with CycloneDX only, no attestation/create-sbom
Add Generate SBOM to Deploy_Production before K8s rolling deploy — use artifact image expression/create-sbom
Pipeline has only a Build CI stage — add a Deploy Dev stage with containerized Generate SBOM before K8s rolling deploy/create-sbom
add the sbom step to the pipelineAgent must still run Phase 2 + Phase 3 (stage picker), not assume CI or prior session config.
AskQuestion (or one numbered menu) per turn; see references/interactive-wizard-flow.mdharness_get once after Phase 1; show structure before PlacementcloneCodebase: true + codebaseRun scriptssource.type: docker with connector + image — not legacy url/variant on docker sourcereferences/sbom-orchestration-step.mdDeployment), Security — label types in Phase 2; filter Phase 3 optionsstepGroup with stepGroupInfra; CI-only → CD needs Phase 3b — references/cd-containerized-step-group.md/run-pipeline after configuration (same as /configure-repo-scan)org_id and project_id are correctharness_list (resource_type: pipeline)connectorRef or harness_search for registry connectorsregistry field)properties.ci.codebase.connectorRef (v0) or v1 codebase blockdocker (not ecr unless image is in ECR)ecr + region + accountgcr vs gar with correct host and project_idacr + full image path under .azurecr.ioinvalid reference format or skopeo fallback failedsource.spec.image — e.g. lavakush07/myapp:v7, not /lavakush07/myapp or split fieldsRead, Annotate, Create/Deploy, Delete for .att uploadcloneCodebase: false or missing properties.ci.codebase on CI stage^[a-zA-Z_][0-9a-zA-Z_]{0,127}$source.type and required spec fields per providerDUPLICATE_IDENTIFIER — rename generate_sbom/security-report or scs_artifact_component MCP resourcesCONNECTOR_NOT_FOUND — verify connector identifier in Project Settings → ConnectorsACCESS_DENIED — PAT with pipeline edit permissioncd_* vs ci_* placement; move step under CD stepGroup.stepsinfrastructureDefinitions or infrastructureDefinition should be present in stageenvironment.infrastructureDefinitions[].identifier or create infra via harness_create (/create-infrastructure)/run-pipeline to execute and /debug-pipeline to diagnose failures/run-pipeline or Harness UI RunstepGroup.steps with stepGroupInfra (KubernetesDirect or VM) — not top-level execution.steps; see references/cd-containerized-step-group.mdstepGroupInfra or container-based execution not enabled<+artifact.image> (or expression from service artifact), not a stale literal tagtype: Security and artifact source matches prior steps (registry vs repo)23e9b8b
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.