StackPractices
intermediate By Mathias Paulenko

Vendor Risk Assessment Template

A template for evaluating third-party vendor security and operational risks.

Topics: security

Overview

Third-party vendors process your data, integrate with your APIs, and often have privileged access to your systems. A vendor breach becomes your breach — the CL0P ransomware campaign against MOVEit hit hundreds of organizations through a single file-transfer vendor. Most security questionnaires are ignored after onboarding, which is why point-in-time reviews keep failing. This template structures a repeatable vendor risk assessment — the core artifact of any third-party risk management (TPRM) program — for evaluating vendors before contract signing, during annual reviews, and after any security incident involving the vendor.

When to Use

Use this resource when:

  • Onboarding a new SaaS provider, cloud vendor, or outsourced development team
  • Conducting an annual security review of existing vendors
  • A vendor discloses a breach or changes their security posture

For penetration-test follow-up rather than vendor evaluation, see the Penetration Test Remediation Template.

Solution

# Vendor Risk Assessment: `<Vendor Name>`

## 1. Vendor Metadata

| Field | Value |
|-------|-------|
| Vendor Name | `name` |
| Service Provided | `description` |
| Data Access Level | `None / Read / Write / Admin` |
| Data Types Handled | `PII / PHI / Financial / Confidential / Public` |
| Contract Value | `$X / year` |
| Criticality Rating | `Low / Medium / High / Critical` |
| Assessment Date | `YYYY-MM-DD` |
| Assessor | `@security-team` |
| Next Review Date | `YYYY-MM-DD` |

## 2. Security Controls

| Control Category | Vendor Claim | Evidence Requested | Verified | Risk |
|------------------|--------------|-------------------|----------|------|
| SOC 2 Type II | Yes / No | Report (last 12 months) | | |
| ISO 27001 | Yes / No | Certificate | | |
| GDPR / CCPA Compliance | Yes / No | DPA + privacy policy | | |
| Encryption at Rest | Yes / No | Architecture doc / screenshot | | |
| Encryption in Transit (TLS 1.2+) | Yes / No | SSL Labs scan | | |
| MFA for Admin Access | Yes / No | Configuration screenshot | | |
| Penetration Test (annual) | Yes / No | Report summary (redacted) | | |
| Incident Response Plan | Yes / No | Document + SLAs | | |
| Sub-processors Published | Yes / No | Sub-processor list | | |

## 3. Operational Risk

| Factor | Rating | Justification | Mitigation |
|--------|--------|---------------|------------|
| Financial stability | `Low / Med / High` | | |
| Geographic / political risk | `Low / Med / High` | | |
| Concentration risk (sole provider) | `Low / Med / High` | | |
| Integration complexity | `Low / Med / High` | | |
| Exit difficulty (data portability) | `Low / Med / High` | | |

## 4. Data Handling Assessment

| Question | Vendor Response | Satisfactory |
|----------|----------------|--------------|
| Where is data stored? | `Region / country` | Yes / No |
| Who can access our data? | `Role / process` | Yes / No |
| Is data commingled with other customers? | `Yes / No / Multi-tenant` | Yes / No |
| Data retention after contract end? | `Days / policy` | Yes / No |
| Can we request deletion? | `Process / SLA` | Yes / No |
| Backup frequency and retention? | `Frequency / retention` | Yes / No |

## 5. Risk Score

| Category | Weight | Raw Score (1-5) | Weighted Score |
|----------|--------|-----------------|----------------|
| Security posture | 30% | | |
| Compliance | 25% | | |
| Operational resilience | 20% | | |
| Data protection | 25% | | |
| **Total** | **100%** | | |

### Score Interpretation

| Range | Rating | Action |
|-------|--------|--------|
| 4.0 – 5.0 | Low Risk | Standard contract; annual review |
| 3.0 – 3.9 | Medium Risk | Require remediation plan; 6-month review |
| 2.0 – 2.9 | High Risk | Security improvements required before onboarding |
| 1.0 – 1.9 | Critical Risk | Do not onboard without CISO approval + external audit |

