本文定义 NSIO Next 的共享策略内核和 AccessGrant 编译语义。NSD 保存策略,生产执行器调用同一个 PolicyKernel;ns、Connector 与 NSGW 只执行目标投影;Client 只创作、预览和展示。任何仓库不得复制一套近似判定。
allow Grant;共享的是 PolicyKernel,不是一个万能编译器:
| 生产消费者 | 输入/输出形态 |
|---|---|
AccessCompiler | AccessGrant → 每目标最小数据面投影 |
CapabilityCompiler | CapabilityPolicy → 能力申请资格与审批约束 |
EdgePolicyEvaluator | EdgeAuthPolicy → 每次外部请求/会话判定 |
AdminAuthorizer | AdminRoleBinding → 在线控制面管理判定 |
四者共同使用 selector resolution、condition evaluation、normalized AST、输入快照、provenance、revision/digest 和稳定错误;各自保留独立 evaluator/compiler version 与动作矩阵。
管理员或个人用户看到的是一个 GrantSet:
数组只服务于一次批量创作。服务端把 subjects × resources 规范化为单主体、单资源规则,并保留共同 grant_set_id。不能在运行时做模糊 M×N 展开。
| kind | 匹配对象 | 用途 |
|---|---|---|
user | Account/Organization principal | 指定一个人所有符合 source 条件的 Membership |
group | 当前 Group revision 的成员 | 团队授权 |
machine_principal | Service Account/Workload Identity | 自动化、服务器和工作负载调用 |
tag | NSD 批准的 MachinePrincipal/Node tag | 服务器或运行主体集合 |
external_binding | 当前 revision 的 ShareBinding | 跨组织最小授权 |
self | 当前规则求值主体本人 | Personal 默认模板 |
self 是求值时展开到当前 User/MachinePrincipal 的宏,不是持久身份。Group、Tag 与 ShareBinding 展开由 NSD 完成并携带对应 revision。Device、NodeMembership、设备本地名称、邮箱字符串或客户端自报标签不能成为 authoring subject;NodeMembership 只作为编译后的运行时源身份。
Subject 回答“谁”,source condition 回答“从哪台设备和什么环境”:
| 条件 | 示例 | 权威 |
|---|---|---|
| Membership/Device | 公司笔记本、组织所有、受管状态 | NSD Device/Membership |
| Network | 仅从开发 Network | NSD |
| posture | managed、encrypted、supported OS | 映射后的 MDM/Posture provider |
| time | 工作时间、到期日 | NSD time authority |
| path/via | 必须经企业 Connector/Exit | signed runtime/gateway projection |
Posture 未知、过期或读取失败不满足要求。Personal 可使用 Device/Network/time 等核心条件;受管 posture 依赖企业治理能力。
| kind | 匹配资源 | 支持的 action |
|---|---|---|
node | Node/Membership | connect |
service | Service ID | invoke |
route | Subnet/Application Route | use_route |
exit_profile | Gateway/Profile or exit resource | use_exit |
Service tag 与 Node tag 是不同 namespace;一个 tag selector 必须声明资源 kind,不能因同名同时命中节点和服务。
PublicApplication 由 EdgeAuthPolicy 管理,Service/Route/Gateway 能力声明由 CapabilityPolicy + CapabilityActivation 管理,租户管理对象由 AdminRoleBinding 管理;它们不进入 AccessGrant Resource Selector。
connect约束可包含 ICMP、TCP/UDP、端口范围。未写协议表示该资源定义允许的全部 L3 协议,不表示管理员权限。
invoke约束作用于 Service 的公开协议/端口,不作用于 backend 原始地址。用户获得 HTTPS Service 不获得承载节点 443 端口的通用 Node 权限。
HTTP path/method/header 等 L7 约束只允许用于 http 或 https_terminated,且由受信任 Service proxy/NSGW 终结并最终执行。tcp、原始 TUN 连接与 tls_passthrough 看不到 HTTP path;Compiler 必须以 constraint_not_enforceable 拒绝这种 Grant,不能生成“看起来已受保护”的投影。TLS passthrough 的 SNI 约束也只有在受信任 parser 能证明完整握手语义时才允许。
use_routeGrant 可以进一步收窄批准 Route 的 CIDR/domain,但请求范围必须逐项等于或被 advertised 范围包含;Default Route 是否可承载 CIDR 请求按明确协议规则处理,Client 不重写。
use_exit绑定具体 Gateway/Profile 或可选资源集合。Grant 只决定候选资格,selection 与运行时健康是独立状态。
未知 constraint 在当前 major 下拒绝发布,不静默忽略安全条件。
每类资源声明 enforcement_capabilities,Compiler 在发布事务中逐项验证 constraint 可由最终执行点观察并强制。安全条件不能只在源端 Client 检查。
| 条件 | Node | Service TCP/UDP | Service trusted L7 | Route | Exit | Edge |
|---|---|---|---|---|---|---|
| protocol/port | 双端 | publisher 最终执行 | proxy 最终执行 | Connector 最终执行 | NSGW scope 执行 | listener 执行 |
| HTTP host/path/method | 不支持 | 不支持 | 支持 | 不支持 | 不支持 | 支持 |
| Device/Posture | credential + 目标端 | credential + publisher | credential + proxy | credential + Connector | selection lease + NSGW | 仅有可信 device signal 时支持 |
| time/expiry | 短租约 + 目标端 | 短 flow credential | session/request | Route credential | Exit lease | request/session |
| exact CIDR/domain | CIDR 仅 L3 | Service ID | Service/host | Connector 投影;DomainRoute best-effort | profile scope | application host/path |
若目标执行器版本不支持某条件,版本协商只能拒绝或不提供该能力,不能删除条件后降级执行。
发布后 Group/Device/Posture 变化会产生新的 effective input revision 和 projection,但不篡改 GrantSet 历史。
一次编译固定读取:
输入引用不存在、revision 不一致或数据库读取失败时整次编译失败。Compiler 不混用“规则是 revision 8、Group 是更新一半的 revision 9”这种非一致视图。
对每个候选 (principal, source_membership, resource, action):
多条命中是同一 Network 内 allow union:任一完整规则允许即可。Union 只表示本机同时可达多个被允许资源,不允许把 Network A 的授权用于 Network B,也不允许节点转发形成跨 Network bridge。
源 Membership 获得可能访问的 peer/netmap 和 egress rule;目标 Membership 获得允许来源的 ingress rule。两端用相同 compiled rule/provenance。
消费者只获得被授权 Service 目录、VIP、健康 endpoint token 和 egress rule;publisher/NSGW 只获得该 Service 的允许消费者范围或短 flow token 校验材料,不获得完整用户目录。
只有批准且 Grant 命中的 Route 进入客户端 projection;无授权 Route 不进入 route table 候选。每条 Route 必须生成双端投影:
RouteAccessCredential;RouteAccessCredential 是自证签名令牌,至少绑定 issuer、Organization/Network、source membership、route ID、connector audience、generation、route_projection_digest、grant rule、input revision、kernel version、issued/expires 和 credential ID。Connector 在本地验证签名、来源、audience、generation/digest 以及本次实际目的地,不在建流路径查询 NSD。两端缺任一投影或 digest 不匹配即 fail-closed。
DomainRoute 是按受控 origin DNS 解析结果安装 IP 路由的 best-effort L3 能力,可能覆盖共享 CDN/多租户 IP;控制台必须展示当前 IP、TTL 与冲突。需要精确 Host/SNI/path 语义时使用 DomainService/Egress Proxy,不能把 DomainRoute 宣称为严格应用授权。
Connector 同时维护 current、next 和可选 previous generation,每代保留独立 digest、input revision、精确目的地、协议/端口、not_before/not_after 与 provenance,禁止把两代目的地集合合并。Compiler 对变化做语义分类:
| 变化 | 行为 |
|---|---|
| additive | 在有界窗口重叠,旧凭据只命中旧集合,新凭据只命中新集合 |
| restrictive | 按 Network 的撤销策略切换 |
| metadata-only | 不创建数据面 generation |
| mixed | 先执行 restrictive,再执行 additive |
Network 默认 security_first:先把新投影 staging 到 Connector 并收 ACK,再给 Client 下发带 activation epoch/not_before 的凭据;到点拒绝旧 generation,未 ACK 的 Connector 移出候选,允许短暂 fail-closed。可选 bounded_drain 允许旧 generation 不超过 credential TTL,控制台必须显示旧权限最晚失效时间并写审计。NSD 只编排和签名,不进入流建立路径。
候选投影先过滤 use_exit/Service Grant,运行配置再绑定 selection、profile 和 scope。Relay path token 与租户 Grant 分开,不能把可 relay 误作可 Exit。
Gateway offline、Service endpoint unhealthy、Node offline 会影响 availability 和路径选择,不删除 Grant。恢复健康时无需重新授权。反过来,资源健康也不能让未授权主体获得目录或路径。
管理端分别显示:Policy allowed、Resource available、Projection applied。不能压成一个 Active。
Grant revoke 提交新 revision,Compiler 发布最小删除/新 snapshot,并使新 flow/session 立即拒绝。已建立连接按资源策略立即断开或短 drain;任何丢失事件的节点在 peer/flow lease 到期后强制失效。
默认企业身份撤销目标不超过 5 分钟,因此相关 peer/flow lease 不能长于 SLA。延迟超过 SLA 触发安全告警,不只记录普通 delivery lag。
撤销关键路径必须使用 subject/resource/selector reverse dependency index 生成定向 delta,不允许等待或退化成单 Network full compile。权威事务先提交 revocation_epoch/tombstone 并立即停止新 credential/lease 签发;在线目标收到定向删除投影后拒绝,漏投影目标由短租约硬上限收敛。Full compile 只在后台做一致性对账和修复,不能成为撤销生效的前置。依赖索引读取或 delta 生成失败时返回明确 security delivery error、保留 tombstone 并告警,不能撤回已提交的撤销或恢复旧签发。
跨组织 Service Share 的有效授权是 provider Grant、Share lease、consumer Binding/Grant 的交集。两边分别编译最小 opaque projection,不交换 Group、Device 或策略图。external_binding:<id> selector 展开与最终交集必须读取同一次编译快照中被 pin 的当前 Binding revision,不能一处用当前值、另一处用签发时旧快照。
首版 runtime 一次激活一个 Profile/主 Network。账号属于多个 Network 不意味着编译器把它们合成一个安全域;切换后重新获取对应 projection。
模拟 API 输入 draft + sample/current principal/resource。它必须以 dry-run 调用对应的生产 AccessCompiler、CapabilityCompiler、EdgePolicyEvaluator 或 AdminAuthorizer;控制台和模拟服务不得维护第二套简化求值器。返回:
模拟结果不是授权。确认提交必须重新计算并比对 digest。
Effective Access 同样读取生产编译结果与 provenance,不在控制台重新求值。每个判定至少记录:policy_schema_version、kernel_version、evaluator_kind、evaluator_version、compiler_build_id、input_revision、grant_set_id、grant_rule_id、projection_digest。
PolicyKernel 或 evaluator 升级即使策略文本未变,也可能改变判定。上线前必须在同一租户和数据驻留边界内对旧/新版本做 shadow evaluation,输出新增、移除和状态变化;高风险差异需确认或 canary。启用后创建新的 effective revision、重投影并写 policy_engine_upgrade 审计。不能把完整身份图跨区复制给集中式影子服务。
| code | 含义 | 用户动作 |
|---|---|---|
grant_subject_not_found | 主体引用无效 | 刷新并重选 |
grant_resource_not_found | 资源已删除/不可见 | 刷新并重选 |
grant_action_invalid | action 与资源类型不匹配 | 修改规则 |
grant_constraint_invalid | 协议/端口/CIDR 等非法 | 修正字段 |
grant_impact_changed | 确认后权威状态变化 | 重新预览 |
grant_approval_required | 需要审批/step-up | 完成审批 |
grant_compile_failed | 权威读取/编译故障 | 保留旧投影、管理员重试 |
grant_projection_outdated | 节点仍执行已被更新 revision 取代的旧投影 | 查看目标、旧/新 revision 和 request ID |
“没有命中 Grant”是正常 deny 事实,不作为系统错误;Client 可在被允许披露时显示 not authorized。
Clark 有 Mac 和 Windows 两个 Device,Bob 有 Laptop 和 Server:
subject=user:clark → resource=nodes:owned → connect:Clark 两台 Membership 可互访,不包含 Bob;subject=user:clark → resource=node:bob-server → connect tcp/22:Clark 符合 source 条件的设备可 SSH Bob Server,其他端口拒绝;subject=group:developers → service:git → invoke https:组员可打开 Git Service,但不能访问承载节点;subject=user:clark + source_condition(device=corp-mac, managed=true) → service:finance → invoke:只允许 Clark 从指定受管电脑访问,个人 Windows 不匹配;