状态:商业基线。本文定义商品边界、Entitlement 数据模型和首版强制范围。价格与配额数字放在本文,架构文档只保留能力轴与执行原则。
首版不建设完整计费平台,但商品边界必须一次设计对:
判断标准只有一条:调整市场套餐时,NSD、NSGW 和 NS App 的协议与代码不需要跟着改。
本文件定义“卖什么”和运行时怎样获得能力。客户怎样报价、付款、开票、催缴与退款以采购、计费与发票为权威;SLA 的测量、抵扣和事故通报以服务运营规格为权威;认证、数据权利和 Legal Hold 以信任与合规为权威。
商业信息不进入运行时。三层各自独立演进:
| 层 | 谁读 | 内容 | 变更频率 |
|---|---|---|---|
| Subscription | 计费系统、管理后台、支持 | resource_pack_10 × 1、折扣、发票 | 随市场活动 |
| Effective Entitlement | NSD | managed_resources.limit = 35 | 订单变化时 |
| Capability Lease | NSGW | org X 可在 singapore 使用 managed_exit,有效至 T,容量 N | 分钟级续租 |
**NSD 不认识 resource_pack_10,NSGW 不认识套餐名和订单。**改套餐名、加组合包、调折扣,都只动 Subscription 层。
三层分离的代价是排查"这个组织为什么有 35 个受管资源"需要跨系统查询。Effective Entitlement 携带一个非权威的溯源引用来消除这个代价:
运行时组件不得对它做任何判断,它只用于支持工单和审计关联。
| 桶 | 含义 | 超限是否阻断合法操作 | 是否影响账单 |
|---|---|---|---|
features | 是否拥有某项功能 | 未拥有即不可用 | 是(决定套餐) |
quotas | 可购买、可计量、影响资源准入 | 是 | 是 |
limits | 非计费的反滥用与安全上限 | 仅在滥用时 | 否 |
service_levels | 托管服务质量与数据生命周期 | 否 | 否(随套餐变化但不按量计) |
新增键落哪个桶,按上表两列判定,不靠直觉。典型误判:审计保留期看起来像配额,但它不阻断任何操作、也不按量计费,属于 service_levels。
quotas 中的数字是已解析的有效总量(Team 25 + Resource Pack 10 = 35)。NSD 只读总量,不做加法,不知道加法的来源。
entitlement_revision 是 (subject, deployment_id) 作用域内由签发方分配的单调递增版本,是防回滚的权威字段。derived_from.revision 仍然只是订单溯源信息,不得用于版本判断。
| 值 | 行为 |
|---|---|
block | 达到上限拒绝新增或扩大;存量不动,已建立连接不受影响 |
warn | 允许操作,产生可观察告警事件与管理端提示 |
meter | 只计量,不告警不拦截 |
首版即完整实现三态,然后通过签发不同的 Effective Entitlement 来切换。临时节点从观察切到告警再切到强制,是换一份声明,不是发一个版本;也可以先在单个组织上试 warn。
这一节决定"签发疏漏会不会锁死客户",是整个模型最容易出事的地方。
| 情况 | 行为 |
|---|---|
| 必需 quota 缺失 | 整份 bundle 无效 → 使用最后有效版本 → 进入 grace → 报 entitlement_missing_required_quota |
| 可选 quota 缺失 | 视为该计量项不适用;不解释成无限 |
显式 limit: 0 | 确定表示不包含该能力 |
每个 schema_version 必须声明其 required quota 集合。启用某个 feature 时还必须校验它依赖的 quota 存在——例如 managed_edge 必须同时存在 edge_regions,否则 bundle 无效。
不采用"缺失一律取 0":那样一次签发疏漏就能锁死整个组织,风险不对称。
| 情况 | 行为 |
|---|---|
未知 feature | 忽略,不启用 |
未知非关键 limit / service_level | 忽略并记录 |
已知 major 中的未知 quota | 按定义是 optional,忽略并记录;requiredness 不由 bundle 自报 |
schema_version 高于本端支持 | 拒绝 bundle,使用最后有效版本 |
未知 enforcement 值 | 拒绝 bundle,绝不擅自转成 block |
| 已知 feature 缺少依赖 quota | bundle 无效 |
未知 enforcement 不降级为 block,因为那会让尚未实现该语义的 Next NSD 突然锁住客户——这与"读不懂 ≠ 拒绝服务"的全局原则冲突。正确路径是拒绝该 bundle、退回最后有效版本、进入 grace 并明确报 unsupported_entitlement_enforcement。
required quota 集合只由 schema major 定义,签发方不能在 bundle 内把新键标成 required。需要新的强制语义时必须提升 schema major;同 major 新增字段只能是 optional。
"使用最后有效版本"只有在它能跨进程重启存活时才成立。要求:
(subject, deployment_id) 已接受的最高 entitlement_revision 和声明摘要;grace_until 约束,且在管理端显示为"陈旧,最后验证于 T";否则在签发服务故障期间重启一次 NSD,就会掉进本节想避免的那个坑。
Entitlement 沿用控制面配置已有的版本回滚拒绝纪律:
entitlement_revision 低于本地最高已接受版本时,即使签名和有效期都合法也必须拒绝,并报 entitlement_revision_rollback;entitlement_revision_conflict;摘要不得基于会受 JSON 字段顺序或空白影响的原始传输字节;entitlement_id 与 entitlement_revision,避免旧 Entitlement 派生的新租约继续扩散;本地高水位能防止单独替换 entitlement 文件,不能独自证明整个 NSD 数据库没有一起回滚。托管云必须把最新接受 revision 的检查点写入独立的 Entitlement Service/审计存储,NSD 恢复后在签发新 Capability Lease 前完成比对。完全离线的企业自建若没有 TPM、外部时间戳或远端签名回执,就无法从密码学上检测整库快照回滚;产品必须把它列为部署边界,不能宣称绝对防回滚。
| 部署 | 来源 |
|---|---|
| 托管云 | 平台 Entitlement Service 签发 |
| Personal(托管) | 平台签发的默认 Personal 声明 |
| 社区自建 | 内置 Community entitlement,不依赖外部签发服务 |
| 企业自建 | 平台签发的离线 license bundle |
社区自建不需要联网验签,这既是产品承诺也是可用性要求。
| 商品 | 形态 |
|---|---|
| Personal | 免费。完整 L3/L4/Grant,限成员数、Network 数和受管节点数 |
| Team | $8/人/月(年付 $6)。商业使用授权、SSO/SCIM、更多资源与审计 |
| Enterprise | 询价。私有部署、合规、专属基础设施、SLA |
| Managed Edge | 独立附加包。托管 Ingress / Egress / Exit、固定 IP |
| Resource Pack | 受管节点超额时购买,10 个一包 |
首版不做 Business 档——Team 与 Enterprise 之间的细分等真实客户分布出来再切,切的时候只改 Subscription 层。
| Personal | Team | Enterprise | |
|---|---|---|---|
human_seats | 6 | 按占用计费 | 合同 |
| 用户设备 | 不限* | 不限* | 不限 |
managed_resources | 10 | 25,Resource Pack 扩展 | 合同 |
networks | 1 | 5 | 不限 |
ephemeral_minutes | 1,000 | 5,000 | 合同 |
edge_regions | 0 | 按购买 | 按购买 |
audit_retention_days | 7 | 30 | ≥365 / SIEM |
| L4 Service | 不限(services_per_network 软上限) | 不限 | 不限 |
| Node/Service Grant | 核心完整 | 完整 | 完整 |
| 自建 Route / Relay / Connector / Gateway | 是 | 是 | 是 |
| Community Relay | 公平使用 | 公平使用 | 公平使用 |
| SSO / SAML / SCIM | 否 | 是 | 是 |
| Posture / Flow Logs | 否 | 否 | 是 |
| 私有 NSD/NSGW、专属 PoP/IP | 社区自建 | 可选 | 完整支持 |
| 商业使用授权 | 否 | 是 | 是 |
* 受 limits.user_devices_per_seat 反滥用上限约束,超出触发提示而非账单。
Personal 的 managed_resources: 10 是转化线所在:足够任何家庭实验室,明显不够一家公司。对照 Tailscale 免费层的 50 个 tagged resource——但在 Tailscale 上发布 Service 需要 tag 身份、会消耗该额度,而 NSIO 的用户设备可以免费发布任意数量 Service。个人用户在真正重要的地方拿到的更多。
| 单位 | 定义 | 计量 |
|---|---|---|
| Human Seat Slot | User 首次登录管理端或其首台设备完成认证时占用 | 当前已占用槽位;同一计费周期内释放后可复用 |
| Managed Resource Slot | 当前被分类为受管资源的 Node Membership | 当前已占用槽位;分类解除或资源删除后释放 |
| Ephemeral Minutes | ephemeral=true 的 Membership 获得有效租约的累计时长 | 按租约有效区间累计(首版只计量) |
| Edge Unit | 已购买的(区域 × 容量)托管 NSGW | 订阅数 |
Human Seat Slot 的释放条件必须确定:User 从 Organization 删除、停用或由 IdP/SCIM deprovision 时释放;仅删除最后一台设备、退出登录或短期离线不释放。因此账单表示组织当前需要的可复用席位容量,不是本周期曾出现过的不同用户总数。
Quota 准入看事务提交时的当前占用数;订阅按购买的槽位容量计费,启用自动扩容时以事件精确计算本周期最高同时占用槽位数。已释放槽位可由另一个 User 或 Membership 在同一周期复用,不能把周期内出现过的不同身份简单累加,也不能用小时采样近似峰值。
Managed Resource Slot 的分类变化必须走同一个资源分类变化事务。下列动作都可能占用或释放槽位,任何 API、同步器或后台任务都不得绕开:
owner_type ∈ {service, tagged, organization, workload} 的 Membership;subnet_router / app_connector / exit_provider / relay_candidate 等基础设施能力;事务必须在同一数据库提交中完成:锁定当前分类与槽位占用 → 计算变化后总量 → 执行 quota enforcement → 写入权威资源状态 → 写入 outbox 计量事件。审批事件只是其中一种触发,不是唯一入口。用户设备免费仅限未被分类为受管资源的 endpoint + service_host。
CapabilityPolicy 只决定节点是否有资格申请能力,不能直接改变 Managed Resource Slot。每个具体能力必须经过统一 CapabilityActivation 事务;策略自动批准也只是该事务的 auto 分支,仍执行 quota allocation、metering、audit 和短租约签发。
CapabilityActivation 的商业语义与健康状态分离:
| 状态 | 是否执行 | 是否保留 Managed Resource Slot | 恢复方式 |
|---|---|---|---|
active | 是 | 是 | 续租 |
suspended | 否 | 是,继续计费 | 恢复 active,不重新抢额度 |
revoked | 否 | 否 | 重新申请与批准 |
unavailable | 由独立 Availability 轴表示 | 不改变 Activation 的占位 | 健康恢复即可,不重新授权 |
暂停必须记录结构化 reason(operator_paused、maintenance、commercial_grace、security_hold)并在管理端明确显示“仍占用额度”。系统不按固定 N 天自动撤销;管理员或策略可在暂停时显式设置 auto_revoke_at,执行前通知、计算影响并审计。策略失去资格不能伪装成 suspended,应走影响预览后的 revoke/管理员确认流程。
可设反滥用上限,但上限触发限速和提示,不触发账单。
| 项 | 桶 | 首版 enforcement |
|---|---|---|
human_seats | quota | block |
networks | quota | block |
managed_resources | quota | block |
edge_regions | quota | block |
ephemeral_minutes | quota | meter |
edge_traffic_bytes | quota | meter |
sso / scim / posture / flow_logs | feature | feature 判定 |
audit_retention_days | service_level | 按声明生效 |
community_relay_mbps | service_level | 按声明限速 |
每项限制只在一个地方强制:
| 限制 | 强制点 |
|---|---|
human_seats | NSD 席位占用变化事务;覆盖首次管理端登录、首台设备认证、删除、停用和 deprovision |
managed_resources | NSD 资源分类变化事务;覆盖创建、owner 变化、能力审批/撤销、临时转长期和删除 |
networks | NSD network 创建事务 |
edge_regions | NSD 签发给 NSGW 的 Capability Lease,不是 API 检查 |
| feature 类 | NSD API + 策略编译 |
UI 永远不是强制点。NSGW 不相信客户端自报的任何商业状态,只接受 NSD 基于有效 Entitlement 签发的短期 lease。
超内部阈值先提示、联系客户或人工调整。**不自动扣款,不突然断网。**真实数据足够后再决定是否推出分钟包和流量包——届时只需签发 enforcement: warn 或 block 的新声明。
| 事件 | 新增资源 | 已建数据面 | 控制面 | 数据 |
|---|---|---|---|---|
| 超配额(仍在付费) | 阻止 | 不受影响 | 完整 | 保留 |
| 主动降级 | 阻止 | 不受影响 | 完整 | 超配额项由客户选择冻结哪些 |
| 欠费(grace 内) | 阻止 | 不受影响 | 完整 | 保留 |
| 托管云欠费(超 grace) | 按当前有效免费 entitlement 阻止新增/扩大 | 已签发收费租约自然到期;Community 范围内的托管 L3/L4 继续 | 降至免费 entitlement,保留付款、导出、删除和影响处理入口 | 按免费档与导出窗口处理 |
| 社区自建商业状态异常 | 不影响 Community L3/L4 | 不受影响 | 完整 | 按本地策略 |
| 合同到期 | 阻止 | 托管 Edge 退出 | 只读 + 导出 | 导出窗口后按策略处理 |
| 安全撤销 | — | 立即,不受商业 grace 延迟 | 立即 | 按策略 |
三条不可动摇:
保留期不是"永不删除"——否则购买一个月 Team 就永久获得 30 天历史,不可执行。正确闭环:
配套两条机制要求:
Entitlement 异常在私有部署中的行为是硬性禁令:
理由不是道德而是运营:网络产品里的 license kill switch,第一次误触发就是客户整组织断网加事故报告;而且对客户掌控的二进制根本不可执行。私有部署收入来自合法授权、升级、支持、合规包和 SLA,不来自远程断网能力。
**NS App 不读取套餐名。**它只读取两件事:
不允许出现 if (plan == "team")。App 的发版周期最长,套餐逻辑一旦写进去,改套餐就要等全部用户升级客户端。
Billing 与管理后台可以显示套餐名和订单——它们属于 Subscription 层。
NSIO Next 不承接旧 NSIO 的订阅、资源用量、价格、账单、License 或 Entitlement:
首版交付的不是计费平台,而是一个边界正确的 Entitlement Resolver。
| 阶段 | 内容 | 为什么在这个位置 |
|---|---|---|
| 1 | Entitlement schema、签名、验签、持久化最后有效声明 | 所有强制点都依赖它 |
| 2 | Resolver:Subscription → Effective Entitlement | 有它才能签发 |
| 3 | NSD 事务层强制(席位、Network、资源分类变化) | 有声明才能强制 |
| 4 | Capability Lease 与 NSGW 校验 | 托管收入前提 |
| 5 | 计量流水(席位槽位、资源槽位、ephemeral 租约分钟、边缘流量) | 可与 3/4 并行 |
| 6 | 管理端用量展示 | 首版终点 |
| 7 | 自助计费门户、发票、超额通知 | 按采购计费规格独立交付,不进入 NSD 数据面事务 |
ledger_sequence 处理同一时刻的释放与占用,不能依赖不同主机的墙上时钟决定周期峰值;usage_reconciliation_findings 并告警,不能静默改写已出账单;Entitlement 跨 NSD、NSGW、管理后台三方,是典型的 schema 漂移高风险面。要求:
ns-shared-next,三方共用同一份定义,不各写一份再对齐;