跳到正文

安全

安全,如待客般周到。

一个身份提供商好不好,取决于租户之间的隔墙有多牢靠,以及它对待机密有多用心。以下是 Usher Identity 的构建方式。我们描述的是软件实际做了什么,并不声称获得了任何认证。

架构

分离的域名,分离的网络。

Usher Identity 自己的页面与每位客户的颁发者位于不同的可注册域名上。数据库所在的网络无法连通互联网,唯一的出口是一个会检查目的地的代理。

  • Caddy 为每个主机终止 TLS,并剥离只有 Usher Identity 自身服务才能设置的标头。
  • 身份验证层为每个环境提供服务,按主机加以区分;不会把为一个主机缓存的内容提供给另一个主机。
  • 每个服务都以自己的用户身份与 Valkey 通信,只能访问自己的键。不存在默认用户。
  • 带有令牌和验证码的语句,绝不会连同其值一起写入数据库日志。

互联网

用户、你的 App、你的服务器

边缘层

Caddy:TLS、HSTS,剥离内部标头

usheridentity.com

网站和 Console

usheridentity.com, console.usheridentity.com

API

api.usheridentity.com

*.usherid.com

身份验证层

每个环境的颁发者和 Lobby

数据网络 · 无对外路由

Postgres

每个环境一个架构

Valkey

每个服务只能访问自己的键

唯一的出口

出站代理

用于每个客户提供的 URL

发现、JWKS、注销

仅限公网地址

Usher Identity 的各个层级。租户域名与平台域名是不同的可注册域名,因此租户的页面与 Console 永远不会同站。

隔离

不共享任何要紧的东西。

每个项目环境都有自己的 Postgres 架构、自己的签名密钥,以及用自己的数据密钥密封的机密。它的颁发者是租户域名上的一个主机,Cookie 仅限该主机使用,因此浏览器永远不会把一个环境的 Cookie 发送给另一个环境。

usheridentity.com

网站、Usher Identity Console、Usher Identity 账户

*.usherid.com

每个环境一个颁发者,位于独立的域名上

环境

用户、会话和令牌保存在专为这个环境创建的架构中。查询都在该架构中运行,从不在带有租户列的共享表中运行。

将 Acme 生产环境中密封的 Google 客户端机密复制到 Northwind 生产环境。

静态加密

信封加密,与所在位置绑定。

你交给 Usher Identity 的机密,会在一个只属于某个环境的数据密钥下用 AES-256-GCM 密封。数据密钥本身又由保存在数据库之外、带版本的主密钥封装。

每个环境专属的数据密钥
即使一个环境的数据密钥遭到泄露,也不会暴露另一个环境的任何信息。
AAD 绑定
环境和用途被绑定进每一段密文,因此值无法在行与行或租户之间挪用。
带版本的密钥
每个密封的值都记录了生成它时所用的密钥版本,因此可以轮换密钥,并重新封装旧的值。
经过认证
借助 GCM 的认证标签,被篡改的值会无法打开,而不会被解密成别的内容。
  1. 主密钥

    保存在数据库之外,带版本

  2. 数据密钥,每个环境一个

    由主密钥封装

  3. 机密

    在数据密钥下用 AES-256-GCM 密封

u1.<key version>.<iv>.<ciphertext + tag>

aad = u1 | version | environment | purpose

密封的值会在认证数据中写明自己的环境和用途。复制到其他任何地方,都无法打开。

实践

每个细节,都认真对待。

  • 密码(如果你使用的话)

    使用 Argon2id 按 OWASP 推荐的强度(19 MiB、两轮)进行哈希处理,并限制同时运行的数量,避免大量登录请求拖垮服务。新密码会通过 Have I Been Pwned 的范围 API 与已知泄露数据比对,该 API 只能看到密码哈希值的一小段前缀。默认最小长度为 12 位。

  • 不存储任何可被重放的内容

    客户端机密、令牌、魔法链接令牌和电子邮件验证码均以哈希形式存储。备用码经过加密。授权码的有效期为五分钟;电子邮件验证码最多可尝试三次。

  • 每扇门都有速率限制

    登录、注册、电子邮件验证码、魔法链接、密码重设和第二重验证检查,各有各的限制:例如,每分钟最多十次密码登录,每十分钟最多五次电子邮件验证码。

  • 严格的 Content-Security-Policy

    每个 Lobby 页面都会获得一个全新的 nonce,以及围绕它构建的策略:只有本源中带有该 nonce 的脚本才会运行,表单只能提交到同源,其他网站也无法把页面嵌入框架。

  • 值得信赖的审计日志

    对工作区、项目和环境的更改都会写入一个仅追加的日志,每条记录都与前一条以哈希链相连,因此任何被修改或缺失的记录都会显露出来。

  • 用于客户 URL 的出站代理

    Usher Identity 向客户提供的地址发出的每个请求(OIDC 发现、JWKS、后端通道注销)都经由同一个代理离开。它只解析一次名称,拒绝私有地址、环回地址、链路本地地址和云元数据地址,并连接到它检查过的那个地址,因此 DNS 重绑定无法把客户 URL 变成内部地址。

  • 永不重复分配的标识名

    生产环境的标识名是其颁发者地址的第一个标签。Console 仅限受邀使用,被举报用于网络钓鱼的 Lobby 会被停用;而且标识名一经使用就永远不会再分配出去,因为旧的 App 可能仍然信任它签发的令牌。

  • 说结束就结束的会话

    Usher Identity 每次请求都会检查自己的会话,而不是信任缓存的副本,因此你结束的会话会立即失效。访问令牌的有效期很短(默认十分钟),你的 API 还可以对其进行内省。

负责任的漏洞披露

发现了问题?请先告诉我们。

如果你认为自己在 Usher Identity 中发现了安全问题,我们很希望听你说说,并会与你一起修复它。

security@usheridentity.com
  • 你发现了什么、在哪里发现的,以及如何复现。
  • 据你了解,有人可以利用它做什么。
  • 我们如何联系你,以及你是否希望被致谢。

请只在你自己拥有的环境中测试,不要访问他人的数据,并在公开之前给我们合理的修复时间。如需举报冒充 Usher Identity 登录页面的网页,请参阅举报滥用。