跳转到主要内容
lurno
安全与隐私

隔离由数据库强制执行,而不是由应用代码。

每一个会改动数据的请求都要经过三次授权,分布在三处、各自独立失效。它们背后是 868 条行级安全策略,因此处理函数里的一个疏漏只是一个缺陷,而不是一次数据泄露。这个页面是写给必须为我们签字的人看的。

简而言之

Lurno 如何让一个组织的数据不被另一个组织看到

Lurno 对每个会改动数据的请求做三次彼此独立的授权。界面在渲染某个控件之前先检查权限。服务端在触及数据之前断言同一项权限,答案为否即拒绝。数据库再应用一条行级安全策略,决定这次查询究竟能返回哪些行。三者必须全部通过。这样的策略共有 868 条,分布在 676 次迁移中,应用数据表位于 14 个领域 schema 中,而不是默认的 public schema,因此即便上层代码写错了,一个组织的数据行在另一个组织的会话中仍然不可达。管理性变更会写入只可追加的审计日志,日志行之间用 SHA-256 串成链,可以用一条查询来验证。Augmental Learning Inc. 对齐 ISO 27001 实践;它没有 ISO 27001 证书,也没有 SOC 2 报告,我们会在问卷里如实写明,而不是让买家自行假设。

三重授权
一种模型:同一个请求被三种彼此独立失效的机制授权三次。第一重是界面:它会隐藏当前登录者没有权限使用的控件。第二重是服务端:处理函数在触及数据之前断言权限,答案为否即抛出错误。第三重是数据库:表上的行级安全策略限制查询能返回哪些行。第一重是便利,第二重是主要边界,第三重是在第二重被绕过时仍然守得住的那一层。
架构

三道关卡,以及每一道背后是什么

逐道来看

一个请求,授权三次

界面里的控件在渲染前先问当前登录者是否持有某项权限。服务端的处理函数在做任何事之前断言同一项权限。随后数据库应用一条策略,决定这次查询能看到哪些行。三种机制,三处必须各自正确,其中任何一处说不,请求就结束。

  • 界面检查是便利,不是边界。它隐藏一个按钮,并不保护一张表。
  • 每次检查都经由同一套权限目录和同一个函数解析。没有哪个处理函数会读取角色名,然后自行决定那个角色意味着什么。
  • 在组织树某个分支上授予的角色沿该分支向下级联——而数据库策略读取的是与界面相同的那棵树,因此两者不可能各说各话。
组织与角色如何组织
在数据库里

676 次迁移中的 868 条策略

隔离是 schema,不是约定。表在创建时就启用行级安全,并配上把判断委托给服务端所调用的同一个权限函数的策略,另有一项迁移检查,会找出被授予访问权却没有对应策略的表。这个数字不是营销数据——它就是你去问数据库“你正在执行多少条策略”时返回的结果。

  • 策略不内联自己的逻辑。它们调用权限函数,因此答案不会和服务端上一刻的判断产生偏差。
  • 写策略除读取条件外还带有检查条件,因此插入操作无法把一行数据放进写入者没有权限的组织。
  • 凡是视图暴露个人数据的地方,都逐列授予访问权。表级授权会悄悄抵消列级保护,所以我们不用它。
Schema

十四个领域 schema,从不用 public

应用数据表位于十四个具名 schema 中——身份与访问一个、组织一个、媒体一个,依此类推。真正要紧的东西都不在默认的 public schema 里,而那正是一次误授权或一个宽松默认值最容易造成暴露的地方。私有媒体对已登录的浏览器根本没有存储策略:每一次读取都由先检查了归属行的服务端签发,每一次上传也以同样方式签发。

  • 一次性令牌——邀请、密码重置、账号找回——以加盐哈希存储。原始令牌只在邮件里出现一次,此后不再出现。
  • 只有品牌资产是公开的。组织的标志和站点图标必须在任何人登录之前就能显示;头像和课时媒体不需要,因此保持签名访问。
问责

事后证明发生过什么

