自托管 Happier 的 relay:SSO、mTLS 和你自己的数据库
Happier 采用 MIT 许可,而每台设备都要经过的那个 relay 是一个你可以自己运行的容器。本页列出随之而来的各项控制 —— 服务器强制执行什么、它存储什么,以及它在运行时交给你的客户端什么。
在看清单之前,先把形态弄清楚是值得的。会话运行在你的开发者自己的电脑上,用的是他们已经有的服务方 CLI。relay 在这些电脑和他们的手机、浏览器、桌面之间传递消息。它是唯一一个必须从外部可达的部件,也正是我们请你托管的那个部件。
下面的所有内容都是服务器配置:那个容器上的环境变量,由那个容器强制执行,路径中没有任何由 Happier 运营的服务。全新服务器的默认姿态是端到端加密存储加开放注册,前提假设是大多数人会把它放在 Tailscale 后面。如果你在读这一页,你几乎肯定想要的是这句话后半段的反面。
那个加密默认设置在底层意味着什么 —— 哪一把密钥在哪里生成、你的 relay 最后手里剩下什么、没有密钥它又能读到哪些列 —— 是 加密架构,写给开发者而不是写给你。谁问服务器能看到什么,就把那一页发给谁;本页只谈你能强制执行什么。
SSO:GitHub 组织、OIDC 群组和客户端证书
身份交给你已经在运行的那一套。Happier 的职责是在每一个请求上执行它,而不只是在注册那一刻,并且持续地问下去。
- 要求使用身份提供方,并在每个请求上重新校验
- 匿名注册默认是开着的,因为大多数自托管的人把 relay 放在 Tailscale 后面就完事了。把它关掉、改为要求身份提供方,资格校验就会在每一条需要认证的 HTTP 路由上、以及在实时握手时执行 —— 而不只是在大门口。来自已经不再符合条件的人的请求会被拒绝,而不是降级处理。
- GitHub 登录,限定在你的组织内
- 可以放行指定的登录名,或者要求用户属于一个或多个 GitHub 组织,匹配其中任意一个或全部。推荐的做法是通过 GitHub App 而不是用户自己的 OAuth 令牌来验证成员身份,这样开发者撤销授权后访问权限不会继续存在 —— 而且在他们撤销时也不会因此中断。
- OIDC 单点登录,每个提供方有各自的放行规则
- Okta、Entra ID、Auth0、Keycloak,任何带发现文档的都行。每个提供方有自己的放行规则:登录名白名单、允许的邮箱域名、用户必须属于其中任意一个的群组、必须全部属于的群组。如果你的 IdP 在令牌里省略了群组、转而返回一个溢出指针,Happier 会把该用户视为不符合条件,而不是视为没有群组。
- 来自你 MDM 的 mTLS 客户端证书
- 在你的反向代理上终结 mTLS,并把验证过的身份转发给 Happier。用证书的 SAN email 或 SAN UPN 来映射身份,这样一台轮换了证书的设备仍然是同一个人,再用签发者和邮箱域名白名单加以限制。除非你有意启用了自动开通,否则未知证书会被拒绝。
- 离职处理:按你设定的间隔重新校验成员身份
- 成员身份会按你设定的间隔重新校验 —— 默认每天一次,最短可到一分钟 —— 结果缓存在身份记录上。值得琢磨的设置是你的 IdP 无法访问时会发生什么:默认宽松,也可以设为严格,此时服务器会失败关闭,而不是让一次陈旧的资格校验顶替一次实时校验。
存储策略、留存期,以及由你托管的数据库
审计人员问完认证之后,紧接着会问到的那些控制项。
- 三种存储策略,默认是最严的那一种
- 仅端到端加密,拒绝明文写入,全新的服务器就是这样。可选,由账号或会话来决定。或者仅明文,面向在基础设施层管理加密、并希望有服务端索引的组织 —— 这是一个真实的取舍,直说:在这个设置下,服务器可以读取存储的内容。
- 由你设定的留存窗口,无需读取会话记录即可执行
- 默认关闭:什么都不设,服务器就永久保留会话。打开之后,会话的规则是有意保守的 —— 只有当一棵会话树在持久化的标志上处于非活动状态、在两个不同的时间戳上都早于截止时间、并且在内存中未被观察到处于活动状态时,它才会被删除,而且截止时间会在删除事务内部再次校验。它从不需要解密会话记录来做判断。
- 一次性为所有人关闭某些功能
- 语音、社交、缺陷报告上传、附件、内嵌终端、会话交接、已连接服务、配额计量 —— 每一项都是服务器上的一个环境变量,在运行时告知客户端。客户端按服务器所说的可用范围来适配,所以被关闭的能力在界面上是不存在的,而不是存在却失败。
- 限流,以及一个由你控制的诊断端点
- 一个全局限流器,加上按路由的限流,各有自己的时间窗和你选定的键策略 —— 按 IP,或者按用户并回退到 IP,当一百个开发者共用一个 VPN 出口地址时,你要的就是后者。服务器诊断快照在你启用之前是关闭的,启用之后也只有所有者能看。
- 一个 Docker 镜像,后面接 SQLite 或 Postgres
- 发布的 relay-server 镜像以非 root 用户运行,内嵌了 Web 界面,默认在单个挂载卷下使用 SQLite,并支持一份有文档说明的 Postgres 覆盖配置。MySQL 也能用,但需要从源码构建镜像 —— 预构建的镜像有意不带那个客户端。请固定一个不可变的标签;镜像不会自我更新。
如果你的组织有 Zero Data Retention 要求
如果你在读这一页,你可能已经从另一个方向撞上过这堵墙。Anthropic 自己的 Remote Control 文档说得很明确:有 Zero Data Retention 这类合规要求的组织无法启用它。在那种状态下,Claude Code 管理控制台里的开关是灰的,所以这不是 Owner 能另作决定的事。它在 Amazon Bedrock、Google Cloud 的 Agent Platform 和 Microsoft Foundry 上同样不可用,并且当流量被指向某个 LLM 网关而不是 api.anthropic.com 时会被禁用。
这些都不是批评。Remote Control 把会话记录留在 Anthropic 服务器上,好让它能在你的各台设备之间同步,而一个签了零留存合同的组织理所当然地排除了这一点。这只是对另一个问题的另一个答案;如果你的组织正处在那个位置,那么剩下的那种形态的答案,就是一个由你自己运行的 relay。
采购拿到的是:一份 MIT 许可和一个容器镜像
MIT。不是 source-available,不是把认证栈放在商业版本之后的 open-core,也不是 AGPL。本页上的一切都和客户端在同一个仓库里,用同一份许可,没有一样是以与我们签合同为前提的。如果你所在组织的政策是 copyleft 不得进门,那么这条政策在这里不会被卡住。
上面这些控制项没有一个是要花钱买的:没有可购买的企业版,也没有需要为其中任何一项去谈的席位数。取决于你的采购流程,这要么是本页最让人安心的部分,要么是最让人不安的部分。你得到的是源码、一份 MIT 许可和一个容器镜像。
立起一个测试 relay,看看它强制执行了什么
诚实的顺序是:在一台用完即弃的主机上把 relay 立起来,让一位开发者连上去,然后读 GET /v1/features,看清楚那台服务器究竟在向它的客户端公布什么。那个响应就是契约,也是确认你设定的策略确实会被客户端遵守的最快方式。
curl -fsSL https://happier.dev/install | bashDocker 部署指南讲了镜像、卷和 Postgres 覆盖配置。服务器认证参考讲了上面提到的每一个变量,包括面向要求 GitHub 或某个 OIDC 提供方的公开服务器的配置示例。

