安全模型
安全是分层且可选的: 未配置任何内容时,Cornus 是适用于本地开发的 pass-through。下列每一层均由配置启用,并且一旦启用即 fail closed——错误 policy 会导致 hard startup error,需要 identity 时拒绝空 identity,配置错误的 verifier 会拒绝而非放行。本页说明模型;安全与认证指南介绍设置和加固步骤。
认证
认证是环绕全部 HTTP surface 的 middleware seam,接在 telemetry handler 内,因此被拒绝的 request 仍会得到 trace。未配置 verifier 时它是 pass-through。启用后,/healthz 和 /readyz 保持开放;其他每条 route 都需要 bearer auth,只有设置 CORNUS_REGISTRY_ANONYMOUS_PULL 时 /v2/* 下的 GET/HEAD 例外。Verifier 配置由环境变量驱动:
| 变量 | 方法 |
|---|---|
CORNUS_AUTH_TOKEN | opaque full-access bearer token,constant-time 比较 |
CORNUS_JWT_HS256_SECRET | HS256 JWT |
CORNUS_JWT_PUBLIC_KEY | 来自 PEM public key 的 RS256/ES256 JWT |
CORNUS_JWT_JWKS_FILE / _URL | 使用 kid selection 和 rotation 的 JWKS (仅 asymmetric) |
CORNUS_JWT_ISSUER / _AUDIENCE | 可选 registered-claim check |
CORNUS_CARETAKER_TOKEN | 仅在 caretaker attach endpoint 接受的 scoped static token |
CORNUS_AUTH_KEYSTORE / CORNUS_AUTHORIZED_KEYS | 使用 SSH 公钥证明换取短期 scoped JWT |
JWT verification 将每个 key 绑定到允许的 algorithm set——拒绝 alg: none、algorithm confusion 与 public-key-as-HMAC——并将 caller identity 保存到 request context 供授权使用。客户端 token issuance (cornus token issue) 是 operator/CLI 操作,而不是通用 HTTP minting endpoint。此外,仅在启用客户端认证时存在安装范围的签名 key: Cornus 用它为自身 build/deploy 数据平面签发短期 registry:push 和 registry:pull credential。这些 credential 在 operator verifier 之前接受,在 request context 中标记为内部 credential,并且只对已知同机 registry host 签发。Kubernetes 将 12 小时的 pull credential 保存在没有 owner reference 的 namespace Secret cornus-registry-pull 中,由受监督 loop 每 4 小时刷新;host backend 则在每次 pull 时签发。Kubernetes caretaker sidecar 从 Kubernetes Secret 获取scoped credential (仅对 caretaker attach endpoint 有效) ,而非将 full-access token 带入每个 pod。
镜像仓库还支持 docker login: 仅在 /v2/* 上,以相同 credential 作为 password 接受 HTTP Basic——static token 或 JWT——并忽略 username (docker login -u token -p $CORNUS_TOKEN) ,输入同一 verifier chain。Registry 的 401 challenge 是 Basic realm="cornus" 而不是 Bearer: Cornus 没有 token service,Bearer challenge 会令 docker 前往不存在的 token realm;Basic 可使标准 docker/podman 用保存的 login 重试。非 registry route 仍 challenge Bearer,以 Basic 封装的 caretaker-scoped credential 在 registry 上仍会被拒绝。
SSH 公钥客户端身份验证为 opt-in。配置后,服务器会为注册与会话签发提供用途绑定的 SSH 签名 challenge,并拒绝 SHA-1 RSA 签名。注册会轮换模式为 0600 的一次性 secret,并且只保存公钥。会话 proof 返回以注册名称为身份的短期 scoped JWT。可写注册仅用于单副本;多副本部署使用声明式 CORNUS_AUTHORIZED_KEYS 与 CORNUS_AUTH_KEYSTORE=none。
TLS 和 mTLS identity
TLS serving 内置于 cornus serve,使用 --tls-cert/--tls-key,并通过 reload callback 在文件 modification time 前进时重新读取文件——外部 rotator (cert-manager、Vault、SPIFFE) 可原地续签挂载 certificate,无需 restart。
mTLS client-cert identity 是额外认证方法: 已验证 client certificate 是 full credential,其 CommonName 为 caller identity,并优先于 bearer token。hub 使用同一 authenticated identity,因此 hub reach/register policy 基于 spoke 无法伪造的 credential。
授权
按 identity 的 API authorization 位于认证之上,是 configure-to-enforce matrix: CORNUS_API_POLICY 将 identity 映射到允许 action (build、deploy、exec、push、pull、gc) 。未设置即 allow-all;一旦配置,caller 必须列在所请求 action 中,且空 identity 被拒绝——有效执行要求 JWT sub 或 mTLS CommonName。Pure read (deploy status、log、registry pull) 默认保持开放,由认证而不是 per-identity authorization 管理。另有两项细化:
- **
exec是独立 action。**如果 policy 允许exec或deploy,则允许 Exec/attach——deploy 蕴含 exec,因此该 action 的价值在于 exec-only identity 可 shell 进入运行中 workload,却不能 apply 或 delete。 - **Registry pull authorization 是 opt-in。**任何 rule 显式提及
pullaction ("*"wildcard 不计) 时,registryGET/HEAD要求它。显式 pull policy 优先于CORNUS_REGISTRY_ANONYMOUS_PULL——anonymous caller 没有 identity,会被拒绝——两者同时配置时 server 会在 startup warning。
Deploy backend 还独立执行workload privilege policy以实施 defense in depth: host backend 除非由 CORNUS_ALLOW_PRIVILEGED / CORNUS_ALLOW_BIND_SOURCES opt in,否则拒绝 Privileged 和 host bind source;Kubernetes backend 默认拒绝用户请求的 privileged workload,但允许 Cornus 自身注入、确实需要 privilege 进行 kernel 9P mount 或 network redirection 的 sidecar。
信任边界
以下边界在其子系统中已说明,集中如下:
- **Remote-build export 只读且受限。**Remote builder 仅经 9P 访问 context、dockerfile 和 named-context 目录——无
..、无 symlink escape、无 write,且字节离开调用方前执行.dockerignore。参见构建引擎。 - **Session id 是 capability。**Deploy-attach session id 不可猜测,位于已认证 stream 内而非 URL;mount relay 仅发布其 digest。
- **每一跳重新评估 egress policy。**Caretaker、server 和 client 都检查 routing policy,受损 pod 无法提升路由;无 session egress 仅对 operator-gated gateway route 有效。参见客户端侧 egress。
- **Hub policy 基于 verified identity。**mTLS 下 spoke identity 来自 client certificate,不来自其自身声明。参见hub。
- **Pod 内 Docker endpoint 需要显式 operator grant。**仅在配置专用 client-scoped token Secret 时才启用
dockercaretaker role,因为它授予 workload deploy-engine access。参见Docker endpoint。
相关页面
- 安全与认证——配置所有 verifier 和 TLS mode,以及加固步骤。
- cornus token——签发 JWT。
- 服务器环境变量——完整 policy surface。