以下情境为教学假设,人物与数字不代表经核实的真实案例。
安全问卷是 B2B 销售里最像考试的环节:客户发来一份几十页的表,问你的加密方式、访问控制、备份频率、事件响应、子处理者和数据删除。填完之后,客户可能签约,也可能没有下文。对一人公司,问卷最难受的地方不是不会填,而是不知道填一次要花多少时间、能换来多少收入。
LedgerLite 的企业客户会在签约前发安全问卷。问卷通常有三类证据:SOC 2 式自评、渗透测试报告、加密与访问控制证明。这一节把这三类证据拆成工时,算出首次准备和复用的成本,再对比多签 2 单的净得。它不提供问卷模板,也不判断某份问卷是否合理;工时、费率和成交数都是教学假设。
问卷到底在问什么
一份安全问卷看起来有几十个问题,落到证据上通常只有三类。客户不是想知道你「重视安全」,而是想知道三件事:控制是否存在、系统能不能被攻破、数据在传输和存储时是否加密、谁能访问。
| 证据 | 客户真正想确认的 | 常见形式 | 首次准备工时 |
|---|---|---|---|
| SOC 2 式自评 | 控制是否存在、是否持续运行 | 问卷、政策文档、截图 | 40 小时 |
| 渗透测试报告 | 系统能不能被攻破 | 第三方测试报告、整改记录 | 24 小时 |
| 加密与访问控制证明 | 数据是否加密、权限是否最小化 | 配置说明、IAM 清单、审计日志 | 16 小时 |
| 合计 | 80 小时 |
SOC 2 式自评不是正式认证,而是一套「把你的控制写成客户能读懂的语言」的工作。它占 40 小时,因为要整理政策、流程、角色和证据,不是填一张表。渗透测试报告占 24 小时,主要是选择测试范围、协调外部测试方、跟进整改和整理报告;外部测试费用另计,不在这 80 小时里。加密与访问控制证明占 16 小时,因为要把配置、权限和日志截成客户能核对的证据。
这三类证据的共同点是:它们不是为某一个客户准备的,而是可以复用的。第一次做的时候,你是在建立一套「安全事实库」;后面每来一个客户,只是从库里取材料、补差异。理解这一点,才能理解后面的成本曲线。
准备一次问卷的成本
首次准备按 80 小时、每小时 $150 计算,成本是 $12,000。这个数字对一人公司不小,但它不是每次都要重付。假设同一套答案复用一次只要 8 小时,那么一年 12 次问卷的总工时是 80 + 11 × 8 = 168 小时,成本 $25,200,平均每次 $2,100。
| 场景 | 首次工时 | 复用工时 | 年问卷数 | 总工时 | 年成本 | 单次平均 |
|---|---|---|---|---|---|---|
| 只做一次 | 80 | — | 1 | 80 | $12,000 | $12,000 |
| 一年 4 次 | 80 | 8 | 4 | 104 | $15,600 | $3,900 |
| 一年 12 次 | 80 | 8 | 12 | 168 | $25,200 | $2,100 |
这张表说明,问卷成本的关键变量不是「一次多少钱」,而是「一年几次」和「复用程度」。只做一次,$12,000 全部压在那一单上;做 12 次,单次平均降到 $2,100,但总成本升到 $25,200。复用不是免费的,它仍然要花 8 小时核对客户差异、更新截图、补充说明。
复用成本还会被三类差异推高。第一,客户所在行业不同,问题和证据要求不同;第二,客户规模不同,大型客户会要求更细的访问控制和事件响应材料;第三,产品变化会让旧答案过期,新增数据字段、换云服务、加子处理者,都要重新准备证据。8 小时是「同一套答案、少量差异」的假设;差异越大,复用成本越接近首次成本。
| 差异来源 | 具体变化 | 对复用工时的教学假设 | 是否要重做证据 |
|---|---|---|---|
| 行业 | 金融、医疗客户要求更多日志与保留证明 | +4 到 8 小时 | 部分重做 |
| 客户规模 | 大型客户要求渗透测试复测与整改证据 | +8 到 16 小时 | 重做 |
| 产品变化 | 新增数据字段、换云、加子处理者 | +4 到 12 小时 | 重做 |
| 问卷框架 | 客户使用不同框架,问题映射不同 | +2 到 6 小时 | 不重做,但要重写答案 |
这张表说明,8 小时复用是一个下限,不是平均值。同一套答案只对「同一行业、同一规模、产品没变、问卷框架接近」的客户成立;四个条件里有一个变化,复用工时就会上升。做年度预算时,用「首次 + 复用 × 次数」算出下限,再按差异表加上浮动,才接近真实投入。
因此,问卷成本应该按「首次 + 复用 × 次数」来预算,而不是按「一次 $12,000」来预算。前者能告诉你一年要投入多少,后者只能告诉你第一单有多贵。
多签 2 单的净得
问卷的价值要用「因为它多签了几单」来衡量。LedgerLite 的客户 LTV 是 $4,320(毛利口径,来自卷一),年付是 $924。假设问卷带来 2 单新增,按 LTV 算是 $8,640,按年付算是 $1,848。
| 口径 | 新增价值 | 问卷成本 | 净得 | 盈亏平衡单数 |
|---|---|---|---|---|
| 首轮,2 单 × 年付 | $1,848 | $12,000 | −$10,152 | 13 |
| 首轮,2 单 × LTV | $8,640 | $12,000 | −$3,360 | 3 |
| 复用,2 单 × 年付 | $1,848 | $1,200 | +$648 | 2 |
| 复用,2 单 × LTV | $8,640 | $1,200 | +$7,440 | 1 |
这张表最诚实的结论是:首轮问卷靠 2 个平均客户收不回来。按年付算,2 单只有 $1,848,连 $12,000 的零头都不够;按 LTV 算,2 单 $8,640,仍然净亏 $3,360,需要 3 单才回本。只有把问卷复用到第二次以后,单次成本降到 $1,200,2 单才开始净得 $648(年付口径)或 $7,440(LTV 口径)。
单客价值变化会直接改变结论。下面四档 LTV 是教学情景,不是客户分层数据:
| 单客 LTV | 2 单价值 | 首轮成本 | 首轮净得 | 盈亏平衡单数 |
|---|---|---|---|---|
| $2,000 | $4,000 | $12,000 | −$8,000 | 6 |
| $4,320 | $8,640 | $12,000 | −$3,360 | 3 |
| $8,000 | $16,000 | $12,000 | +$4,000 | 2 |
| $12,000 | $24,000 | $12,000 | +$12,000 | 1 |
这张表说明,同样 2 单,单客 LTV 从 $4,320 升到 $8,000,首轮净得就从 −$3,360 变成 +$4,000;升到 $12,000,一单就覆盖成本。问卷是否值得做,不取决于问卷本身,而取决于它服务的客户价值。
所以「多签 2 单」本身不是一个足够的理由。首轮问卷要成立,需要满足至少一个条件:新增单数超过 3 单;单客 LTV 明显高于平均;或者这套答案能复用到后续多个投标里。三个条件里,第三个最容易由一人公司控制,也最容易被忽略。
这也解释了为什么大客户和小客户不能用同一套问卷策略。对小客户,$12,000 的首次成本要摊到很低的 LTV 上,怎么算都不划算;对大客户,一次问卷可能打开多轮采购、多个部门、多年续约,复用次数和单客价值都更高。
分层策略:小客户不问卷,大客户必问卷
把客户按「年付」和「LTV」分层,问卷策略就不是「做或不做」,而是「做到什么程度」。
| 客户层 | 判断依据 | 建议 | 理由 |
|---|---|---|---|
| 小客户 | 年付 ≤ $924,LTV ≈ $4,320 | 不单独问卷 | 首轮 $12,000 需要 3 个 LTV 才回本 |
| 中型客户 | 年付 $924 到 $4,320 | 用标准自评 + 复用答案 | 单次边际成本 $1,200,1 单 LTV 可覆盖 |
| 大客户 | LTV > $12,000 或合同明确要求 | 必做,可接受定制问卷 | 1 单即可覆盖首轮成本 |
| 平台型客户 | 数据由平台掌握 | 只提供平台合规材料 | 责任边界在平台,不在开发者 |
这张表的门槛都来自前面的计算:$12,000 是首次成本,$4,320 是平均 LTV,$1,200 是复用成本。小客户不问卷,不是不重视安全,而是单位经济不成立;大客户必问卷,也不是因为大客户更挑剔,而是单客价值足以覆盖固定成本。
平台型客户是另一种情况。如果用户账号、支付和主要数据都在平台上,开发者能提供的证据有限,问卷的重点会从「你的安全体系」变成「你的构建和更新流程」。这时候不需要重建一套企业安全体系,只需要把平台已经提供的合规材料和自己的发布流程准备好。
Nord Studio 的客户以品牌官网为主,客户数据少,问卷通常停留在标准自评;它不需要为每个项目重做 80 小时。Tidecast 通过 Steam 发行,用户账号与支付数据由平台掌握,开发者能提供的证据更多是构建与更新流程,而不是一套完整的企业安全体系。
对 LedgerLite,分层还意味着不要把 260 家客户都当成企业客户。要求 DPA 和安全问卷的只是一部分;问卷成本要摊到那部分客户上,而不是摊到全部收入上。摊错对象,会得出「问卷很便宜」或「问卷贵得离谱」两个相反的错误结论。
代码:问卷成本与成交净得
下面的 security-review.ts 把这一节的口径固化成两个函数。reviewCost 用「首次工时 + 复用工时 ×(次数 − 1)」算年成本和单次平均;reviewNetGain 用「新增单数 × 单客价值 − 年成本」算净得,并给出盈亏平衡单数。金额用整数美分,工时可以是小数。
// file: src/contract/security-review.ts
// tier: L1
// verify: node --test test/contract/security-review.test.ts
import { type Cents } from "../core/money.ts";
import { type Result, fail, ok } from "../core/result.ts";
export type ReviewCostInput = {
firstReviewHours: number;
reuseHoursPerReview: number;
reviewsPerYear: number;
hourlyRateCents: Cents;
};
export type ReviewCost = {
totalHours: number;
firstReviewCostCents: Cents;
reuseCostCents: Cents;
annualCostCents: Cents;
averageCostCents: Cents;
};
export type ReviewDealInput = {
annualCostCents: Cents;
extraDeals: number;
valuePerDealCents: Cents;
};
export type ReviewNetGain = {
addedValueCents: Cents;
netGainCents: Cents;
breakEvenDeals: number;
};
function validHours(value: number): boolean {
return Number.isFinite(value) && value >= 0;
}
function validAmount(value: Cents): boolean {
return Number.isInteger(value) && value >= 0;
}
/**
* The first questionnaire is mostly a one-time documentation job; later ones
* reuse the same answers. Total hours therefore grow with the number of
* reviews, but not proportionally: firstReviewHours + reuse * (n - 1).
*/
export function reviewCost(input: ReviewCostInput): Result<ReviewCost> {
if (!validHours(input.firstReviewHours)) {
return fail("first review hours must be non-negative");
}
if (!validHours(input.reuseHoursPerReview)) {
return fail("reuse hours must be non-negative");
}
if (!Number.isInteger(input.reviewsPerYear) || input.reviewsPerYear < 1) {
return fail("reviews per year must be a positive integer");
}
if (!validAmount(input.hourlyRateCents)) {
return fail("hourly rate must be a non-negative integer amount");
}
const reuseCount = input.reviewsPerYear - 1;
const totalHours = input.firstReviewHours + input.reuseHoursPerReview * reuseCount;
const firstReviewCostCents = Math.round(
input.firstReviewHours * input.hourlyRateCents,
);
const reuseCostCents = Math.round(
input.reuseHoursPerReview * reuseCount * input.hourlyRateCents,
);
const annualCostCents = firstReviewCostCents + reuseCostCents;
return ok({
totalHours,
firstReviewCostCents,
reuseCostCents,
annualCostCents,
averageCostCents: Math.round(annualCostCents / input.reviewsPerYear),
});
}
/**
* A questionnaire is worth preparing only when the value of the extra deals
* it unlocks exceeds the cost. Break-even deals are rounded up: a fractional
* deal still costs one full questionnaire cycle.
*/
export function reviewNetGain(input: ReviewDealInput): Result<ReviewNetGain> {
if (!validAmount(input.annualCostCents)) {
return fail("annual cost must be a non-negative integer amount");
}
if (!Number.isInteger(input.extraDeals) || input.extraDeals < 0) {
return fail("extra deals must be a non-negative integer");
}
if (!validAmount(input.valuePerDealCents) || input.valuePerDealCents === 0) {
return fail("value per deal must be a positive integer amount");
}
const addedValueCents = input.extraDeals * input.valuePerDealCents;
return ok({
addedValueCents,
netGainCents: addedValueCents - input.annualCostCents,
breakEvenDeals: Math.ceil(input.annualCostCents / input.valuePerDealCents),
});
}
代码里有四个口径值得注意。第一,totalHours 不是「单次成本 × 次数」,而是首次加复用,所以次数越多,单次平均越低,但总成本仍然上升。第二,averageCostCents 用总成本除以次数并四舍五入,适合做报价参考,不适合做现金流预测。第三,breakEvenDeals 用 Math.ceil 向上取整,因为半个客户也要走一整轮问卷。第四,reviewNetGain 要求单客价值大于零;价值为零时无法算盈亏平衡,直接报错比返回无穷大更诚实。
代码不判断问卷是否真的能带来新增单,也不判断客户 LTV 是否稳定。它只把「准备成本」和「成交净得」变成一个可复算的数;新增单数和单客价值仍然是输入假设,换一组假设,结论就会变。
小结
- 安全问卷通常要三类证据:SOC 2 式自评 40 小时、渗透测试报告 24 小时、加密与访问控制证明 16 小时,合计 80 小时。
- 首次准备 80 小时 × $150 = $12,000;复用一次 8 小时 × $150 = $1,200。
- 一年 12 次问卷的总工时是 80 + 11 × 8 = 168 小时,成本 $25,200,单次平均 $2,100。
- 多签 2 单按 LTV 算是 $8,640,首轮净亏 $3,360,需要 3 单才回本;复用后净得 $7,440。
- 按年付算,2 单只有 $1,848,首轮净亏 $10,152,需要 13 单才回本;口径不同,结论差很远。
- 小客户不问卷,因为首轮 $12,000 摊到 $4,320 的 LTV 上不成立;大客户必问卷,因为 1 单就能覆盖首轮成本。
- 平台型客户的数据在平台,问卷重点应放在构建和更新流程,而不是重建企业安全体系。
阅读导航:上一节:11.2 数据泄露的责任与通知 · 下一节:12.1 风险登记册:概率、影响、责任人 。
常见错误与边界
- 把问卷当成一次性合规成本。 首次 80 小时之后,每次复用还要 8 小时;一年 12 次的总成本是 $25,200,不是 $12,000。
- 用单次成本乘次数。 正确算法是「首次 + 复用 ×(次数 − 1)」;直接乘会高估总成本,也会高估单次平均。
- 只用年付算成交价值。 年付 $924 和 LTV $4,320 差 4.7 倍;用错口径,盈亏平衡单数会从 3 单变成 13 单。
- 把「多签 2 单」当成充分理由。 首轮 2 单按 LTV 仍净亏 $3,360;要 3 单才回本,或者靠复用降低成本。
- 对所有客户用同一套问卷深度。 小客户不问卷、大客户必问卷;分层依据是 LTV 和复用次数,不是客户态度。
- 忽略外部渗透测试费用。 80 小时只是内部工时;第三方测试、复测和整改可能另有报价,要单独计入。
- 把 SOC 2 式自评当成正式认证。 自评是把自己的控制写成客户能读懂的语言,不等同于第三方审计报告;两者不能互相替代。
- 假设复用成本固定为 8 小时。 行业、客户规模、产品变化都会推高差异;差异越大,复用成本越接近首次成本。
- 把平台合规材料当成自己的安全体系。 平台型客户的数据在平台,开发者能证明的是构建和更新流程;不要承诺平台层面的控制。
- 把本节数字当成报价。 80 小时、8 小时、$150/小时和 2 单都是教学假设;真实成本要按自己的证据库、客户要求和外部报价重算。
问卷的成本在签约前发生,收益在签约后出现,所以它天然容易被低估:签单时没人会记得那 80 小时,续约时也没人会把它算进获客成本。把它当成一笔可以复用的固定投资,按客户层级分配,才能既不被问卷拖垮,也不因为答不上来丢掉本可以拿下的单。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。