Skip to main content
INS // Insights

Vendor Security Questionnaire Evidence

Updated October 2026 · 8 min read

Vendor security questionnaire evidence is the artifact behind the answer, with a collection time, a period, and a hash. A customer sends a spreadsheet, a portal form, or a SIG-style workbook and asks how you review access, how long you keep logs, and whether people finished training. A paragraph that says "yes, quarterly" is an answer. It is weak evidence. The evidence is the closed access-review export for that quarter, the log-retention configuration, the training gap list, each with the date it was generated. When the same question arrives from the next customer, the row should point at a fresh artifact, not at last spring's PDF.

Rutagon builds that map for SOC 2 teams in the mid-market who already answer these questionnaires by hand. The GRC platform you run holds the control statements and the policies. The questionnaire uses the customer's wording, and it often asks for a sample the platform does not package in that shape. We bind each question we see repeatedly to a control and to a generator that refreshes the artifact. NIST SP 800-53 is the control language many of those questions are loosely translated from. The customer is not asking you to implement the entire catalog. They are asking for proof on the rows they sent. This is a commercial due-diligence questionnaire, the kind a buyer sends before a contract. It is not a proposal response.

What vendor security questionnaire evidence contains

Each repeated question becomes a row in a register. The row has an id, the prompt in the customer's words, the internal control it maps to, the evidence object, the time that object was collected, the period the object covers, a hash, and a maximum age in days. The packager reads the register. If collected_at plus the maximum age is still in the future, the row is fresh and the artifact is attached. If it is stale, the row is omitted from the "current" pack and listed on a gap sheet. We do not attach a stale file under a fresh cover letter.

row_id: access-review-quarter
prompt: How often is user access reviewed, and provide the latest completion record
control: quarterly recertification
evidence_uri: s3://evidence-bucket/access-review/2026-q3/closed.json
collected_at: 2026-10-02
period: 2026-07-01..2026-09-30
max_age_days: 40
sha256: recorded on the object
pack_status: fresh

The hash is how we notice a silent edit. The questionnaire pack stores the hash we sent. The object in the bucket stores the same hash in its metadata. If someone replaces the JSON without writing a new row, the next pack build fails the compare and the row goes to the gap sheet. Replacing evidence in place is a good way to disagree with yourself in front of a customer who saved the previous file.

The generators already exist for the controls that show up on almost every form. A closed access-review campaign is the artifact for the access question, and the shape of that file is the one in exporting access review evidence. A vendor's own access into your environment is a different question, and SOC 2 vendor access evidence is the population for it. Training completion, log retention, and vulnerability aging each have a generator with its own freshness window. The register points at those generators. It does not store a second copy of the narrative.

Freshness windows are specific. An access-review export older than the campaign cadence plus a short buffer is stale. A log-configuration export older than a month is stale if changes are continuous, because the customer is asking what is true now. A policy PDF can live longer if the policy truly did not change, and the row then cites the policy version and the approval date. We pick the window when the row is created. A default of "a year" on every row makes the pack look full and makes it wrong.

How a pack is built for one customer

Customers do not send the same spreadsheet. They send overlapping questions with different numbering. The register is keyed by our control, and each customer template is a list of their row numbers mapped to our row ids. Building a pack for a customer is: walk their template, resolve each map, attach the fresh artifact, and write "no current artifact" on the gap sheet where the map is missing or stale. Someone fills the gaps or accepts a narrower answer. The pack does not invent a yes.

Unmapped questions stay visible. A new prompt about AI training data or about a subprocess we do not have is not forced onto an old control to keep the completion meter green. The gap sheet lists it as unmapped, with the prompt text. The owner either adds a generator, maps it to an existing artifact that actually answers it, or writes a short factual response that is labeled as a statement rather than as evidence. A statement has an author and a date. It is not given a hash that implies a system produced it.

PBC request automation is the same machinery aimed at the auditor's list during the exam. The questionnaire register reuses the generators. The template mapping is the part that differs, because a customer workbook is not the auditor's request list. Keeping two unrelated folder trees is how the customer receives a PDF from March while the auditor receives a JSON from October for the same control. One generator, two consumers.

We keep the customer's completed workbook out of the engineering repository. The pack is data: template id, maps, artifact URIs, the gap sheet. The workbook they sent may contain their own security details and is stored with the deal, not in git. What belongs in the pipeline is our register and the generators. Evidence freshness tracking is the clock those generators share. A questionnaire send that ignores the clock will attach the file that happened to be in the downloads folder.

Names and accounts are trimmed before a file leaves. An access-review export for a customer does not need every employee's email if the question asked for the completion record and the method. We have a redaction step per row: include the fields the prompt asked for, drop the rest. The full export remains in the evidence bucket for the auditor. The customer pack gets the redacted object, and the row records which profile was applied. Sending the full file because it was easier is how a questionnaire response becomes a data incident.

What we stop doing by hand

The manual pattern is a shared drive of answered spreadsheets, each slightly different, none of them tied to a collection date. The next questionnaire starts by copying the previous answers forward. That copy is how a control you changed in June is still described as it worked in January. The register makes the copy unnecessary for every mapped row. The narrative sentence can still be edited by the person who owns the customer relationship. The attachment cannot be older than the window without showing up on the gap sheet.

Ownership is split on purpose. The control owner owns the generator and the freshness window. The person who sends the questionnaire owns the template map and the cover note. Engineering owns the pipeline that refuses a stale attachment. When those are the same overloaded person, the pipeline still refuses the stale file. The refusal is the feature. A pack that always succeeds will eventually send the wrong quarter.

Contractor and vendor access review feeds one of the generators, for the question that asks how you review third parties who have access to you. That is your review of them. The questionnaire this article answers is their review of you, or a customer's review of you. The evidence objects overlap, and the direction of the question does not. We label the row so a pack for "we reviewed our vendors" is not attached to "how do you review your employees."

Rutagon's deliverable is the register, the template maps, the freshness check, the redaction profile, and the gap sheet. The GRC platform continues to hold the policies and the control statements. The questionnaire stops being a hunt through old mail for a screenshot that still looks plausible.

Frequently Asked Questions

Is a written answer enough for a questionnaire row?

A written answer is a statement, and it should have an author and a date. Where the question asks for a record of a control operating, the attachment is the generated artifact: the export, the configuration, the completion list. We hash that artifact and record when it was collected. The statement does not replace it.

What happens when the artifact is older than the window?

The row is left out of the current pack and listed on the gap sheet with the collection time and the maximum age. We do not relabel a stale file as current. Someone refreshes the generator or the pack goes out with an explicit gap.

How do different customer spreadsheets share evidence?

Our register is keyed by the control, and each customer template maps their question numbers onto those row ids. The generator runs once, and each pack attaches the same fresh object, redacted with that row's profile. Unmapped questions stay on the gap sheet until an owner maps them or writes a dated statement.

Should we send the full internal export?

Only if the prompt asked for it and the data is appropriate to leave the company. The default profile keeps the fields the question asked for and drops names and account identifiers the customer does not need. The unredacted object stays in the evidence bucket for the auditor.

How is this different from the auditor's request list?

The generators are shared. The template is not. A customer workbook and a PBC list both consume the access-review export, the log configuration, and the training file. The map from their numbering to our row ids is what we maintain per customer, so the two processes do not drift into two different folders.

Ask for an evidence diagnostic that maps your recurring questionnaire rows to live artifacts and shows which attachments are stale. Contact Rutagon at rutagon.com/contact, 907-841-8407, or contact@rutagon.com.