## 6. Remediation Plan (if applicable)

| Gap | Required Action | Owner | Due Date | Status |
|-----|----------------|-------|----------|--------|
| | | | | |

Explanation

The template treats vendor assessment as a structured, evidence-based process, not a checkbox exercise. Each control requires evidence, not just a “yes.” The risk scoring forces trade-offs: a cheap vendor with poor encryption may be acceptable for public marketing data but never for health records. The data handling section matters most because vendors often commingle customer data in multi-tenant architectures, making deletion and breach containment harder.

Vendor Risk Assessment Process

flowchart diagram: Intake request
  1. Identification — the team requesting a new vendor fills the assessment request with the use case and the data to share; security assigns an evaluator.
  2. Initial questionnaire — send the security questionnaire (SOC 2, ISO 27001) and request certifications, policies and audit reports; check the status page and breach-notification policy. Two-week response deadline works well.
  3. Technical assessment — authentication (SSO, MFA, SAML), encryption in transit and at rest, access management, data retention and deletion, residency, and sub-processors.
  4. Compliance assessment — map regulatory requirements, review the Data Processing Agreement, verify breach notification clauses (72 hours under GDPR) and audit rights.
  5. Decision — compute the weighted score, get sign-off from security, legal and engineering, and document conditions.
  6. Continuous monitoring — annual review, incident notifications and sub-processor changes; reassess when the vendor’s posture changes.

Verifying the SOC 2 report

A SOC 2 badge on a landing page isn’t evidence. When the report arrives, check:

  • The report covers the specific service you will use — vendors with multiple products often scope only the flagship one.
  • The period is current (within the last 12 months) and it’s Type II, not Type I.
  • The trust services criteria match your requirements: Security is always included; Availability, Confidentiality, Processing Integrity and Privacy are optional.
  • There is no qualified opinion and exceptions are minor — read the exceptions section, not just the opinion.
  • The system description matches the architecture the sales team described.

Automating the assessment

Between formal reviews you can watch a vendor’s public security posture with a few API calls. This script checks DNSSEC, TLS grade, security.txt, and breach history for a vendor domain:

import os
import requests
from dataclasses import dataclass, field

@dataclass
class VendorSecurityCheck:
    vendor_name: str
    domain: str
    results: dict = field(default_factory=dict)

    def check_dnssec(self) -> None:
        """Check if the vendor domain has DNSSEC enabled."""
        try:
            resp = requests.get(
                f"https://dns.google/resolve?name={self.domain}&type=DNSKEY",
                timeout=10
            )
            self.results["dnssec"] = (
                "enabled" if resp.json().get("Answer") else "disabled"
            )
        except Exception:
            self.results["dnssec"] = "error"

    def check_tls(self) -> None:
        """Check TLS configuration via the SSL Labs API."""
        try:
            resp = requests.get(
                f"https://api.ssllabs.com/api/v3/analyze?host={self.domain}"
                f"&all=done&ignoreMismatch=on",
                timeout=15
            )
            data = resp.json()
            # The API is async: it returns a status until the scan finishes.
            if data.get("status") != "READY":
                self.results["tls_grade"] = f"pending ({data.get('status')})"
            else:
                grades = [e.get("grade") for e in data.get("endpoints", [])]
                self.results["tls_grade"] = min(g for g in grades if g)
        except Exception:
            self.results["tls_grade"] = "error"

    def check_security_txt(self) -> None:
        """Check for a published security contact file."""
        url = f"https://{self.domain}/.well-known/security.txt"
        try:
            resp = requests.head(url, timeout=10, allow_redirects=True)
            self.results["security_txt"] = url if resp.status_code == 200 else "not found"
        except Exception:
            self.results["security_txt"] = "not found"

    def check_breach_history(self) -> None:
        """Check domain breach history via Have I Been Pwned.

        Requires a paid API key in the HIBP_API_KEY env var; the
        /breacheddomain endpoint returns breaches that included the domain.
        """
        key = os.environ.get("HIBP_API_KEY")
        if not key:
            self.results["breaches"] = "skipped (no HIBP_API_KEY)"
            return
        try:
            resp = requests.get(
                f"https://haveibeenpwned.com/api/v3/breacheddomain/{self.domain}",
                headers={"hibp-api-key": key, "User-Agent": "VendorAssessment/1.0"},
                timeout=10
            )
            if resp.status_code == 200:
                self.results["breach_count"] = len(resp.json())
            elif resp.status_code == 404:
                self.results["breach_count"] = 0
            else:
                self.results["breaches"] = f"error {resp.status_code}"
        except Exception:
            self.results["breach_count"] = "error"

    def run_all(self) -> dict:
        self.check_dnssec()
        self.check_tls()
        self.check_security_txt()
        self.check_breach_history()
        return self.results