没人能核查的审计日志,只是包装更好的日志文件。这一份是只可追加、可发现篡改的,而核查它就是一条查询。

只可追加的日志

管理性变更以事件形式写入,带有操作者、动作、资源、组织,以及变更前后的数据。没有任何操作会更新审计行。写入路径只做追加。

SHA-256 哈希链

每个事件都存储前一个事件的哈希和自身的哈希,两者都由数据库触发器赋值,而不是由记录该事件的代码赋值。改动其中一行,之后的每个哈希都会对不上。

可以当场看着跑的验证

一个验证函数会沿着链走一遍,指出第一处断裂所在的行。评审时我们会当着你的面运行它。

访问权限复核

谁在哪个组织里持有哪个角色,按计划定期复核,而不是等到审计时才看。一次移除和其他操作一样,也是一条审计事件。

破坏性操作需要两个人

匿名化或删除一个人先是一次申请,然后是一次单独的批准。申请人不能批准自己的申请,任何人都不能把自己作为对象。

你可以结束的会话

已登录的人可以撤销自己的其他会话,被撤销的会话会在下一次权限检查时被拦住,而不是等到令牌自然过期。

隐私

从同意到删除,每一步都有时钟

每个租户是其学习者数据的控制者,Lurno 是处理者。下面这套机制让这种划分成为事实,而不只是合同上的措辞。

  1. 01

    带版本的同意

    一个人同意的每份政策都带有版本号。政策一变,旧的同意即失效:会再次征询本人,并记录他同意了什么、在什么时候。AI 处理是单独的一项同意——撤回它,就不会有任何内容发往任何服务商。

  2. 02

    以向导形式完成的数据主体访问请求

    管理员按流程走完请求,而不是临场发挥:确认主体身份、收集平台上持有的全部数据、生成导出文件。可携带意味着机器可读——JSON 和 CSV,而不是一份截图的 PDF。

  3. 03

    有终止日期的留存

    个人数据按类别设有留存期,而不是默认永久保存。停用账号、过期邀请和陈旧会话,都有一个此后即不再存在的日期。

  4. 04

    需两人授权的删除

    一名管理员发起,另一名批准,之后才会执行。发起人永远不能批准,两人也都不能把自己作为对象。删除会触及引用该人的那些表,而不只是资料行。

  5. 05

    带 72 小时时钟的事件登记

    一起事件就是一行记录,带有从发现时刻起算 72 小时的截止时间,以及在关闭之前会持续触发的提醒。时钟从发现开始走,而不是从有人想起第 33 条的那一刻。

数据驻留

数据实际存放在哪里

文件

可以指向别处的媒体存储

文件通过一个存储接口写入,该接口有四种实现:Supabase Storage、Amazon S3、Azure Blob Storage 和 Google Cloud Storage。对于数据驻留要求,这通常就是诚实的答案——一次部署可以把文件写进你被要求使用的那个地区的存储桶,而不必等供应商去开一个地区。请尽早告诉我们你的要求,我们会明确说明今天能否满足。

  • 数据库、认证以及 API 所运行的函数由 Supabase 托管。那是你无法通过配置绕开的唯一依赖,它在 DPA 中被具名列出。
  • 各组织的自定义域名通过 Cloudflare 提供服务,证书自动签发,因此贝鲁特或米兰的学习者看到的是你的域名,而不是我们的。
自定义域名与白标
分析

产品分析在欧盟,且不包含学习者

平台分析通过 PostHog 的欧盟区域运行,外面包了一层抽象,因此更换供应商不必改动产品。会话回放经过遮罩处理,并且从不记录学习者——学习者界面根本没有接入回放。

  • 文本输入以及任何被标记为个人数据的内容,都会在浏览器中、在回放发往任何地方之前先被遮罩。
  • 分析受同意管控,除非组织主动开启,否则处于关闭状态。在任何界面上,都不会对未成年人做画像。
AI 安全

文本在抵达 AI 服务商之前会经历什么

学习者的一条消息、一份上传的 PDF、在助手里敲下的一个问题:这些都是内容,没有一样是指令。这个区分是被强制执行的,而不是在提示词里请求的。

