enforce-slsa · v1.0.0 · 2026-10-14 · sha256 b22eb7bc51735d86
enforce-slsa v1.0.0A
Immutable. This exact content never changes and is served at /api/v1/blob/b22eb7bc51735d86.
---
name: enforce-slsa
description: >-
Add an SLSA Verification (SlsaVerification) step to an existing Harness pipeline to verify SLSA
provenance attestations and optionally enforce OPA policy sets on provenance data. Supports CI and
CD (Deployment) including CI-only pipelines — append a Deploy stage via Phase 3b when verifying
before deploy. Supports Docker, ECR, GCR, GAR, ACR, HAR, and Local artifacts. Only works with
existing pipelines. Use when asked to verify SLSA, enforce SLSA policies, add SLSA verification
step, validate SLSA attestation, or gate deploy on SLSA provenance.
Trigger phrases: enforce SLSA, SLSA verification, verify SLSA, SLSA policy enforcement,
SlsaVerification, verify SLSA attestation, add SLSA verify step.
metadata:
author: Harness
version: 1.0.0
mcp-server: harness-mcp-v2
summary: Add SLSA Verification (verify attestation + OPA policy sets on provenance) to pipelines
license: Apache-2.0
compatibility: Requires Harness MCP v2 server (harness-mcp-v2)
---
# Enforce SLSA
Add an **SLSA Verification** (`SlsaVerification`) step to an existing Harness pipeline. The step
verifies SLSA provenance attestations (when enabled) and optionally evaluates OPA policy sets against
provenance data.
This skill only works with **existing pipelines** — do not create standalone verification-only pipelines.
**Prerequisites:** SLSA provenance must already exist for the artifact (typically from a `provenance`
step via `/generate-slsa` — UI label SLSA Generation). Optional **policy sets** for provenance
enforcement (`/create-policy`, `harness_list` `policy_set`).
**Supported stages:** CI, CD (`Deployment`), and Security. CD requires a **containerized step group**.
Unlike SBOM enforcement, CI and CD both use **`SlsaVerification`** (no separate CD step type).
Guide the user through a **step-by-step interactive wizard** (same UX as `/generate-slsa`):
- Wizard: `references/interactive-wizard-flow.md`
- UI ↔ YAML: `references/slsa-verification-step.md`
- CD containerized step groups: `skills/security/generate-slsa/references/cd-containerized-step-group.md`
---
## Interaction model (mandatory)
1. **One question per turn** — use `AskQuestion` when available; otherwise numbered options with `(Recommended)`.
2. **Opening message** — add SLSA Verification; mention generation + optional policy prerequisites.
3. **Progress breadcrumb** — after pipeline fetch:
`Pipeline · Placement · Source · Details · Verify · Policy · Submit`
4. **Record answers** — running summary; do not re-ask unless the user changes direction.
5. **Fetch before configure** — `harness_get` before placement/source questions.
6. **Show pipeline structure** — highlight `provenance` (SLSA Generation) and connectors.
7. **Infer source from generation** — when one `provenance` step exists (or `identifier: slsageneration`), reuse its source (map `repo` → `image_path`, lowercase → PascalCase types).
8. **Never guess image tags** — default from generation step; ask if ambiguous.
9. **Confirm before write** — summary + `harness_update` only after user confirms.
10. **Stop after update** — after successful `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`).
11. **CD on CI-only pipeline** — do not reject CD verify; run Phase 3b to add Deploy stage + containerized group.
12. **Verify method must match generation** — keyless ↔ keyless, keybased ↔ public key from same key pair.
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 missing `provenance` (SLSA Generation) step |
| 3 | Placement | AskQuestion: after generation, CD before deploy, etc. |
| 3b | Placement (CD) | Service, env, infra, step group if new Deploy stage |
| 4 | Source | Infer from generation or pick registry tile |
| 5 | Source | Registry provider (Third-Party only) |
| 6 | Details | Connector (skip if obvious) |
| 7 | Details | Image / image_path (default from generation) |
| 8 | Verify | AskQuestion: verify attestation method |
| 9 | Policy | AskQuestion: policy set(s) or skip |
| 10 | Submit | AskQuestion: confirm pipeline update |
After Phase 10 `confirm` → insert step, `harness_update`, then provide summary (do not run the pipeline).
### Supported stage types
| Stage type | Step `type` | Placement notes |
|------------|-------------|-----------------|
| `CI` | `SlsaVerification` | **After** `provenance` / `slsageneration` in the same stage |
| `Deployment` | `SlsaVerification` | Containerized step group; **before** deploy |
| `Security` | `SlsaVerification` | After generation when artifact is in registry |
### CD edge case
If no `Deployment` stage and user chose CD verify:
> No CD Deploy stage yet. We can add a **Deployment** stage with a **containerized step group** and
> place **SLSA Verification** before deploy.
Run Phase 3b (service, environment, infrastructure, `stepGroupInfra`) — mirror `/generate-slsa` Phase 3b.
Use `skills/security/generate-slsa/references/cd-containerized-step-group.md` with `SlsaVerification`.
### After the wizard — backend steps
#### Check prerequisites
1. **SLSA generation** — pipeline contains `type: provenance` (SLSA Generation) or user confirms provenance exists.
2. **Policy sets** (optional) — `harness_list(resource_type="policy_set")`. If user wants policy
enforcement and none exist, direct to `/create-policy` before continuing.
#### Extract context from pipeline YAML
From `provenance` step (if present — also match `identifier: slsageneration`), copy and transform:
| Generation | Verification |
|------------|--------------|
| `source.type: docker` | `source.type: Docker` |
| `source.spec.repo` | `source.spec.image_path` |
| `source.spec.connector` | `source.spec.connector` |
| `spec.attestation` | matching `verify_attestation` (private → public key for keybased) |
#### Generate SLSA verification step YAML
**CI / Security — Docker Registry, keyless verify:**
```yaml
- step:
identifier: slsaverification
name: SLSA Verification
type: SlsaVerification
spec:
source:
type: Docker
spec:
connector: lavakush07
image_path: lavakush07/easy-buggy-app:blog
verify_attestation:
type: keyless
spec:
oidcProvider: harness
timeout: 15m
```
**Key-based verify** (generation used `keybased` + private key):
```yaml
verify_attestation:
type: keybased
spec:
publicKey: account.cosign_public_key
```
If API validation rejects flat `keyless` / `keybased`, retry with nested `cosign` wrapper — see
`references/slsa-verification-step.md`.
**Policy enforcement** (Advanced tab — step-level `enforce`):
```yaml
enforce:
policySets:
- slsa_provenance_rules
```
**No attestation verify** (policy-only): omit `verify_attestation`.
**CD Deploy** — same step type inside containerized `stepGroup`; use `<+artifact.image>` for
`image_path` when verifying service artifacts.
Full provider mapping: `references/slsa-verification-step.md`.
#### Insert step into pipeline YAML
- Insert at Phase 3 placement — **after** `slsageneration` when possible.
- Do not modify unrelated steps.
- Step identifier: `slsaverification` (use `slsaverification_cd` in CD when CI already has one).
- **CD:** inside containerized step group only.
#### 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, check PascalCase `source.type`, `image_path` vs `repo`, and `verify_attestation`
shape (prefer flat `keyless`; fallback nested `cosign`).
#### Provide summary
Report the results to the user (same pattern as `/configure-repo-scan` — do **not** execute the pipeline):
```
## SLSA Verification Configured
**Pipeline:** <pipeline_name>
**Step:** SLSA Verification (SlsaVerification)
**Location:** Stage "<stage_name>", <position>
**Source:** Docker — <connector> — <image_path>
**Verify attestation:** Keyless (Harness OIDC) — or as configured
**Policy sets:** <list or none>
**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 SLSA Verification step in Pipeline Studio to adjust Advanced settings.
### Next Steps
1. Run the pipeline via `/run-pipeline` to verify SLSA verification executes successfully
2. If the run fails, diagnose with `/debug-pipeline`
3. View verification outcome on the execution **Supply Chain** tab
4. If **Failed** due to policy deny, tune policies via `/create-policy`
5. Add generation with `/generate-slsa` if provenance was missing
6. Automate with `/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.
---
## Examples
### Verify after SLSA Generation
```
/enforce-slsa
Add SLSA verification after slsa-generation — keyless verify, policy set slsa_prod_rules
```
### CD before deploy
```
/enforce-slsa
Verify SLSA in deploy stage before K8s rolling deploy for easy-buggy-app:blog
```
### Key-based verify (matches keybased generation)
```
/enforce-slsa
Verify SLSA with public key account.cosign_public_key — same image as generation step
```
---
## Performance Notes
- Only **existing pipelines** (may append Deploy stage).
- **Wizard UX mandatory** — one question per turn.
- **Reuse generation source** — scan for `type: provenance` or `identifier: slsageneration`; map `repo` → `image_path`, lowercase → PascalCase types.
- **Verification `source.type` is PascalCase** (`Docker`) — generation uses lowercase (`docker`).
- **`verify_attestation`** is snake_case (not `verifyAttestation`). Prefer flat `type: keyless` + `oidcProvider` (same shape as generation `attestation`).
- Policy sets on step **`enforce.policySets`** — not `spec.policy` like SBOM enforcement.
- List `policy_set` via MCP — do not invent identifiers.
- **CD:** containerized step group only; see `skills/security/generate-slsa/references/cd-containerized-step-group.md`.
- **Do not execute pipelines** in this skill — use `/run-pipeline` after configuration (same as `/configure-repo-scan`).
- Pair with `/generate-slsa` (generate) and `/create-policy` (OPA rules).
---
## Troubleshooting
### No SLSA Generation Step
- Add `/generate-slsa` first with attestation enabled (`type: provenance` in YAML).
- Verification needs `.att` in registry or provenance in SCS Artifacts.
- Scan for `provenance` steps — not `SlsaGeneration` (API uses `provenance`).
### Attestation Verification Failed
- Verify method must match generation (`keyless` vs `keybased`).
- Keybased: use **public** key secret (generation uses **private** key).
- Keyless non-harness: configure Connector for Keyless Signing.
### Wrong Image / No Provenance
- Use same `image_path` as generation `repo` field.
- Symptom: verify passes wrong artifact — image mismatch.
### Policy Evaluation Failed
- Review policy set Rego rules; check Supply Chain tab for violations.
- Confirm policy set identifier (not display name) in `enforce.policySets`.
### YAML Validation Errors
- `source.type` must be PascalCase for verification (`Docker`, not `docker`).
- Docker source uses `image_path`, not `repo`.
- `verify_attestation`: use flat `type: keyless` + `spec.oidcProvider: harness` — not nested `cosign` unless API rejects flat shape.
- `DUPLICATE_IDENTIFIER` — rename `slsaverification`.
### CD Step Errors
- Place inside `stepGroup` with `stepGroupInfra` — not top-level `execution.steps`.
- See `skills/security/generate-slsa/references/cd-containerized-step-group.md`.
### User Chose CD on CI-Only Pipeline
- Expected — run Phase 3b; do not force CI-only unless user changes direction.
### Pipeline Run Failed
- Use `/run-pipeline` to execute and `/debug-pipeline` to diagnose failures
- Confirm verify method matches generation attestation; check public key for keybased
- Missing runtime inputs: provide branch/tag or deploy inputs via `/run-pipeline` or Harness UI Run
### MCP Errors
- `CONNECTOR_NOT_FOUND` — verify connector in Project Settings.
- `ACCESS_DENIED` — PAT needs pipeline edit and policy read permissions.