Skip to content

Releases: OnyxAxisOwO/ObsidianArc

Release list

v0.10.0

Choose a tag to compare

@OnyxAxisOwO OnyxAxisOwO released this 10 Oct 10:21

次版本:新增功能和大量安全加固,部分行为有变化,升级前请读完下面的升级须知。插件契约 arcx.APILevel 仍是 4,已装的插件包照常工作。

升级须知

这一版有几处会改变已有部署的行为,升级前请逐条确认:

  • 部署在 Cloudflare 后面的,必须设 OBSIDIAN_TRUST_CLOUDFLARE=true。 CF-Connecting-IP 现在只有在运维方声明
    前面是 Cloudflare 时才采信(且仍需 OBSIDIAN_TRUST_PROXY 信任本地代理)。不设的话,所有访客都会被认成同一个
    Cloudflare 出口地址,登录、注册、PoW、试用等按地址的限流会互相拖累;日志里会出现一次警告。
    不在 Cloudflare 后面的不要设:任何客户端都能伪造这个头。
  • OIDC 登录现在校验 id_token 的 iss、aud 和 exp。 配置的签发方必须和提供方实际签发的完全一致,
    否则升级后用该提供方登录会失败。
  • 开启两步验证和修改邮箱要带当前密码(current_password),直接调用这些接口的脚本需要跟着改。
  • 按邮箱自动关联第三方登录只对被证明过的邮箱生效,按插件定义的绑定字段自动关联已取消;见下方安全加固一节。
  • 试用开着却没指定试用模型的,试用接口会返回 503,请在后台指定一个。
  • docker-compose.yml 不再有默认数据库密码。 没在 .env 里设 POSTGRES_PASSWORD 时 compose 会拒绝启动,
    不再悄悄用公开的 obsidian。已经在用默认密码的部署,先在 .env 写入原来的值(数据库里的密码不会因此改变),再升级。
  • OIDC 的签发方和各端点必须是 https(localhost、127.0.0.1、[::1] 上的 http 除外),发现文档里的端点也一样;
    这些请求不再跟随重定向。已保存的明文地址不会被改动,但用它登录会按「暂不可用」失败,请改成 https。
  • 开了注册人机验证时,第三方登录开新账户必须从注册页发起。 从登录页用第三方登录、而账户还不存在的,会被提示去注册页;
    已有账户的登录不受影响。插件的注册守卫现在也作用于第三方注册。
  • 改密码会换发当前会话的 Cookie(旧的立即失效,其他会话照旧全部退出)。网页终端里的 me passwd 拿不到新 Cookie,
    所以会连同浏览器在内的所有会话一起退出。
  • secret.key 存在但内容无效时拒绝启动,不再生成新密钥覆盖它(覆盖会让已加密保存的 SMTP、备份、两步验证等密钥全部读不出来)。
    报错会写明文件路径和处理办法。
  • 控制台参数解析改为出错即停:布尔开关写 off、no 之类,数字或时长写错,都会报错而不是当成真或 0;
    --trusted false、--yes false 按字面理解。依赖旧的宽松写法的脚本需要跟着改。
  • 没有密码的账户(第三方登录开设的)设置第一个密码,必须在 15 分钟内刚用第三方账户登录过,否则返回 reauth_required,
    设置页会提示先重新登录。
  • 改密码或管理员重置密码,会撤销该账户在本站身份提供方下发给第三方应用的令牌和未兑换的授权码(同意记录保留),
    这些应用需要用户重新登录一次。
  • 服务商的 Base URL(新建时填写的地址也算)、SMTP 的服务器、端口和用户名只有超级管理员能设定或修改。 有 providers 或
    security 授权的委派管理员仍能改其他字段;有 providers 授权的委派管理员只能复制已有的服务商,副本的 Base URL 必须与原服务商相同,
    密钥随之复制,不会返回到页面。
  • /v1 的 API Key 同样受两步验证策略和 OIDC 绑定策略约束:会话会被拦下的账户,它的密钥也会被拒绝(策略开启前签发的密钥不再绕过)。
  • 设了 OBSIDIAN_TRUST_CLOUDFLARE=true 时,Cloudflare 报告为明文 http 的页面访问会 308 跳到 https。 只读 CF-Visitor,
    不读 X-Forwarded-Proto(Flexible 模式回源一律是 http,据它跳转会无限循环)。
  • 插件的「清除数据」(卸载时一并删除数据)只有超级管理员能做,有 plugins_remove 授权的委派管理员只能保留数据卸载。
    安装编进二进制的插件时,随安装提交的每个设置项还要有该项自己的修改权限,安装面板只显示并提交当前管理员能改的项。
  • 改密码或管理员重置密码后,该账户已打开的 SSH 控制台会在下一条命令时结束,需要重新连接(在 SSH 里执行 me passwd 的那条连接也一样)。
    调整密码哈希参数后,账户下一次登录触发的自动重新哈希也会让它的 SSH 连接结束一次。
  • 未启用的额度窗口现在也照常计数,只是不做拒绝判断。之后再启用某个窗口,它从当前周期已有的用量算起,而不是从零开始。
  • 绑定第三方账户要先确认身份:有密码的账户输入当前密码,没有密码的账户须在 15 分钟内刚登录过。绑定改为由
    POST /api/auth/oauth/connections/{provider} 发起,GET /api/auth/oauth/start/{provider}?link=1 不再绑定账户;设置页和 OIDC 绑定页已跟着改,
    直接调用旧地址的脚本需要改。
  • 插件的登录守卫现在也作用于 SSH 控制台的密码登录和第三方注册的补全表单,以前只拦网页登录。
  • 注册或第三方补全时填错邀请码按地址计次(IPv6 按 /64):同一地址猜错超过 30 次后,约 30 分钟内带邀请码的注册都会被拒绝(429),
    被拒的请求不再做 AI 审查和邮箱检查。不带邀请码的注册不受影响。
  • 被两步验证或 OIDC 绑定策略拦下的账户,本站身份提供方不再为它续期令牌、兑换授权码或返回 userinfo,账户完成要求后恢复。
  • /v1 的请求体每个账户同时最多读 4 个,第 5 个排队等前面的读完,不报错;一个账户上传慢只拖慢它自己。
  • 迁移 0069–0073 在启动时自动执行,无需手动操作。0072 新建 oauth_states,让第三方登录的 state 只能用一次;0073 给赠金记录加上撤销标记。