注入分类

不受信任的输入会在真正的调用发生之前先被分类。试图引导模型转向的文本会被标记,而不是被执行。

随机化围栏

不受信任的文本被包在一个它猜不到的、每次请求都不同的标签里,而该标签会从内容本身中剥除。截断时会重新闭合围栏,而不是让它敞着。

调用前脱敏

姓名、邮箱和标识符在任何内容发往服务商之前就被替换。批改是在匿名化后的作答上进行的;回到学习者本人的对照关系留在我们的服务器上。

输出结构校验

每一个响应都要按 schema 校验。格式不合规的回复只有一次修复机会,随后即失败,而不会流入课程。

从提议到变更的完整轨迹

请求、被采纳的草稿和被拒绝的草稿,是同一份哈希链日志中的不同条目。模型提议了什么,就摆在有人实际采用了什么的旁边。

身份

用户如何登录

按安全评审人员需要的方式写:今天有什么,以及没有什么。

账号通过邀请创建

账号由管理员创建或通过邀请创建——没有自助注册。重置和找回链接是一次性的,并以哈希形式存储。

合作方登录(静默 SSO)

已经完成认证的合作方系统,可以用一份签名断言把用户移交过来,学习者不会看到第二次登录。它按组织配置,使用密钥,并且可撤销。

SAML 和 OIDC 单点登录

规划中

尚未开发。如果你的上线依赖 Entra ID 或 Okta,请在第一次通话时说明,我们会告诉你它的进展,而不是暗示它已经有了。

MFA 与通行密钥

规划中

同样在路线图上。今天由身份提供方处理密码,会话可由本人撤销,撤销会在下一次权限检查时生效。

次级处理者

所有会接触你数据的一方

共五家,每一家都在数据处理协议中具名列出,而不是事后才被发现。

Capability它负责什么适用范围
Supabase数据库、认证、文件存储,以及 API 所运行的函数主要处理者。媒体存储可以改指向 S3、Azure 或 GCS。
CloudflareDNS、TLS,以及各组织所使用的自定义域名为各组织域名终结 TLS;证书自动签发。
OpenAIAI 生成、辅导和初评草稿仅在请求需要时调用,且在脱敏之后。也可以改配置为 Anthropic 或 Google,组织还可以接入自己的密钥。
Resend事务性邮件——邀请、通知、重置组织可以用自己的子域名和自己的密钥发送。
PostHog产品分析和经过遮罩的会话回放欧盟区域。学习者界面不被录制。

具有约束力的清单是数据处理协议中的那一份,另有面向学校的 FERPA 学生数据隐私附录。我们会在通话之前把两份都发给你,而不是通话之后。

无障碍

WCAG 2.1 AA,以及我们没有的东西

Lurno 按 WCAG 2.1 AA 构建。自动化 axe 检查在持续集成中运行,因此一次对比度不达标或一个缺失的标签会让构建失败,而不会进入发布版本。键盘操作路径、可见焦点和减少动效偏好都在组件库里实现,而不是逐个页面事后补上。产品提供英语、法语、阿拉伯语和意大利语,阿拉伯语全程从右至左,而不是把从左至右的布局翻译一遍。

我们没有的是 VPAT 和第三方无障碍审计,我们宁愿写在这里,也不想把它埋进第 47 题的答案里。如果一份正式的合规报告是采购的前提条件,请尽早提出——那是一次范围界定的讨论,不是一个勾选框。

采购会问的问题

在你不得不发问卷之前就已作答

没有。Lurno 对齐 ISO 27001 实践——访问控制、密码学、日志、变更管理和供应商管理都作为控制项实现在产品中——但 Augmental Learning Inc. 既没有 ISO 27001 证书,也没有 SOC 2 报告。我们宁愿可被核查,也不追求好看。本页上的每一点都能在一次实时会话中演示。

把问卷发给我们。

其中大部分上面已经答过。剩下的——数据驻留、留存、次级处理者、DPA——带到通话上来,我们会用与这里同样直白的措辞回答。