Sign Artifact
Add an Artifact Signing (SscaArtifactSigning) step to an existing Harness pipeline. The step
retrieves an artifact from a registry or local workspace, signs it with Cosign, and optionally pushes
the .sig signature file back to the registry.
This skill only works with existing pipelines — do not create standalone signing-only pipelines.
Prerequisites: Container images must be built and pushed (or available in registry) before signing.
Key-based signing requires Cosign key pair file secrets (/create-secret). Harness docs note that
Deploy-stage signing is not yet supported — prefer CI or Security stages.
Guide the user through a step-by-step interactive wizard (same UX as /verify-sign):
- Wizard:
references/interactive-wizard-flow.md - UI ↔ YAML:
references/artifact-signing-step.md - CD note:
references/cd-containerized-step-group.md
Interaction model (mandatory)
- One question per turn — use
AskQuestionwhen available; otherwise numbered options with(Recommended). - Opening message — add Artifact Signing after build/push; mention keyless, key-based, Vault, and HAR.
- Progress breadcrumb — after pipeline fetch:
Pipeline · Placement · Source · Details · Signing · Upload · Submit - Record answers — running summary; do not re-ask unless the user changes direction.
- Fetch before configure —
harness_getbefore placement/source questions. - Show pipeline structure — highlight build/push and existing
SscaArtifactSigningsteps. - Infer connector from build/push — skip connector question when unambiguous from YAML.
- Never guess image tags — always ask for image in Phase 7.
- Confirm before write — summary +
harness_updateonly after user confirms. - Stop after update — after successful
harness_update, provide a configuration summary and point the user to/run-pipelineto execute. Do not callharness_execute, poll executions, or runharness_diagnosein this skill (same pattern as/configure-repo-scan). - Phase 3 Placement is mandatory — always run Phase 2 then Phase 3.
- Sequential with SBOM/SLSA — if
SscaOrchestrationorprovenanceexists, place signing after those steps sequentially (Cosign registry race). - Offer all three source tiles — Third-Party, Harness Artifact Registry (HAR), and Harness Local Stage (HAR is supported in YAML even when the UI screenshot shows only two tiles).
- Existing signing step — if
SscaArtifactSigningalready exists, ask: update in place, add a second step, or abort. If existing step hasuploadSignature.upload: false(or block missing) and user wants.sigin registry, setupload: true. - Upload
.sigdefaults OFF in Harness — UI checkbox Attach signature to Artifact Registry is unchecked by default. For container images, always setuploadSignature.upload: trueunless the user explicitly opts out. Confirm this in Phase 9 and in the submit summary. - Verify
.sigafter run — when upload is enabled, after the user runs via/run-pipeline, check step logs for signature push success; see Troubleshooting if registry shows no signature tag. - List all connectors before Phase 6 — never show a hand-picked subset. Call
harness_listwithfilters: { type: "<ConnectorType>" }andsize: 100at project, org, and account scope; merge and present every match inAskQuestion. Seereferences/interactive-wizard-flow.mdPhase 6. - Add CI
failureStrategieson update — when inserting signing into a CI stage, ensure the stage hasfailureStrategieswithMarkAsFailure(notIgnore). Missing orIgnorehides signing failures asIgnoreFailedwhile the pipeline continues. - Warn when no build/push step — if the pipeline has no image build/push step, warn that signing will target a pre-existing registry image; confirm the tag exists and was pushed before signing.
- Surgical YAML only —
harness_updatemust start from the exactyamlPipelinereturned byharness_getin this session. Insert or update only theSscaArtifactSigningstep (and CIfailureStrategiesif required). Never add, remove, or reorder other steps. Never addHarnessSAST,HarnessSCA, STO scanners, or/configure-repo-scansteps — use those skills only when the user explicitly asks for code/container scanning.
Full phase prompts: references/interactive-wizard-flow.md.
Instructions
Wizard phases
| Phase | Breadcrumb | Action |
|---|---|---|
| 0 | Pipeline | AskQuestion: pipeline URL ready? |
| 1 | Pipeline | Collect URL → harness_get |
| 2 | Pipeline | Display structure; note build/push + existing signing steps; flag missing uploadSignature.upload: true |
| 2b | Pipeline | If SscaArtifactSigning exists — AskQuestion: update, add second, or abort |
| 3 | Placement | Mandatory AskQuestion: stage + position + anchor push step (after build/push recommended) |
| 4 | Source | AskQuestion: Third-Party, HAR, or Local |
| 5 | Source | AskQuestion: registry provider (Third-Party only) |
| 6 | Details | Connector — list all matches via harness_list + filters.type (skip if obvious) |
| 7 | Details | Image / registry fields; optional digest expression |
| 8 | Signing | AskQuestion: keyless, keybased, vault |
| 9 | Upload | AskQuestion: attach .sig to registry (container images only) |
| 10 | Submit | AskQuestion: confirm pipeline update |
After Phase 10 confirm → generate YAML, insert step, harness_update, then provide summary (do not run the pipeline).
Supported stage types
| Stage type | Placement notes |
|---|---|
CI |
Recommended — immediately after BuildAndPush* or image push step |
Security |
End of stage when signing pre-built registry images |
Deployment |
Not supported by Harness today — warn user; prefer CI signing |
After the wizard — backend steps
Extract connectors from pipeline YAML
From BuildAndPushDockerRegistry, BuildAndPushECR, BuildAndPushGCR, BuildAndPushGAR,
BuildAndPushACR, Kaniko/Run push steps, SscaOrchestration, SscaArtifactSigning, or
provenance steps — reuse connectorRef / connector. Signing source uses connector (not
connectorRef).
Generate Artifact Signing step YAML
Use only wizard answers. Docker Third-Party uses source.spec.image (not repo).
Docker Registry — key-based signing (Harness docs reference):
- step:
identifier: artifactsigning
name: Artifact Signing
type: SscaArtifactSigning
spec:
source:
type: docker
spec:
connector: lavakush07
image: lavakush07/easy-buggy-app:v5
signing:
type: cosign
spec:
private_key: account.cosign_private_key
password: account.cosign_password
uploadSignature:
upload: true
timeout: 15m
Keyless signing (Harness OIDC) — include upload when pushing .sig:
signing:
type: keyless
spec:
oidcProvider: harness
uploadSignature:
upload: true
Non-Harness keyless OIDC (requires account Connector for Keyless Signing):
signing:
type: keyless
spec:
oidcProvider: non-harness
uploadSignature:
upload: true
Harness Artifact Registry (HAR):
source:
type: har
spec:
registry: <har_registry_identifier>
image: my-image:v5
Harness Local Stage (non-container):
source:
type: local
spec:
workspace: <path_in_workspace>
artifact_name: my-artifact.jar
version: "1.0.0"
No registry upload: omit uploadSignature or set upload: false. Harness still stores signature
metadata internally — but external tools and registry-side verify need upload: true.
Amazon ECR / GCR / GAR / ACR: see references/artifact-signing-step.md — always include
uploadSignature.upload: true when user expects .sig in the registry.
Insert step into pipeline YAML
Critical: Parse yamlPipeline from harness_get and treat it as the only source of truth. Do not
rebuild the pipeline from examples, templates, or assumptions (e.g. cloneCodebase: true does not
imply a Harness Code Scan step).
- Insert at Phase 3 placement — after build/push (or after SBOM/SLSA when present).
- Do not modify unrelated steps, variables, or failure strategies — except add CI
failureStrategiesif the stage has none or usesIgnore(useMarkAsFailure). - Before
harness_update, diff mentally: step count must increase by at most one (or zero if updating an existingSscaArtifactSigning). If any new step types appear (e.g.HarnessSAST), stop and fix the YAML — do not save. - Step identifier:
artifactsigning(useartifactsigning_2, etc. if duplicate). CD Deploy placement is unsupported — do not use_cdsuffix for signing steps.
CI stage must include failureStrategies (API may accept saves without it, but runs show
IgnoreFailed when signing fails):
failureStrategies:
- onFailure:
errors: [AllErrors]
action:
type: MarkAsFailure
Update pipeline via MCP
harness_update
resource_type: pipeline
resource_id: <pipeline_identifier>
org_id: <organization>
project_id: <project>
body: { yamlPipeline: "<updated pipeline YAML>" }
On validation errors, read the API message. Common fixes: image vs repo, signing vs attestation,
private_key / password secret refs for key-based cosign.
Provide summary
Report the results to the user (same pattern as /configure-repo-scan — do not execute the pipeline):
## Artifact Signing Configured
**Pipeline:** <pipeline_name>
**Step:** Artifact Signing (SscaArtifactSigning)
**Location:** Stage "<stage_name>", <position>
**Source:** docker — <connector> — <image>
**Signing:** Keyless (Harness OIDC) — or as configured
**Upload .sig:** Yes / No
**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 Artifact Signing step in Pipeline Studio to adjust Advanced settings.
**Signature:** After a successful run, view on the Supply Chain tab and Chain of Custody.
### Next Steps
1. Run the pipeline via `/run-pipeline` to verify the Artifact Signing step executes successfully
2. If the run fails, diagnose with `/debug-pipeline`
3. If **no `.sig` in registry**, confirm `uploadSignature.upload: true` — see Troubleshooting
4. Add verification with `/verify-sign`
5. Add SBOM/SLSA **before** signing if not present (`/manage-supply-chain` or `SscaOrchestration` / `provenance`)
6. Automate with `/create-trigger`
Examples
After Docker build/push — key-based sign + upload .sig
/sign-artifact
Add artifact signing after docker push — lavakush07/easy-buggy-app:v5, key-based with account cosign secrets, upload signature
Keyless on Harness Cloud
/sign-artifact
Use defaults — keyless Harness OIDC after Build_and_Push, attach signature to registry
Harness Artifact Registry
/sign-artifact
Sign image my-service:v2 from Harness Artifact Registry registry-id prod-har — keyless
Placement must be explicit
/sign-artifact
add signing to the pipeline
Agent must still run Phase 2 + Phase 3 — do not assume stage or skip placement.
Fix missing .sig in registry
/sign-artifact
Signing step succeeded but no .sig in Docker Hub — update existing artifactsigning step to upload signature
Agent must inspect existing YAML for uploadSignature, set upload: true, ensure signing runs
after build/push sequentially, then run the pipeline via /run-pipeline.
Performance Notes
- Only existing pipelines — do not create standalone signing pipelines.
- Wizard UX is mandatory — one question per turn; see
references/interactive-wizard-flow.md. - Docker source uses
image— notrepo(SLSAprovenanceusesrepo; SBOM usesimage). - Signing block is
signing— notattestation(SLSA generation) orverifySign(verification). - HAR is a first-class source —
source.type: harwithregistry+image; offer even if UI shows only Third-Party + Local tiles. - Deploy stage signing unsupported — warn if user picks CD Deploy placement.
- Upload .sig — container images only; maps to
uploadSignature.upload: true. Harness UI defaults this to unchecked — missing block = no registry upload. - One signing step = one image — monorepos need multiple steps or sequential runs per image.
- Key-based signing — private key + password must be Harness file secrets (
/create-secret). - Do not execute pipelines in this skill — use
/run-pipelineafter configuration (same as/configure-repo-scan). - Do not use for dashboard-only SSCA config — use
/manage-supply-chaininstead.
Troubleshooting
Pipeline Not Found
- Verify org/project;
harness_list(resource_type:pipeline).
Connector Not Found
- Search build/push steps for
connectorRef. - List connectors with
harness_list+filters: { type: "DockerRegistry" }(notharness_search, notparams.filterType). Query project, org, and account scopes; see Phase 6 inreferences/interactive-wizard-flow.md.
Image Not Found / Invalid Reference
- Docker: single
imagestring — e.g.lavakush07/easy-buggy-app:v5. - HAR:
registryidentifier +imagename with tag or digest.
Signing Failed (Key-based)
- Verify file secrets exist and Cosign key is
ecdsa-p256. - Try
signing.type: cosignwithprivate_key+passwordifkeybasedfails validation. - JFrog registries need extra connector permissions for signature upload.
Signing Failed (Keyless)
- Requires Harness CI execution context; configure Connector for Keyless Signing for non-harness OIDC.
.sig Not in Registry (step succeeded)
Most common cause: uploadSignature.upload is missing or false. Harness defaults the UI checkbox
Attach signature to Artifact Registry to unchecked — signature is stored in Harness only.
Fix checklist:
- Set
uploadSignature.upload: trueon theSscaArtifactSigningstep (container images only). - Re-run pipeline after updating YAML — existing successful runs do not retroactively upload.
- Confirm signing step uses the same connector and image tag as the build/push step.
- Place signing sequentially after build/push — not in parallel with push, SBOM, or SLSA.
- Check step logs for upload/push errors (403 = connector lacks write permission to push signature tags).
- Docker Hub / OCI registries: Cosign pushes signatures as separate manifest tags (e.g.
sha256-<digest>.sig) or OCI referrers — not always visible as a.sigfile in the UI. Usecosign verifyCLI or Harness Supply Chain tab to confirm. - JFrog Artifactory: connector needs permission to push signature artifacts alongside the image.
- ECR/GCR/GAR/ACR: connector must have push permissions; use digest pinning if tag was overwritten between push and sign.
SBOM / SLSA / Signing Race
- Symptom: missing
.sigor attestation in registry — steps ran in parallel. - Fix: reorder — build/push → SBOM → SLSA → signing sequentially in the same stage.
Existing Signing Step Without Upload
- Inspect YAML: if
uploadSignatureis absent, Harness treated upload as disabled. - Ask user: update existing step with
upload: truevs add new step.
Deploy Stage Not Supported
- Harness docs: artifact signing in Deploy stage is on the roadmap — use CI stage instead.
YAML Validation Errors
- Step
typemust beSscaArtifactSigning. - Docker source requires
connector+image(notrepo). uploadSignature.uploadis boolean — UI checkbox "Attach signature to Artifact Registry".
Skipped Placement
- Re-run wizard from Phase 2; ask stage + position explicitly.
Pipeline Run Failed
- Use
/run-pipelineto execute and/debug-pipelineto diagnose failures - Map branch/tag into
inputsvia/run-pipelinefor codebase pipelines - If stage status is
IgnoreFailed, signing likely failed — inspectartifactsigningstep logs; add or fixfailureStrategies: MarkAsFailureon the CI stage
Signing step failed but pipeline continued (IgnoreFailed)
- CI stage is missing
failureStrategiesor usesIgnore/ non-blocking failure strategy. - Fix: set
failureStrategies→MarkAsFailureon the CI stage, then re-run.
Unexpected Harness Code Scan / STO Step After Update
- Cause: agent sent a reconstructed full
yamlPipelineinstead of the fetched YAML + signing insert. - Fix:
harness_getthe pipeline, delete the unwantedHarnessSAST/ STO step from YAML, save viaharness_update, or remove the step in Pipeline Studio. - Prevention: follow rule 20 (Surgical YAML only) — never add scan steps in this skill.
MCP Errors
CONNECTOR_NOT_FOUND— verify connector identifier.ACCESS_DENIED— PAT needs pipeline edit permission.harness_updatetimeout — retry once; if MCP bubble times out, provide YAML summary for manual paste in Pipeline Studio.