Dockyard Container Attestations

January 19, 2026 ยท View on GitHub

This document describes the attestations attached to Dockyard container images for supply chain security.

Overview

Every container image published to ghcr.io/stacklok/dockyard includes multiple attestations:

TypePredicate TypeDescription
SBOMSPDXSoftware Bill of Materials (via Docker buildx)
Build ProvenanceSLSABuild provenance attestation (via Docker buildx)
MCP Security ScanSCAI v0.3Cisco AI Defense mcp-scanner results
SignatureSigstoreKeyless OIDC signature via Cosign

MCP Security Scan Attestation (SCAI)

The MCP security scan attestation uses the SCAI (Software Supply Chain Attribute Integrity) predicate type, an official in-toto attestation format.

Predicate Type

https://in-toto.io/attestation/scai/v0.3

Schema

{
  "_type": "https://in-toto.io/Statement/v1",
  "subject": [{
    "name": "ghcr.io/stacklok/dockyard/npx/context7",
    "digest": { "sha256": "..." }
  }],
  "predicateType": "https://in-toto.io/attestation/scai/v0.3",
  "predicate": {
    "attributes": [{
      "attribute": "MCP_SECURITY_SCAN_PASSED",
      "conditions": {
        "scanner": "cisco-ai-mcp-scanner",
        "scannerVersion": "4.1.0",
        "scannerUri": "https://github.com/cisco-ai-defense/mcp-scanner",
        "analyzers": ["yara"],
        "toolsScanned": 5,
        "blockingIssues": 0,
        "allowedIssues": 1,
        "scanDate": "2026-01-19T12:00:00Z",
        "configFile": "npx/context7/spec.yaml",
        "sourceRepository": "https://github.com/upstash/context7"
      },
      "evidence": {
        "name": "scan-summary.json",
        "digest": { "sha256": "..." },
        "uri": "https://github.com/stacklok/dockyard/actions/runs/...",
        "mediaType": "application/json"
      }
    }],
    "producer": {
      "uri": "https://github.com/stacklok/dockyard",
      "name": "dockyard-ci",
      "digest": { "gitCommit": "..." }
    }
  }
}

Attributes

AttributeDescription
MCP_SECURITY_SCAN_PASSEDScan completed with no blocking security issues
MCP_SECURITY_SCAN_WARNINGScan completed with warnings (insecure_ignore enabled)
MCP_SECURITY_SCAN_FAILEDScan found blocking security issues

Conditions

FieldTypeDescription
scannerstringScanner tool identifier (cisco-ai-mcp-scanner)
scannerVersionstringVersion of the scanner (e.g., 4.1.0)
scannerUristringURI to the scanner source repository
analyzersarrayList of analyzers used (yara, llm)
toolsScannednumberNumber of MCP tools scanned
blockingIssuesnumberCount of blocking security issues
allowedIssuesnumberCount of allowed (non-blocking) issues
scanDatestringISO 8601 timestamp of scan
configFilestringPath to the spec.yaml configuration
sourceRepositorystringSource repository of the MCP server (from spec.yaml provenance)

Evidence

The evidence field links to the full scan results artifact:

  • name: Artifact filename (scan-summary.json)
  • digest.sha256: SHA256 hash of the scan summary for integrity verification
  • uri: Link to the GitHub Actions run where scan was performed
  • mediaType: Content type (application/json)

Verification

Verify Image Signature

cosign verify ghcr.io/stacklok/dockyard/npx/context7:latest

Verify MCP Security Scan Attestation

cosign verify-attestation \
  --type https://in-toto.io/attestation/scai/v0.3 \
  ghcr.io/stacklok/dockyard/npx/context7:latest

Download and Inspect Attestation

# Download all attestations
cosign download attestation ghcr.io/stacklok/dockyard/npx/context7:latest

# Decode and pretty-print SCAI attestation
cosign download attestation ghcr.io/stacklok/dockyard/npx/context7:latest | \
  jq -r 'select(.payloadType == "application/vnd.in-toto+json") | .payload | @base64d | fromjson'

View SBOM

docker buildx imagetools inspect \
  ghcr.io/stacklok/dockyard/npx/context7:latest \
  --format "{{ json .SBOM }}"

Policy Enforcement

Kyverno Example

Enforce that only images with passing MCP security scans can be deployed:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-mcp-security-scan
spec:
  validationFailureAction: Enforce
  rules:
    - name: check-mcp-scan-attestation
      match:
        resources:
          kinds:
            - Pod
      verifyImages:
        - imageReferences:
            - "ghcr.io/stacklok/dockyard/*"
          attestations:
            - type: https://in-toto.io/attestation/scai/v0.3
              attestors:
                - entries:
                    - keyless:
                        issuer: https://token.actions.githubusercontent.com
                        subject: "https://github.com/stacklok/dockyard/.github/workflows/build-containers.yml@*"
              conditions:
                - all:
                    - key: "{{ attributes[0].attribute }}"
                      operator: Equals
                      value: "MCP_SECURITY_SCAN_PASSED"

OPA/Gatekeeper Example

package dockyard.security

deny[msg] {
  input.predicate.attributes[_].attribute != "MCP_SECURITY_SCAN_PASSED"
  msg := "MCP security scan did not pass"
}

deny[msg] {
  input.predicate.attributes[_].conditions.blockingIssues > 0
  msg := sprintf("Found %d blocking security issues", [input.predicate.attributes[_].conditions.blockingIssues])
}

References