变化

  • 封禁账号成为单独的操作。用户页的「账户状态」一栏可以填写封禁理由(不超过 500 字,对方登录时看到),「解除封禁」会清空理由;
    批量栏的「封禁」让选中的账户统一使用一个理由。原先的「状态」下拉框和列表里的「已禁用」标签去掉,账户统一叫「已封禁」。
    不能封禁自己的账户。控制台 user edit 和 user create 新增 --reason,需与 --status disabled 一起使用。

  • 安全加固(2026-10-10 复查)。会改变行为的部分:

    • 委派权限收窄:把应用设为受信任(跳过授权页)、修改应用的回调地址、改动已受信任的应用,mail.public_url(验证邮件链接的域名),
      都只有超级管理员能做;invites 权限的管理员不能认领自己创建的邀请码;概览页的「最新用户」只返回显示用的字段,不再带邮箱和注册 IP。
    • 备份:改备份目的地(S3 端点、存储桶、区域,或 WebDAV 地址)必须重新填写凭据,否则拒绝保存;账户导出改为流式写出,
      不再在 2000 个对话处静默截断;导入拒绝含 NUL 字符的文本,大小上限按实际字符数计算。
    • 出站:供应商连接拒绝链路本地地址和云元数据地址(169.254.0.0/16、fe80::/10、100.100.100.200、fd00:ec2::254),
      本机和局域网照常;插件 http.fetch 同样拒绝这两个元数据地址。供应商报错里出现的 API Key 会被替换成 ***。
    • /v1/messages 和 count_tokens:tool_result 里再嵌套 tool_result 或 tool_use 返回 400(以前会被静默丢掉,深层嵌套能耗尽内存)。
    • 插件:编进二进制的插件安装也要两步验证码(策略要求时);插件包的路由不再收到调用方的 Arc API Key(Authorization/X-Api-Key);
      赠金的 valid_days 上限 36500 天;db.query 的结果按字节封顶。
    • 会话:watch 每一轮都重新核对会话和权限,登出、降权、停用后下一轮就停;控制台发起的验证码尝试按调用者的真实地址限流,不再共用一个桶。
    • 其他:登录限流表有了容量上限(满了也不会挤掉正在计数的账户);单个账户最多占一个上传解码槽;请求日志写入前清理 NUL 与非法 UTF-8
      (PostgreSQL 上一条坏请求会让整批日志丢失);PostgreSQL 上并发结算同一笔赠金不再超支;SSH 控制台在文件句柄耗尽时重试而不是退出整个进程;
      退出登录会清空上一个账户的对话、草稿、暂存文件和项目列表;主题色名为 constructor 等继承属性时不再卡死启动;
      Markdown 的标题和未闭合反引号改为线性扫描,长空格行不再卡死标签页。
    • 部署:Makefile 和 scripts/deploy.sh 校验 git describe 得到的版本号格式后才用于 shell;deploy.sh 也校验远端报告的 CPU 架构。
    • 第三方登录:state 在服务端只能用一次(复制一份 Cookie 再用会被拒绝);补全表单不能改动提供方证明过的绑定字段;
      收窄应用的授权范围同样约束它已经持有的令牌(刷新、userinfo、兑换授权码都取交集)。
    • 委派权限:有「用户」授权的管理员不能改期或收回超级管理员的卡(仍可以给其加卡)。
    • 控制台:审计日志里,没有声明参数的命令(backup configure、me passwd)的位置参数一律遮盖,user passwd 第二个参数起
      和 watch 的全部参数按凭据处理;两条无法解析的帮助示例已改正,测试逐条解析所有示例。
    • 数据:标题和消息写入前去掉 NUL(PostgreSQL 上整条写入不再失败);导入的推理内容和存储同一上限,不再截到 32000 字;
      读取偏好设置失败时导出报错,不再生成缺项的文件;撤销赠金先锁行再读取额度;secret.key 先写临时文件再硬链接发布,
      首次启动中断不再留下空文件;请求日志的方法名有长度上限,批量写入失败时记下原因。
    • 网页:退出登录时还会清空模型选择与推理设置、管理员的模型定价缓存、待回复红点;退出前发出、退出后才返回的请求
      (清空全部对话、未读数、模型列表)不再改动下一个账户的界面;第三方登录、授权页和插件的错误码只查对象自有的键,
      站点主题卡片同样只认自有的强调色名称。
    • 后台:插件页的两个列表同时只开一条记录,不再并排两个面板把列表和标题挤成一个字宽。
    • 后台:从头像菜单打开设置、用量、API 密钥、关于等面板时留在后台,面板在后台旁边打开,关闭后回到原来的后台页面(地址里多一个 panel 参数,
      刷新和后退都按它走);从这里连接第三方账号,成功或失败都回到后台。以前会离开后台、跳回聊天主页。
    • 登录限流:限流表填满时不再拒绝新的名字(以前一波匿名请求就能让所有人无法用密码登录);匹配到账户的计数不会被回收,
      仍在封锁中的计数也不会。正确的二次验证码、正确的当前密码不再清空此前的错误次数。SSH 握手名额的 IPv6 地址按 /64 计。
    • 密码:登录时自动重新哈希只替换刚校验过的那份哈希,与改密码同时发生时不会把旧密码写回去;SSH 连接记下的是校验所用哈希的指纹。
      watch 每轮复核登录状态时不再顺延会话、也不记为活动。
    • 额度:预留、结算、退还、重置卡、管理员重置和过期清理都按同一顺序加锁,PostgreSQL 上不再互相死锁;重置后重试的请求只计一次每分钟次数。
    • 模型:管理员手动开关过的模型,健康检查不再自动把它重新打开。上游流里未闭合的工具调用块改为续扫,长块不再越来越慢。
    • 最终复查:撤销赠金后,在途的预扣退还或结算不再让它重新可花;改模型先锁行再读,不再把健康检查刚停用的状态写回去;
      部署脚本和 Makefile 在展开前检查插件名、包路径、版本号和 ARCH,带引号、$(shell …) 或换行的值不再被执行;
      附件与生图上传读到一半停住时会按时答复并断开,不再一直占着连接;清理任务修剪用量计数失败时写日志;一次 Esc 只关最上面的面板,后台抽屉里没保存的内容不再跟着丢;插件 db.query 的大小预估按 JSON 转义后的字节计。
    • 插件:db.query 的回复按 8 MiB 封顶,单个超大的单元格在编码前就拒绝;事务打开时宿主拒绝核验人机验证;arcpack 打包时拒绝符号链接
      和特殊文件。arcpack build 用本机 Go 工具链照常编译,只应用于可信的源码(见插件包文档)。
  • 后台会提示新版本:超级管理员打开后台时,服务器向 GitHub 查一次最新的 Release(结果缓存 12 小时,失败缓存 30 分钟,
    不开后台协程),有新版本就弹出面板显示版本号和发布说明,可以「跳过此版本」或「稍后」;概览页另有一行常驻提示。
    只通知,不自动下载。新设置 update.check(默认开),内网或不想对外请求的实例可以关掉;控制台 update status 看同样的结果。

  • 可信代理转发了 CF-Connecting-IP 而没有设 OBSIDIAN_TRUST_CLOUDFLARE 时,概览页也会给超级管理员挂一条警告,不再只在日志里提一次。

  • 移除工作模式(让 AI 在对话里替账号执行控制台命令的那一面)。首页不再有「对话 / 工作」切换,只剩对话;
    项目保留,在项目里开的就是普通对话。以前在工作模式里开的对话照常打开,按普通对话显示,文字都在;
    它们当时执行过的命令记录还留在数据库里(messages.tool_calls_json),但不再显示。
    设置项 chat.agent_max_rounds 删除,迁移 0071 清掉已存的值;旧的设置导出文件里带着它,导入时会跳过;直接保存会被当作未知键拒绝。
    对话接口的 mode 字段仍然接受,但不再起作用,新对话一律是普通对话。
    /v1 网关的工具调用(客户端自己的 agent 用的那套,包括文本模拟)不受影响。

  • 安全加固(2026-10-09 全量审计)。会改变行为的部分:

    • 计费:回答中途停止或断开时,按已经流出的文字估算用量(不再只记上游中途报的数,常常是 0);
      生成过程中删除对话也照样记账。
    • 第三方登录按邮箱关联已有账户,现在要求这个邮箱在本站被证明过(点过验证邮件、填过验证码,或已关联的提供方担保过),
      并且永远不关联进管理员账户。新列 users.email_proven_at,迁移 0070 自动执行;已有账户一律从「未证明」开始,
      下次用已关联的提供方登录时会自动补上。按插件定义的绑定字段自动关联已取消:账户上的值是注册时自己填的,证明不了什么;
      这类账户请先用密码登录,再在设置里连接提供方。内置身份提供方的 email_verified 也改为同一含义。
    • 只有超级管理员能上传、安装插件包(包的迁移以数据库所有者身份执行);plugins_manage 仍可启停已安装的插件。
    • OIDC 的签发方、各端点、client id/secret、oauth.oidc_trust_email 和 oauth.link_by_email 只有超级管理员能改。
    • 供应商改 Base URL(或复制密钥到不同地址的新供应商)必须重新填写 API Key;SMTP 改服务器、端口或用户名必须重新填写密码。
    • 有「用户」权限的委派管理员不能再读超级管理员的对话、列出或吊销其 API Key;管理员不能在后台重置自己的密码。
    • 设置导入遇到密钥掩码时保留原值,不再覆盖。
    • 开启两步验证和修改邮箱,设有密码的账户须输入当前密码(current_password;控制台 2fa enable / me edit 用
      --current-password);改密码和这两处的密码校验共用按账户的尝试次数。
    • 登录限流:成功登录只清空该账户的失败计数,不再清空 IP 的;按 IP 的额度为 30 次,按账户仍是 5 次。所有按地址的限流
      (登录、验证码、兑换码、PoW、试用)把 IPv6 按 /64 计。PoW 挑战和试用接口的内存表有上限并定期清理。
    • next 跳转拒绝任何位置的控制字符和反斜杠(堵住 /%09/evil.com)。
    • 账户导入/导出:每个账户同时只能一个,全站导出最多 2 个、导入最多 4 个并发;导入有存储文字上限。
    • 上游响应最多读 64 MiB,单个工具调用参数最多 8 MiB;附件上传和生图先占解码槽再读请求体。
    • 试用:没有指定试用模型时不再自动用第一个模型(返回 503)。
    • 注册验证码:所选模式不可用(例如提供它的插件被停用)时回落为 Turnstile 并真的要求验证,不再放行。
    • 站点 logo 以 sandbox; form-action 'none' 返回;反馈里员工回复不再暴露员工的用户 id;签到奖励在赠金条默认有效期已过时不发放。
    • 终端:用户提交的文本打印到终端前去掉控制字符;审计日志里位置参数中的密钥(setting set 密钥项、2FA 验证码、
      邀请码等)被遮盖;logo set / login-bg set 只接受 base64 或 data URL,不再读服务器上的文件;网页终端历史按账户保存、
      不记含密钥的行、退出登录时清空。
    • SSH:客户端断开即取消正在执行的命令;每个账户最多 4 个会话(MaxSessionsPerAccount),exec 最长 15 分钟,
      watch 默认最多 1 小时(--for);用户名超过 64 字节直接拒绝;握手阶段的连接全站最多 64 个、每个地址 8 个;
      受 OIDC 绑定策略约束的账户也不能用 SSH 绕过。
    • 插件包:路由响应一律带 Content-Security-Policy: sandbox; default-src 'none';describe 返回的来源只接受
      http(s)://主机[:端口] 和 blob:;迁移和清理脚本须以包名开头(旧的 NNNN_ 命名仍可用于低于核心最新编号的版本),
      与核心或其他包撞版本的安装会被拒绝,已存的冲突包在启动时跳过而不是让服务器起不来;插件字段不能用 users 表已有的列名;
      homepage 必须是 http(s);users.set_status / users.delete 只有在超管本人发起的调用里才能动管理员、谁也不能停用最后一个超管;
      后端同时最多 32 个调用(Limits.MaxConcurrent),满了路由返回 503、守卫拒绝。
  • 插件契约:arcx.APILevel 升到 4,多了 sweep 钩子(SDK 的 arc.OnSweep):服务器每 10 分钟的例行清理和启动时,
    依次调用每个启用了它的插件包,给它做定期工作的机会(复查外部状态、收回授予的东西)。没有声明的包不会被唤醒;
    每次调用仍是平常的期限,插件自己记节奏、分批做。

  • 插件契约:arcx.APILevel 升到 3,多了两个权限。

    • rewards:rewards.bonus 往账户的赠金条里发赠金(不填有效期就用赠金条自己的默认值),rewards.cards 发重置卡;
      都可以并入插件的事务,和「为什么发」一起成功或一起回滚。赠金页面会标出「插件:<名字>」。
    • challenge:challenge.describe / challenge.verify 借用站点自己的人机验证。用哪种由注册页的验证码设置决定
      (PoW、Turnstile 或两者);注册页不用核心自带的验证时,页面已加载 Turnstile 就用它,否则用 PoW。密钥不离开服务器。
    • 已装的旧包照常工作;声明了新权限的包在旧服务器上会被拒绝安装。
  • 插件的浏览器端:

    • userPanels 可以不带固定表单,改为 entries:一个由插件提供的列表,每一项在 /x/<slug>/<id> 打开自己的表单
      (通知可以直接链到某一项),提交前由核心画出并完成人机验证,再把证明交给插件;结果显示在表单的位置。
    • 用户表单多了 checks(多选,可限制最多几项);choice 可以 list(一行一个选项)和 required(必选时不预选第一项)。
    • 后台操作卡片和记录上的操作,控件多了 textarea、number、switch 和 rows(一行一行地编辑一张小表,值是 JSON),
      select 可以 load 服务器才知道的选项,每个控件可以 visible(按其他输入决定是否显示)。
    • 用户表单多了 list:一行一个短文本,可以添加、删除行(可限制最多几行),交给插件时去掉空行。
    • userPanels 可以写 menu: 'usage',入口在账户菜单里排到「用量」正下方,给升级、充值这类和额度有关的面板用。
    • 首屏传输体积 +2.33 kB。
  • 管理员可以完整设置站点外观(后台「设置 → 站点」):

    • 未登录背景(登录、注册、验证等页面)和新增的登录后背景,各分电脑/平板/手机 × 浅色/深色六种,每种可以是图片或一段 HTML。
      平板指两边都至少 600px 的触屏(tablet_light / tablet_dark);没设置的屏幕依次沿用最接近的形状,同明暗优先。
      HTML 背景在沙箱里以独立的源运行(Content-Security-Policy: sandbox allow-scripts),能画、能加载外部资源,碰不到本站和 Cookie,也不接收点击。
    • 「站点主题」卡片:默认配色模式、控件颜色、背景色调,以及登录后背景的暗化、模糊、面板透明度和面板模糊(theme.* 设置)。
      默认只是读者没选时的初始值;打开「强制使用此主题」后读者不能...
Read more