# Example usage
vendor = VendorSecurityCheck(vendor_name="Acme Cloud", domain="acmecloud.com")
for key, value in vendor.run_all().items():
    print(f"  {key}: {value}")

And this scores the questionnaire once the answers come back:

from dataclasses import dataclass, field

@dataclass
class VendorRiskScorer:
    scores: dict  # category -> score (1-5)
    weights: dict = field(default_factory=lambda: {
        "security": 0.30,
        "compliance": 0.25,
        "operational": 0.20,
        "data_protection": 0.25,
    })

    @property
    def total_score(self) -> float:
        return round(sum(
            self.scores.get(cat, 0) * weight
            for cat, weight in self.weights.items()
        ), 2)

    @property
    def decision(self) -> str:
        score = self.total_score
        if score >= 4.0:
            return "LOW RISK — standard contract, annual review"
        if score >= 3.0:
            return "MEDIUM RISK — remediation plan, 6-month review"
        if score >= 2.0:
            return "HIGH RISK — improvements required before onboarding"
        return "CRITICAL RISK — do not onboard without CISO approval"

    @property
    def critical_gaps(self) -> list:
        return [
            f"{cat}: {score}/5 is critical"
            for cat, score in self.scores.items() if score <= 2
        ]

# Example usage
scorer = VendorRiskScorer(scores={
    "security": 4, "compliance": 5, "operational": 3, "data_protection": 4,
})
print(scorer.total_score)   # 4.05
print(scorer.decision)      # LOW RISK — standard contract, annual review

Run both from CI weekly and store results next to the assessment — a vendor whose TLS grade drops from A to C between reviews is a signal worth a re-assessment.

Tiering vendors before you assess

Running the full template on every vendor wastes review cycles — a three-person SaaS that renders your logo shouldn’t get the same scrutiny as the processor hosting your database. Tier by data access, not by contract size:

TierProfileAssessment depth
CriticalHandles PII/PHI, privileged access, or hard to replaceFull template + SOC 2 verification + annual re-review
StandardBusiness data, replaceable, standard integrationsFull template, no site visit; re-review at renewal
LowPublic data only, no integrationsShort questionnaire (10 questions) + posture checks from the automation section

Tiering also answers “how deep should the questionnaire go” — SIG Lite (~150 questions) maps to the Standard tier, while Critical vendors justify the full SIG. If your organization already classifies data, reuse those labels from the data classification template so tiers stay consistent.

Variants

ContextFocusAdditional Checks
Cloud infrastructure (IaaS)Shared responsibility modelVerify where provider responsibility ends and yours begins
SaaS with API integrationOAuth / token securityReview scopes, token rotation, and webhook signing
Outsourced developmentSource code accessNDA, background checks, secure development practices
Payment processorPCI DSSRequire AoC (Attestation of Compliance) and SAQ
AI / ML vendorModel training dataVerify your data is not used to train models unless explicitly agreed

What Works

  1. Assess vendors before contract signature, not after onboarding
  2. Require a Data Processing Agreement (DPA) for any vendor touching PII
  3. Review sub-processors annually; a vendor’s vendor is still your risk
  4. Maintain an offboarding checklist that includes data deletion verification
  5. Document the rationale for any accepted risk; auditors will ask for it

