Supply Chain & Third-Party Risk
Modern systems depend on hundreds of third-party components — open-source libraries, SaaS integrations, cloud services, and outsourced development. A TRA is incomplete without assessing these dependencies. This section covers SBOM analysis, vendor tiering, OSS risk scoring, and Nth-party cascading risk.
Related Tools & Sections
Supply Chain Risk Landscape
Software Supply Chain Attack Surface
SBOM Analysis
A Software Bill of Materials (SBOM) is the foundation of supply chain risk assessment. Two major standards exist — use both for comprehensive coverage.
SPDX (Linux Foundation)
- • ISO/IEC 5962:2021 standard
- • Focus: license compliance + security
- • Formats: SPDX, JSON, RDF, YAML
- • Strong license expression support
- • Used by: Linux kernel, NTIA guidance
CycloneDX (OWASP)
- • OWASP flagship project
- • Focus: security + vulnerability tracking
- • Formats: XML, JSON, Protocol Buffers
- • Built-in VEX (Vulnerability Exploitability eXchange)
- • Used by: OWASP, DHS CISA, commercial tools
# SBOM Risk Analysis Script
# Analyzes CycloneDX SBOM for supply chain risk indicators
import json
from dataclasses import dataclass, field
from datetime import datetime, timezone
@dataclass
class DependencyRisk:
name: str
version: str
risk_score: float = 0.0
risk_factors: list = field(default_factory=list)
def analyze_sbom(sbom_path: str) -> list[DependencyRisk]:
"""Analyze SBOM for supply chain risk indicators."""
with open(sbom_path, "r") as f:
sbom = json.load(f)
findings = []
components = sbom.get("components", [])
for comp in components:
risk = DependencyRisk(
name=comp.get("name", "unknown"),
version=comp.get("version", "unknown"),
)
# Check for known vulnerabilities
vulns = comp.get("vulnerabilities", [])
if vulns:
critical = sum(
1 for v in vulns
if v.get("severity", "").lower() == "critical"
)
risk.risk_score += critical * 25 + len(vulns) * 5
risk.risk_factors.append(
f"{len(vulns)} known vulns ({critical} critical)"
)
# Check for outdated components
licenses = comp.get("licenses", [])
if not licenses:
risk.risk_score += 10
risk.risk_factors.append("No license declared")
else:
for lic in licenses:
license_id = lic.get("license", {}).get("id", "")
if license_id in ("AGPL-3.0", "GPL-3.0-only"):
risk.risk_score += 15
risk.risk_factors.append(
f"Copyleft license: {license_id}"
)
# Check supplier information
supplier = comp.get("supplier", {})
if not supplier:
risk.risk_score += 10
risk.risk_factors.append("No supplier information")
# Flag components without hashes
hashes = comp.get("hashes", [])
if not hashes:
risk.risk_score += 15
risk.risk_factors.append("No integrity hashes")
if risk.risk_factors:
findings.append(risk)
# Sort by risk score descending
findings.sort(key=lambda r: r.risk_score, reverse=True)
return findings
def generate_risk_report(findings: list[DependencyRisk]) -> str:
"""Generate supply chain risk summary report."""
lines = ["Supply Chain Risk Analysis Report"]
lines.append("=" * 40)
lines.append(
f"Analysis Date: "
f"{datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}"
)
lines.append(f"Components Analyzed: {len(findings)} with findings")
lines.append("")
high_risk = [f for f in findings if f.risk_score >= 50]
medium_risk = [f for f in findings if 20 <= f.risk_score < 50]
low_risk = [f for f in findings if f.risk_score < 20]
lines.append(f"HIGH RISK: {len(high_risk)} components")
lines.append(f"MEDIUM RISK: {len(medium_risk)} components")
lines.append(f"LOW RISK: {len(low_risk)} components")
for risk_level, items in [
("HIGH", high_risk),
("MEDIUM", medium_risk),
]:
if items:
lines.append(f"\n--- {risk_level} RISK ---")
for item in items[:10]:
lines.append(
f" {item.name}@{item.version} "
f"(score: {item.risk_score})"
)
for factor in item.risk_factors:
lines.append(f" - {factor}")
return "\n".join(lines)NIST SSDF (SP 800-218)
The Secure Software Development Framework defines practices that software producers should follow. Use SSDF as an assessment checklist when evaluating vendor security maturity.
| Practice Group | Focus | Key Assessment Questions |
|---|---|---|
| PO — Prepare the Organization | Security governance, roles, tooling | Does the vendor have a documented SDLC? Security team? Training program? |
| PS — Protect the Software | Code integrity, access controls, artifact security | Are builds reproducible? Artifacts signed? Source access controlled? |
| PW — Produce Well-Secured Software | Secure design, code review, testing | Threat modeling done? SAST/DAST in pipeline? Dependency scanning? |
| RV — Respond to Vulnerabilities | Vulnerability disclosure, patching, communication | SLAs for critical patches? Public disclosure policy? CVE assignment? |
Vendor Risk Tiering
Not all vendors require the same assessment depth. Tier vendors based on data access, integration depth, and business criticality to allocate assessment effort efficiently.
Tier 1 — Critical (Full Assessment)
Vendors with direct access to sensitive data or critical business processes.
- • Criteria: Processes PII/PHI/PCI data, has network access, single point of failure
- • Assessment: Full security questionnaire (SIG/CAIQ), SOC 2 Type II review, pentest results, on-site audit, SBOM review
- • Review frequency: Annual + triggered by incidents
- • Examples: Cloud infrastructure (AWS/Azure), payment processor, HRIS, EHR system
Tier 2 — High (Standard Assessment)
Vendors with limited data access or non-critical integrations.
- • Criteria: Internal data access, API integration, indirect customer impact
- • Assessment: Security questionnaire, SOC 2 report review, contract review
- • Review frequency: Annual
- • Examples: Project management SaaS, CI/CD platform, monitoring tools
Tier 3 — Standard (Light Assessment)
Vendors with no data access or minimal integration.
- • Criteria: No sensitive data, website-only tools, replaceable
- • Assessment: Self-attestation, public security page review, contract clauses
- • Review frequency: Biennial or on renewal
- • Examples: Marketing analytics, design tools, office supplies
OSS Criticality Scoring
Open-source dependencies require different risk assessment than commercial vendors. Evaluate them on health metrics rather than questionnaires.
| Risk Factor | Low Risk | Medium Risk | High Risk |
|---|---|---|---|
| Maintainer count | 5+ active maintainers | 2–4 maintainers | Single maintainer |
| Last commit | < 30 days | 30–180 days | > 180 days |
| Security policy | SECURITY.md + disclosure process | Issue-based reporting | No security policy |
| OpenSSF Scorecard | Score ≥ 7/10 | Score 4–6/10 | Score < 4/10 or N/A |
| Signed releases | GPG/Sigstore signed | Checksum only | No verification |
Nth-Party Cascading Risk
Your vendors also have vendors (4th parties), creating cascading dependency chains. A breach at a 4th party can propagate through your entire supply chain.
Nth-Party Risk Cascade
Concentration Risk
SaaS Risk Assessment
SaaS Vendor Risk Assessment Checklist
═════════════════════════════════════
DATA SECURITY
□ Where is data stored? (region, jurisdiction)
□ Encryption at rest (algorithm, key management)
□ Encryption in transit (TLS version, cipher suites)
□ Data isolation model (single-tenant vs multi-tenant)
□ Data retention and deletion policies
□ Right to audit clause in contract
ACCESS CONTROL
□ SSO/SAML/OIDC integration available?
□ SCIM provisioning supported?
□ IP allowlisting capability
□ Role-based access control granularity
□ MFA enforcement options
□ Session management controls
INCIDENT RESPONSE
□ Documented incident response plan?
□ Breach notification SLA (e.g., 72 hours for GDPR)
□ Customer communication process
□ Post-incident report provided?
□ Insurance coverage
COMPLIANCE & ASSURANCE
□ SOC 2 Type II report (current period)
□ ISO 27001 certification (current)
□ Penetration test results (redacted OK)
□ GDPR / CCPA compliance attestation
□ Industry-specific (PCI, HIPAA, FedRAMP)
EXIT STRATEGY
□ Data export format and mechanism
□ Data deletion confirmation upon termination
□ Transition assistance period
□ API data extraction capability
□ Contract termination notice periodSection Summary
Key Takeaways
- • SBOMs (SPDX/CycloneDX) are foundational for dependency risk analysis
- • NIST SSDF provides a vendor security maturity assessment framework
- • Tier vendors by data access and criticality to allocate assessment effort
- • OSS dependencies need health metric evaluation, not questionnaires
- • Map Nth-party dependencies to identify concentration risk
Next Steps
- • Section 09: Cloud & AI Risk — cloud-native and AI/ML risk assessment
- • CI/CD & Supply Chain — pipeline attack patterns
Evidence to Capture
The artefact is dependency-level and vendor-level together: what you ship, what is inside it, who attests to it, and what the contract says when it fails.
Dependency inventory with format and version: SPDX or CycloneDX, the generator used, and the commit or build the document describes. A stale inventory is worse than none.
Dependency detail: Package, version, licence, direct or transitive, and whether it ships to production or exists only in the build.
Vendor assurance artefacts: The report period covered, the certification scope, the penetration test date, and the clauses that allocate responsibility.
Tier and its rationale: The tier the vendor was placed in and the criteria that put it there, since the tier drives how much assurance is required.
Nth-party chain: The dependencies of your critical vendors, and where two vendors share one underlying provider.
Exit and continuity terms: Export format, deletion confirmation and notice period — the terms that bound the part of the risk you cannot reduce.
Supply Chain False Positives
Automated dependency alerts and vendor questionnaires both over-report, and the excess is what gets bulk-closed.
- Component you do not ship: A vulnerable build-time or development-only package, or one excluded from the artefact, is not exposure. Record the reachability argument.
- Version range versus resolved version: A manifest range that permits a vulnerable version says nothing about what is deployed. Check the lockfile and the built artefact.
- Unreachable code path: A flaw in a code path the product never invokes is a recorded finding, not a live risk, and should not carry the same priority.
- Repeated transitive entries: The same library appears once per parent in an inventory. Counting entries overstates the dependency count many times over.
- Vendor gap taken as your risk: A provider internal control gap is their risk under the contract. Yours is the service failure you depend on. Name which you are recording.
- Quiet project assumed compromised: Low maintenance activity is a health signal, not an incident. Weigh it as a likelihood factor rather than a finding.
- Alert flood bulk-closed: Uncontextualised dependency alerts produce a backlog that gets closed in batches, which is worse than a shorter reviewed list.
Tier-Based Treatment and Exit Paths
You cannot patch a vendor. Treatment is contractual and assurance pressure where you cannot change the dependency, upgrade or removal where you can, and a tested exit path for what you cannot replace.
For components
- • Pin and upgrade, or take the package in-house where upstream is unmaintained
- • Enforce lockfile integrity and provenance attestation in the build
- • Remove unused and build-only dependencies from the shipped artefact
For vendors
- • Require current attestation at the tier the data access warrants
- • Write notification, audit and exit clauses into the contract
- • Maintain an exit plan with a tested data export
Review trigger
- • New vendor, or an existing vendor changes tier
- • Vendor security incident or lapsed attestation
- • Critical advisory on a dependency that ships to production