跳转到内容

隐私与成对标识符

查看 Markdown

Sudomimus 的设计目标之一,是阻止不同应用在用户不知情的情况下跨产品关联同一个人,并将控制权交给用户而不是应用。本页介绍实现这一目标的身份模型。

用户认证时,应用永远不会拿到一个全局且稳定的账户 ID,而是拿到一个按用途隔离的标识,它只对该应用(或同一个开发者旗下的一组应用)有意义。三条原则始终成立:

  • 真实的账户标识永不离开系统。 每个账户都有内部主键,但它只用于系统内部的记录关联:不会写入令牌,也不会展示给应用或正在登录的用户。
  • 默认不存在跨应用关联。 两个互不相关的应用,对同一个人会拿到不同的标识。两个应用所有者即便互相比对,也无法看出他们各自的用户其实是同一个人。
  • 用户可以轮换自己的标识。 身份的连续性是一种用户可以主动撤销的选择。

扇区(Sector):隔离的基本单位

Section titled “扇区(Sector):隔离的基本单位”

每个应用都只属于一个扇区。扇区决定哪些应用可以共享同一用户标识:

  • 在同一个扇区内,一个用户只有一个标识,因此放进同一扇区的两个应用,对该用户会看到相同的标识。这是刻意为之——它让同一个开发者可以把一组相关产品(比如一个游戏启动器和它的配套应用)作为单一身份来运营。
  • 处于不同扇区的应用,对同一个用户看到的是互不相关的标识。无论怎样比对这些标识,都无法还原出背后是同一个人。

默认情况下,每个应用都会获得一个全新的独立扇区——最大化隔离。开发者如果确实希望自己的两个应用共享某用户身份,需要主动把它们放进同一个扇区;在主动开启之前,什么都不会被共享。扇区与你的应用一同存在于一个组织之内 —— 见组织与扇区

标识谁能看到可轮换用途
账户别名(account alias)用户本人,在账户门户中可见。应用永远看不到。用户可以通过其他渠道将它提供给允许列表的管理者。这样运营方可以允许某位特定用户,而应用始终不会得知该别名。
扇区主体(sector subject)应用;它就是令牌里的 sub 声明。应用用于标识用户的键,也是开发者在规则中进行允许列表匹配的值。它按 (用户, 扇区) 唯一。

两者都是不透明、人类可读的令牌——扇区主体形如 sub_9SQ5535CRWNDDM2T,账户别名形如 quiet-meadow-7h2k-9m4p-3fnp-falcon。应用应当把它们当作不透明字符串:不要解析、不要假设格式。正是这一点,让格式日后可以演进而不破坏任何接入方。

  • 轮换账户别名会改变用户对外提供、用于允许列表的句柄。应用既没见过旧值,也看不到新值;只有通过其他渠道维护的允许列表会受到影响。
  • 轮换扇区主体会改变应用对该用户看到的 sub。旧的主体不再可解析,于是应用看到的就像是一个全新的用户。这是用户的”忘掉我和这个产品之间的连续性”开关,可在账户门户中行使。

另一半:声明共享(claim sharing)

Section titled “另一半:声明共享(claim sharing)”

成对标识带来的隐私,最多只能强到应用仍然能拿到的那个最强的稳定声明为止。如果每个应用同时还被给到同一个真实邮箱,它完全可以改用邮箱来做关联——那个化名式的 sub 就形同虚设了。

因此,身份声明是一个独立的、由用户掌控的层。针对每个应用,用户自己决定其邮箱名(first name)姓(last name)是否会被签进该应用的令牌:

  • 开发者按声明逐项声明应用是否请求它:关闭(off)可选(optional)必需(required)
  • 可选项由用户在登录时最终拍板,并且可以随时在账户门户中撤销此前授予的某项声明。撤销在下一次签发的令牌上即刻生效——授权状态在每次签发时实时读取,绝不会从旧令牌里缓存的副本读取。
  • 从未被授予某声明的应用,根本不会收到它;该字段会从令牌中缺席。

这两层——成对标识,加上按应用粒度的声明控制——合在一起意味着:应用拿到的,恰好是用户选择给它的那一份身份信息,而没有任何可以用来在别处悄悄找到同一个用户的东西。

关于完整模型 —— 策略级别、同意界面,以及 OIDC scope 如何决定进入令牌的内容 —— 见身份声明与共享