Common Mistakes

  1. Accepting a vendor’s security questionnaire without requesting evidence
  2. Treating all vendors the same regardless of data sensitivity or access level
  3. Not re-assessing vendors after a breach or acquisition
  4. Ignoring sub-processors; many breaches happen at the fourth-party level
  5. Having no exit plan; vendors know migration costs keep you locked in

Troubleshooting

  • Vendor stalls on the questionnaire: send the short form first (10 questions on encryption, access control, and incidents) and escalate the full one only if they pass. Vendors who can’t answer the short version rarely pass anyway.
  • Assessors disagree on scores: score independently, then discuss only the categories with 2+ points of divergence. Average the rest and move on.
  • Evidence is stale: treat any document older than 12 months as missing. A SOC 2 from two years ago tells you they were compliant once — nothing about today.
  • Legacy vendor predates the process: run a retroactive assessment ordered by data-access level; don’t try to grandfather vendors through.

Further Reading

Frequently Asked Questions

How do I assess a startup that has no SOC 2 yet?

Request their security roadmap and interim controls. Review their architecture for encryption, access control, and logging. Conduct a lightweight technical assessment (architecture review + penetration test of the integration). Accept higher risk only if the vendor is critical and no mature alternative exists. Require SOC 2 Type I within 12 months as a contract clause.

What is a Data Processing Agreement and when do I need one?

A DPA is a legal contract that defines how a vendor (processor) handles your data under GDPR / CCPA. You need one whenever a vendor processes personal data on your behalf. The DPA should cover data categories, processing purposes, sub-processors, security measures, breach notification SLAs, and deletion requirements.

How do we handle vendors already in use without assessment?

Start with the ones holding Restricted or Confidential data and run them through the same process retroactively — everyone else queues behind risk, not seniority. Where the assessment turns up unacceptable risk, mitigate first (restrict access, add monitoring, tighten contract terms) before talking migration. Write down both the gap and the deadline to close it; that's also the evidence you need to make the process mandatory going forward.

What do we do if a vendor suffers a data breach?

Activate your incident response plan — a vendor breach is your breach. Work out what data they held and what leaked: customer records, shared credentials, IP. If customer data was exposed, GDPR gives you 72 hours to notify. Rotate anything you shared with them, and check the contract for notification and compensation clauses. Afterwards, reassess the whole relationship: one breach can be bad luck, but a vendor that didn't notify you inside the contractual window has told you something about how they operate.

How do we evaluate cloud infrastructure vendors (AWS, GCP, Azure)?

Cloud providers sit at the top of the risk pile because of data volume and how hard they are to replace. Check their certifications (SOC 2 Type II, ISO 27001, FedRAMP) and read the shared responsibility model carefully — the line between their job and yours is exactly where outages and breaches land. CSPM tooling covers the continuous-monitoring side. Look at their incident history and how honest their postmortems are, plus the regions and residency options if you have GDPR or HIPAA obligations. All three majors publish extensive compliance documentation — useful, but written by them.

How do we handle vendor sub-processors?

A sub-processor is a vendor your vendor uses to process your data — your vendor's vendor is still your risk. Require full disclosure in the contract, verify the DPA flows the same standards down to them, and subscribe to sub-processor change notifications (you've got the right to object). For Restricted data, check each sub-processor's posture individually and document the whole processing chain. That chain is usually the weakest link in the assessment.

How often should we reassess vendors?

Reassess vendors: annually for vendors with access to Restricted or Confidential data. Biannually for vendors with access to Internal data. Triennially for vendors with access only to Public data. Out-of-cycle reassessment when: the vendor suffers a breach, changes sub-processors, changes terms of service, or changes security posture (e.g., loses a certification). Document each reassessment. If a vendor degrades their security posture: implement mitigations or consider contract termination. A reassessment isn't a rubber stamp — it's a genuine evaluation of whether the vendor still meets your standards.

Who should own the vendor assessment process?

Security or a dedicated risk/GRC team usually runs it, but the data owner in engineering, procurement, and legal all sign off. The requester proposing the vendor should never be the sole assessor — that's a conflict of interest that quietly approves everyone.