NSD 是 NSIO Next 的租户权威控制面。它保存 Organization/Network 资源、验证身份与准入、编译最小授权投影、签名分发、记录审计并执行 Entitlement。NSD 永不进入业务数据路径,也不持有节点私钥。
全部能力的权威对象、审批事务和跨组件责任见产品能力目录与实现闭环;对象状态与 API 见控制资源生命周期,credential、建流与 generation 见数据面协议。本文件不得通过控制面实现便利改变其中的用户或失败语义。
NSD 负责:
NSD 不负责:
| 模块 | 权威数据 | 主要输出 |
|---|---|---|
identity | Account、ExternalIdentity、Credential | Session、assurance、login event |
directory | Organization、Member、Group、Role | principal selectors |
network | Network、Device、Membership、address lease | netmap inputs |
enrollment | Request、Approval、Grant、Key | committed Device/Membership |
policy_kernel | selectors、conditions、normalized AST | shared resolution、provenance、digest、stable errors |
access_compiler | AccessGrant + runtime resources | per-target Node/Service/Route/Exit projections |
capability | CapabilityPolicy/Activation | eligibility、approval、quota allocation、activation lease |
edge_policy | PublicApplication/EdgeAuthPolicy | versioned verifier/policy projection、simulation、revocation index |
admin_authz | AdminRoleBinding | scoped management decisions |
data_lifecycle | export/delete/retention/hold jobs | scoped tasks、tombstone、completion evidence |
continuity | backup checkpoint、restore epoch、水位 | verify/restore evidence |
service | Service、Endpoint、Manifest refs | directory/DNS projection |
route | Route、ApplicationRoute | route/DNS projection |
gateway | Gateway、Profile、Selection、Ingress | candidates/config/leases |
share | ShareOffer/Binding | bounded cross-org leases |
entitlement | signed snapshots/head/quota | admission and capability lease |
delivery | outbox、snapshot、ack watermarks | signed event streams |
credential_issuer | projection digest、runtime identity、lease policy | Relay/Service/Route/Exit/Ingress 短期凭据 |
audit | immutable events/retention/hold | console/export/webhook |
notification | durable intents | email/in-app/webhook delivery |
模块通过事务事件和明确接口协作,不共享“随便查表”的全局数据库句柄。编译器只读权威快照,写 projection/outbox,不在计算中修改资源。
首版支持:
首版不以“多 NSD 同时控制一台设备”作为核心能力。一个 active Profile 对应一个 NSD deployment;用户可以保存多个 Profile,但系统路由/DNS 不做跨权威 union。
SQLite 与 PostgreSQL 必须具有相同事务语义。SQLite 写入会串行排队,不能以随机 busy 错误暴露给用户;批量注册通过 Reservation 降低长事务。
所有租户写请求按固定顺序:
任何异常在步骤 7 前不得留下正式资源;步骤 7 后重试必须通过 idempotency key 返回同一结果。
Identity Authority 对外只暴露标准 OAuth/OIDC 会话。首版登录方式为邮箱密码、Google、GitHub 和企业 OIDC;社会登录不要求先填邮箱。Passkey 主登录后续增加,WebAuthn 首版用于 MFA/step-up。外部身份主键是 (issuer, subject),验证邮箱全局唯一但不用于静默合并账号。
首次个人登录事务:创建 Account → Personal Organization → default Network → owner membership → 安全默认 Grant template → audit。全部成功才提交。邀请第一位成员、开始试用或升级套餐都在同一 Organization 原地发生,不迁移资源 ID。
logout、登录方式解绑、SCIM deprovision 和 Device revoke 是四种不同事务。会话过期默认不撤销数据面 Membership;企业可显式启用更严格策略。
Enrollment 完整行为以专项文档为准。NSD 实现要点:
Device 表示组织内的设备身份与生命周期所有权;Node Membership 表示该 Device 加入一个 Network 后的数据面身份。一个 Device 可有多个 Network Membership,但每个 Membership 有独立 Node/WG Key、Node IP、Grant 和 lease。
地址分配事务需要:池级锁/原子 claim、唯一约束、释放隔离期和审计。Node FQDN 由 node-name.network-slug... 生成,重命名更新 DNS alias 但不改变 Node IP/ID。Service VIP 从独立池分配,不能与 Node IP 混用。
Device offline 不等于 revoke。Peer lease 过期使其移出活跃 projection;重新认证可恢复。Organization-owned Device 在员工离职时保留,撤该员工 Membership/assignment 后等待重新分配。
AccessGrant 编辑器收集五元组:subject、source/device condition、resource、action、constraint。CapabilityPolicy、EdgeAuthPolicy 和 AdminRoleBinding 使用各自的动作与资源 schema,但共享同一个 PolicyKernel 的 selector、condition、规范化、版本、provenance 和错误语义。NSD 保存 author intent 与 normalized form,并生成 immutable version。
发布前必须:
默认策略:Personal 初始模板允许本人设备基础互访;企业默认拒绝横向 L3,只开放明确 Service/管理流量。模板是可见、可修改的普通 AccessGrant version,不是隐藏后门。PublicApplication、能力申请和控制台管理权限不得塞入 AccessGrant。
选择器、规范化、命中和撤销语义以Grant 与策略编译实现规格为权威。本节只定义 NSD 模块边界。
AccessCompiler 输入为同一 revision 视图中的 principal、Group、Membership、Service/Endpoint、Route、Gateway、Share、health、posture 和 Entitlement。输出按目标 Membership/Connector/NSGW 最小化:
各执行器在固定 kernel/evaluator version 下纯函数化,同一输入 revision 产生同一 canonical output。读失败、引用缺失或未知安全语义时不发布新 revision,保留最后有效 projection 并产生对应 *_evaluation_failed。不能用 unwrap_or_default 把失败编译成空授权。
共享 selector/condition 只在 PolicyKernel 实现一次;AccessCompiler、CapabilityCompiler、EdgePolicyEvaluator 和 AdminAuthorizer 是独立生产消费者,不互相冒充。模拟和 Effective Access 必须 dry-run/读取这些生产实现,不能在控制台复制“看起来一样”的 allow 算法。
声明来源是 ns Local Manifest 或受管 publication request。NSD 先用 CapabilityPolicy 判断申请资格,再以逐实例 CapabilityActivation 完成批准、配额占用、审计和租约;自动批准也走同一事务。随后校验协议、backend 元数据、名称和本地同意,创建 Service/Endpoint 并分配 VIP/FQDN。
状态轴:declaration、approval、publisher health、projection、consumer authorization。online 只由健康 Endpoint 决定;无 ACL 不等于 offline,无 endpoint 不等于 unauthorized。
每个 Service 至少生成两类互补投影:consumer projection 含目录/VIP、可选 Endpoint、action 和 ServiceFlowCredential 获取/携带材料;publisher projection 含本 Service、Endpoint、本地 backend 约束、允许 consumer 范围、验签键、generation/digest/revision/expiry。publisher 不获得完整成员目录。两侧共享同一 grant_rule_id、generation 和 digest,任一侧缺失时 fail-closed;NSD 不进入 ServiceFlow 建流路径。
Service 修改使用 revision,协议/域名/网络等高影响字段先预览。删除 Service 会撤目录和租约,但不远程删除节点本地 manifest。Endpoint 离线只移出健康集合,不删除 Service。
成员 Portal API 必须复用 compiler 的 services_visible_to_principal 结果,站点/节点由可见 Service 推导,只返回成员自己的 Device,不返回完整 policy。
Route advertisement 进入 pending,管理员看到 publisher、CIDR/domain、冲突和预计受众。批准只创建可授权资源,用户仍需 Route Grant。
CIDR 冲突按 Network、route kind、prefix、priority 和 publisher health 计算;不静默随机选择。Domain Route 对 DNS answer 设置数量/TTL 上限并记录 origin resolver;禁止解析回 Service VIP。
Route lease 短期续租。publisher unhealthy、approval revoke、Grant revoke 或 lease expire 都重编译。NSD 不宣称终端已安装,只在 ack 后展示 applied 数量。
每条批准 Route 生成客户端投影和 Connector 投影。Connector 投影包含允许来源、精确目的地、协议/端口、NAT、generation/digest/revision/expiry;客户端获得绑定同一 digest 的签名 RouteAccessCredential。Connector 本地验签和校验实际目的地,建流时不得回查 NSD。
变更通过 current/next/previous generation 编排。Compiler 区分 additive、restrictive、metadata-only 和 mixed;Network 默认 security_first,可选 bounded_drain。NSD 负责 staging、ACK、activation epoch 和审计,不能把新旧目的地集合合并,也不能为消除切换窗口进入流路径。
Gateway 注册报告独立 capability:relay、managed_relay、egress、exit、ingress。每项有配置 schema、health、capacity 和 Entitlement lease;拥有 relay 不自动拥有其他 capability。
Gateway Exit candidate 按当前 principal、gateway、profile、scope 和可用性投影。集合状态明确区分 available、no_authorized_candidates、temporarily_unavailable 和 read_failed。gateway_name 是可选展示字段,缺失不影响旧一版 Next consumer;实际选择仍绑定 gateway ID + scope。
提交 selection 时授权失败硬拒不落库;已授权但暂时离线可以保存 suspended。已保存 selection 不自动切换到另一个 gateway,恢复授权/健康后可重新生效。
Egress 被建模为 Service backend,AccessGrant 决定谁可用。Ingress 由 PublicApplication + EdgeAuthPolicy + IngressBindingLease 绑定已存在 Service,不能填任意内网地址。证书、WAF、域名、区域和配额是 PublicApplication 自己的对象,不污染 Service 生命周期。
EdgeAuthPolicy 支持 OIDC、API Key、Service Credential、Signed URL、mTLS 和显式 Anonymous。访客形成 EdgeIdentity/ExternalPrincipal,但不创建 Network Membership;NSGW 使用最小 Gateway 身份与 Binding Lease 访问后端。内部 AccessGrant 和公网 EdgeAuthPolicy 分别求值、分别撤销,控制台必须交叉展示。
NSD 保存/规范化 policy、运行 dry-run 与签名投影,但不参与每个访客请求。NSGW 使用同版本 PolicyKernel/Edge evaluator 本地验证 method credential 和 request context;NSD 读取失败只阻止发布新 revision,不能让 NSGW 回查后临时放行。
Egress 作为 Service publisher 获得同一 publisher projection、ServiceFlowCredential 验签材料和本地 EgressOriginLease;该 lease 绑定实际 origin allowlist/DNS/TLS/generation,不发送给公网 origin。Ingress 获得 IngressBindingLease、IngressBackendCredential 和最小 publisher projection,不获得 Network peer map。NSD 为 NSGW 编译按 application、policy revision、binding lease、edge identity、credential 和 IdP session 可索引的撤销材料。安全撤销要求 NSGW 在 SLA 内终止长连接;策略读取失败返回 503,不伪装成 403。
Relay 调度只向 NSGW 暴露 RelayRouteLease 中的 opaque relay_route_id/relay_session_id、direction、流量上限、revision 和 expiry;稳定 Membership/Node/WG 身份只留在 NSD 与端点投影中。Exit 为终端和 NSGW 签发同一 selection/profile/scope/generation 的 ExitTunnelLease,两侧独立校验。credential 签发读取已提交且已编译的投影快照,不从未经批准对象临时拼装,也不把 NSD 放进每流路径。
验签通过的 bundle 事务化激活为 head 与 quota projection。防回滚 high-water mark、当前 revision 和 quota limit 使用同一权威字段。新 bundle 缺失旧 resource type 时保留 used/reserved,更新 revision 并标记 feature_not_entitled,不伪装成 limit=0。
注册热路径只做一次原子条件更新,零行后分类回读为 missing required quota、entitlement quota projection revision stale 或 limit reached。该事务 revision 不一致最多重试一次。批量部署先建 Reservation,再逐台消费,未消费差额到期归还。
计费/签发服务故障不得阻止 NSD 启动。最后有效 bundle 与签名持久化,grace 过期后的行为按 feature/managed capability 分别处理,不提供远程 kill switch。
每个目标 Membership 的 projections 用独立 stream/type/revision。权威对象提交写 transactional outbox;delivery worker canonical serialize、签名、存 snapshot/delta、发送并追踪 ack。
断线重连通过客户端水位选择 delta 或 snapshot。服务端保留窗口不足时发送新 snapshot。ack 不能反向修改权威资源,只更新交付状态和管理端可观测性。
背压策略:同类型未发送 delta 可合并为最新 snapshot;Enrollment/撤销/安全事件不能被普通状态更新覆盖。单个慢节点不能阻塞 Organization 编译或其他节点分发。
| API 域 | 主要资源 |
|---|---|
/auth | login、callback、token、MFA、identity binding |
/me | profile、Organizations、Networks、sessions |
/enrollment | requests、poll、grant、commit、cancel |
/orgs/{org} | members、groups、roles、billing status |
/networks/{net} | devices、memberships、nodes、services、access-grants、routes、capability-policies/activations |
/gateways | registrations、profiles、selections、public-applications、edge-auth-policies、binding-leases |
/roles | admin role definitions、bindings、impact preview |
/audit | query、export、legal hold |
/admin | deployment/tenant operations,独立强权限 |
/control | 四消息 Device Key/NSD Authority 认证、短期 runtime credential、target-minimal event stream、snapshot、ack |
列表 API 使用 cursor、稳定排序和作用域过滤。批量导出异步生成,下载 URL 短期签名。错误统一使用共享信封。
权威事务与审计同事务写入,外部通知通过 outbox。每个事件记录 actor、proof/assurance、action、resource、before/after revision、result、request ID 和 origin,不记录 secret。
通知是可重试副作用,不能决定权威提交是否成功。站内、邮件和 Webhook 使用同一 event ID 去重。高风险安全事件不可被用户普通通知偏好关闭。
Hosted/Self-hosted 备份和 restore epoch 以备份与灾难恢复为权威。恢复后必须重新应用撤销、deletion tombstone、最高 Entitlement revision 和新 projection epoch。状态页/SLA 所需 SLI 只输出服务事实,不泄露租户目录;事故与支持流程见服务运营规格。
所有 repository 方法要求显式 TenantContext。SQL 唯一键和外键包含 tenant/network scope。跨组织 Share 使用 opaque binding 和最小复制,不允许 join 两边完整目录。
管理员 API、租户 API、控制流和 Gateway API 使用不同 audience/credential。支持人员访问必须 just-in-time、带理由、审批和全审计,默认不可见业务资源。
NSD 功能完成必须同时有权威事务、最小 projection、Client 可解释状态、撤销 SLA 和审计证据。