Skip to content

安全模型

安全是分层且可选的: 未配置任何内容时,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_TOKENopaque full-access bearer token,constant-time 比较
CORNUS_JWT_HS256_SECRETHS256 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:pushregistry: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_KEYSCORNUS_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 (builddeployexecpushpullgc) 。未设置即 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 显式提及 pull action ("*" wildcard 不计) 时,registry GET/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 时才启用 docker caretaker role,因为它授予 workload deploy-engine access。参见Docker endpoint

相关页面

Released under the Apache-2.0 License.