CipherStash 客户端 FFI (@cipherstash/protect-ffi(中文(简体) )
[大 如果您想要在您的应用程序中执行此软件包, 请使用官方
@cipherstash/stack软件包。 。 。 .
该项目为CepherStash客户端Rust SDK提供了JS装订,并被 创建- 尼昂。 。 。 .
大楼
大楼需要 已支持的节点和rust版本。 。 。 .
要运行建设,运行:
$ npm run build
此命令使用 @neon-rs/cli (英语) 用于从输出中组装二进制节点加通 cargo。 。 。 .
本地设置
认证 stash CLI来建立你的地方环境。 它通过 npx - 不需要单独安装:
npx stash auth login
您将被提示注册或创建账户 .
探索
建成后 protect-ffi,您可以在节点控制台探索其出口.
代表团必须出示全权证书,以便 newClient() 成功——从 CipherStash 剖面商店、环境变量或明确 authStrategy 转至 newClient()对于地方发展来说,最简单的选择是: npx stash auth login,它包含配置文件商店。 或者设置 CS_WORKSPACE_CRN, (中文(简体) ), CS_ACCESS_KEY,则 CS_CLIENT_ID编号 :CS_CLIENT_KEY 键盘在您的环境中 .
$ npm i
$ npm run build
$ node
> const addon = require(".");
> const client = await addon.newClient({ encryptConfig: {v: 1, tables: {users: {email: {indexes: {ore: {}, match: {}, unique: {}}}}}} });
> const ciphertext = await addon.encrypt(client, { plaintext: "plaintext", column: "email", table: "users" });
> const plaintext = await addon.decrypt(client, { ciphertext });
> console.log({ciphertext, plaintext});
EQL 版本选择
newClient 接受一个 eqlVersion 选项选择线条格式
encrypt 编号 : encryptBulk 编号 : encryptQuery 发出 :
// EQL v2 (default) — the `eql_v2_encrypted` payload format
const v2 = await addon.newClient({ encryptConfig })
// EQL v3 — payloads for the per-capability `eql_v3` domains
const v3 = await addon.newClient({ encryptConfig, eqlVersion: 3 })
与 eqlVersion: 3,每列有效载荷的目标 eql_v3 域名
来源于 cast_as 和索引:
每个公示栏域都包含一个 eql_v3_ 前缀( 故为 SQL)
列类型是 public.eql_v3_text_eq; 仅词查询双胞胎不
(单位:千美元)eql_v3.query_text_eq),因为 eql_v3 计划已经把它们改了.
cast_as | 家属 | 索引 | 域名 |
|---|---|---|---|
text | text | unique + 键 ore + 键 match | eql_v3_text_search_ore |
text | text | unique + 键 ope + 键 match | eql_v3_text_search |
text | text | unique + 键 ore | eql_v3_text_ord_ore |
text | text | match | eql_v3_text_match |
text | text | unique | eql_v3_text_eq |
int 编号 : small_int 编号 : bigint | integer 编号 : smallint 编号 : bigint | ore (有无) unique(中文(简体) ) | eql_v3_<family>_ord_ore |
int 编号 : small_int 编号 : bigint | integer 编号 : smallint 编号 : bigint | unique | eql_v3_<family>_eq |
number 编号 : decimal 编号 : date 编号 : timestamp | double 编号 : numeric 编号 : date 编号 : timestamp | 见上文 | 见上文 |
| 任意平面 | —— 说 | 无 | 仅存储域( e)eql_v3_text, (中文(简体) ), eql_v3_integer, (...) (中文(简体) ) |
boolean | boolean | 不仅仅是 | eql_v3_boolean (只存储——任何索引错误) |
json | json | ste_vec (必须, compat 模式) | eql_v3_json_search |
注释:
- 最富有的匹配域获胜,它必须覆盖每个配置
能力——一种沉默地放弃术语错误的组合
(例如:.
unique+ 键match或者说ore+ 键match文本:没有单个域 带有这些术语集,所以添加缺失的索引以达到搜索 域或将能力分出各列。 仅使用 Scalar 配置 可使用eqlVersion: 2; 包含ste_vec需要v3时. - 两个文本搜索域仅在它们携带的顺序名词上有所不同:
eql_v3_text_search_ore携带ob(德文),eql_v3_text_search携带op(OPE) (英语). 配置两者ore财务报告和审定财务报表ope选择 ORE . - 例外: 投出一个 任期 等会就没事了 能力 活下来了.
非文本排序域只携带
ob这样unique+ 键ore编号 数字列投放hm——平等仍然通过ORE操作者实现. - 排序文本需要
unique指数(eql_v3_text_ord_ore编号 :eql_v3_text_ord_ope携带hm+ 键ob编号 :op(三);ore- 只有文本错误. - A 类
json栏ste_vec索引必须使用compat模式(模式)cipherstash-client默认自0.40.0起). v3 命令 SteVec 条目 cLLW -OPE 游戏op任期;astandard- 模式索引发布 CLLW- OREoc,哪个 没有机械转换,所以在配置时出现这样的列错误. - 包含
ste_vec默认为 EQL v3. 明确eqlVersion: 2被拒绝,因为客户端不能代表新的 以 v2 有线格式选择绑定 SteVec 信封. decrypt接受 两者 格式,不论eqlVersion,所以v2和 v3 数据可以在迁移期间共存.- v3 查询加密返回索引名词只操作符: scalar 查询
生成列域的查询双双 (
{v, i, <terms>},没有c密码)——与col = $1::jsonb::eql_v3.query_<name>(或 命令操作员,或@@(原始内容存档于2017-09-21). for match. 剧本总是带着所有的东西 列域术语,以indexType被问及。 贾森 封装查询生成eql_v3.query_json针和ste_vec_selector查询返回赤色选择器散列 页:1->编号 :->>操作员。 JSON 路径中的精确平等ste_vec_value_selector与{path, value}返回一个输入 适合 GIN 支持的仅选取封闭针@>操作员. ope- 索引列映射到<family>_ord_ope并携带op(CLLW-OPE)名词(从密码-客户0.38.
[注] 正在中断类型脚本更改 :
encrypt编号 :encryptBulk现在返回EncryptedPayload(单位:千美元)Encrypted | EncryptedV3改为Encrypted。 。 。 . V2 客户端的运行时输出没有变化, 但访问的代码.k或指定结果为Encrypted必须先缩小。 v3 分级带 没有k在读它之前注意它的存在'k' in payload && payload.k === 'ct'(a v2 scalar),或检查payload.v === 3以检测v3成员。 (赤裸的)payload.k === 'ct'不汇编反对工会。 )
大缩略语
已加密 cast_as: 'bigint' 列存储已签名的64位整数
(PostgreSQL 存档副本) bigint) (中文(简体) ). encrypt 编号 : encryptBulk 编号 : encryptQuery 编号 :
encryptQueryBulk 接受简写为JS number 或联合来文
bigint数字 :
bigint输入是精确的,并对照完整的i64范围检查范围: -9223372036854775808至9223372036854775807 (2^63至2^63-1) (中文(简体) ). 区域外的值RangeError指定界限和界限 错误的方向。 没有code这是JS的边界检查, 而不是在下面描述的 Rust 错误之一 错误搜索索引 条款(hm, (中文(简体) ),ob, (中文(简体) ),op)由同值产生,所以边界 请检查是否也覆盖索引- 期限生成 .number输入保留现有的精确整数 :分数, 非无限值, 或超出范围值出错, 而不是沉默 被截断了.- A 类
bigint仅被接受为平面图的顶层平面文字 栏。 JSON没有大块头,所以大块头都在里面cast_as: 'json'文档(或 JSON 封装查询条款) 以TypeError尼昂和原子弹上 更一般地说, 简洁的文字如下JSON.stringify两个平台上的语义:toJSON获得荣誉(a)Date成为它的ISO字符串,undefined属性被丢弃,以及 非无限数字成为null。 。 。 . - 内线形式
{"__protect_ffi_bigint__": "<digits>"}实值 保留:acast_as: 'json'完全由这个构成的简单文字 单键形状(带有相距 i64 小数字符串) 读取为 a 比林特在边界,拒绝Json列。 嵌入 较大文档中键的发生不受影响.
const ciphertext = await addon.encrypt(client, {
plaintext: 9007199254740993n, // beyond Number.MAX_SAFE_INTEGER — stays exact
column: 'score',
table: 'users',
})
const decrypted = await addon.decrypt(client, { ciphertext })
// decrypted === 9007199254740993n (a JS bigint)
[尖叫声] 中断更改 :
decrypt编号 :decryptBulk编号 :decryptBulkFallible现在,总是返回一个JSbigint页:1cast_as: 'bigint'栏-甚至 符合联署材料编号的价值观。 以前的释放返回anumber,无声地失去精确度Number.MAX_SAFE_INTEGER(2^53-1) (中文(简体) ). 代码比较或计算已解密的大意 列必须更新(例如:.decrypted === 123n改为decrypted === 123,或Number(decrypted)当值已知时 (小一点).
错误
两个条目都投出一个普通的JS Error 拥有稳定 code,设置在 Rust 中
从错误变体。 没有包装课 也没什么可拆的.
并不是每次失败都有代码——包裹密码-客户端错误
到达没有田. 'UNKNOWN' 是那个案件的名称,而不是一个值
脏发作.
类型脚本类型 a catch 变量为 unknown,所以你缩小一次。 那个
此软件包不需要任何信息 :
try {
await addon.encryptQuery(client, opts)
} catch (err) {
if (err instanceof Error && 'code' in err && err.code === 'INVALID_JSON_PATH') {
// handle JSON path mistakes
}
throw err
}
要将代码作为打入的值环绕, 请使用 isProtectErrorCode检查中
价值而不是外地存在的重要性: 节点集 code 独自一人
错误,所以赤裸裸 err?.code 读取会让 ECONNRESET 其中一个通过
这些.
import {
isProtectErrorCode,
type ProtectErrorCode,
} from '@cipherstash/protect-ffi'
function errorCode(err: unknown): ProtectErrorCode | undefined {
const { code } = err as { code?: unknown }
return isProtectErrorCode(code) ? code : undefined
}
密码本身是 PROTECT_ERROR_CODES 内 src/errors.ts,哪个
src/errorCodes.test.ts 检查 #[diagnostic(code(..))]
属性 Error 内 crates/protect-ffi/src/lib.rs - 一个地方一个代码
决定.
可用的脚本
在工程目录中,您可以运行:
由于这个包裹被吸收到 cipherstash/stack 单雷波, 货物被故意避免违约 build 财务报告和审定财务报表 test 路径: 根 pnpm test 到达每个包裹,在这条道路上的货运过程会给每个贡献者的机器上放上一个Rust工具链. 鲁斯特活佛以自己的剧本为后盾,以下列举. packages/protect-ffi/src/lintWiring.test.ts 执行分法.
pnpm run build
编译类型脚本 lib/ 与 tsc。这是软件包 main,它被生成——一个工作空间的消费者解决一个空包直到运行. 它不会建造土生土长的; 使用 build:native 对于这个.
pnpm run build:native
构建节点加通( N)index.node)来源,生成一个发布库 cargo --release。 。 。 .
额外 cargo build 可附上论据。 注意没有 -- 分隔符 – pnpm 向前 -- 逐字记录( npm 剥去它),这些脚本结束于 > cargo.log因此,一个分离的旗地 之后 重新定向和货物拒绝作为立场论据。 例如,允许 货物特性数字 :
pnpm run build:native --feature=beetle
pnpm run debug
类似 build:native 但生成调试构建 cargo。 。 。 .
pnpm run cross
类似 build:native 但使用时 交叉键 要交叉编译到另一个平台。 使用 CARGO_BUILD_TARGET 用于选择构建目标的环境变量. pnpm run zigbuild 通过 货物建造,这是释放矩阵用来给glibc打针.
pnpm run build:wasm
构建 wasm32-unknown-unknown 输出到 dist/wasm/ 与 wasm-pack,然后插入 .wasm 作为基准64 ./wasm-inline 输入。 需要原32目标 wasm-pack (两者均由 mise install 在此目录中).
pnpm test
类型检查TypeScript,运行单元测试(tsc + vitest),并用提示和格式检查TypeScript. 无货物,按设计——见上文.
注:这也没有进行整合测试. 对于这些,见 下级。 。 。 .
pnpm run test:cargo
测试套房的一分之一: cargo test --locked 加号 cargo fmt --check。运行时使用路径过滤的根工作流程,而不是 pnpm test。 。 。 . --locked 而不是悄悄地再生出一个僵尸 Cargo.lock ——建筑脚本没有通过,所以一个合法地更新锁的局部建筑仍然有效.
pnpm run test:typecheck:wasm
类型检查 type-tests/ 与原子弹产生的声明相对应 dist/wasm/需求 build:wasm 财务报告和审定财务报表 build 因此它不属于 pnpm test ——必须经过一个新的克隆人,没有 dist/。 。 。 .
mise run lint:rust
每个Rust检查CI门上:对宿主目标进行剪接,对接 wasm32-unknown-unknown,以及 cargo fmt --check。 。 。 . pnpm test 把这些都抛出,所以在推动rust改变之前先跑.
原臂需要安装一次目标:
rustup target add wasm32-unknown-unknown
mise run fmt 修正检查报告的格式.
项目布局
该项目的目录结构是:
protect-ffi/
├── Cargo.toml
├── README.md
├── integration-tests/
├── lib/
├── src/
| ├── index.mts
| └── index.cts
├── crates/
| └── protect-ffi/
| └── src/
| └── lib.rs
├── platforms/
├── docs/
├── scripts/
├── package.json
└── target/
| 条目 | 目的 |
|---|---|
Cargo.toml | 货物 显示文件,通知 cargo 命令. |
README.md | 这个文件. |
integration-tests/ | 包含整合测试的目录. |
lib/ | 包含生成输出的目录 页:1。 。 。 . |
src/ | 包含 TypeScript 源文件的目录. |
index.mts | 此库通过时的输入点 无害环境管理 import 语法. |
index.cts | 此库通过时的输入点 司法理事会 require。 。 。 . |
crates/ | 包含项目 Rust 源代码的目录树 . |
lib.rs | Rust源代码的入站点. |
platforms/ | 包含此库所支持的每个平台的二进制附加后端的分布的目录. |
docs/ | JSONB 整合文件和移民说明. |
scripts/ | 构建帮助脚本( 如 WASM inlineing) . |
package.json | 时间 显示文件,通知 npm 命令. |
target/ | 二进制由罗斯特建筑所出产的文物. |
融合测试
融合测试现场 ./integration-tests 目录.
这些测试利用了 Rust 和 JavaScript 的本地建筑来测试 @cipherstash/protect-ffi 正如API消费者那样.
目录是它自己的私人 pnpm 工作空间成员(@cipherstash/ffi-integration-tests),这样 pnpm install 在回波根安装它, 两者 @cipherstash/protect-ffi 财务报告和审定财务报表 @cipherstash/eql 解决此树上的包而不是公布柏油丸。 它已经 没有 test 脚本 目标——根 pnpm test 否则会尝试运行一个套房 需要多克和现场证明。 使用 mise 任务.
这些测试依赖于:
- 要配置的 CipherStash (通过)
.toml配置或环境变量),以及 - 待设定的 Postgres 环境变量
示例环境变量:
CS_CLIENT_ID=
CS_CLIENT_KEY=
# The integration tests read CS_CLIENT_ACCESS_KEY; the library itself reads CS_ACCESS_KEY
CS_CLIENT_ACCESS_KEY=
CS_WORKSPACE_CRN=
# Must match the port used by the integration-test setup (mise.toml)
PGPORT=5436
PGDATABASE=cipherstash
PGUSER=cipherstash
PGPASSWORD=password
PGHOST=localhost
进行整合测试:
mise setup
mise test:integration
也可以以"观察"模式运行集成测试:
mise test:integration --watch
默认的锁上下文测试不包含在内,因为无效锁上下文在ZeroKMS中的火灾安全警告. 包括这些,运行:
mise test:integration:all
释放
这个包被吸收到 cipherstash/stack
和它的放出现在运行在该存储器的
更改 流动而不是a
workflow_dispatch 触发。 不再有手取的版本:
包装及其6个平台软件包共享更改器 fixed 组,所以
释放所有7个在锁步.
写入更改列表( E)pnpm changeset 在 repo 根) 命名
@cipherstash/protect-ffi; 固定组向平台传播凸起
软件包。 变形体变成 CHANGELOG.md 条目 - 更改器拥有
现在的文件,所以 [Unreleased] 标题和 version npm 生命周期
用来宣传它的钩子不见了.
出版的剪接已经完成,随之而来的是更改的禁运. 无
现在所有七个软件包都值得信任的出版 cipherstash/stack绑定
改为 release.yml名称 @cipherstash/protect-ffi 释放
通常情况下。 挡住一个的警卫scripts/lint-no-ffi-changeset.mjs和
页:1 .changeset/<name>.md.deferred 将它停到切口的公约
都不见了.
而路径被证明, 不只是配置 —— 说 0.32.0 发表于
此仓库 。 Npm 名称上的 SLSA 出处
https://github.com/cipherstash/stack 财务报告和审定财务报表 .github/workflows/release.yml, (中文(简体) ),
这是解决问题的唯一证据:
这一段说,FFI的释放没有从这里流出,写着0.31.0
当0.32.0 降落时,最新鲜的 也从未重温过.
如果您发现一个文件仍然带有扩展名, 该文件是写在
封锁,目前为惰性而非停放: @changesets/read 选择在
.endsWith('.md'),因此它描述的更改会空出
更改日志条目和无内容 changeset version 或者说 changeset publish 将
说吧 重命名为 git mv,或者如果更改从未运出,则删除.
scripts/__tests__/no-parked-changesets.test.mjs 不管是哪一种方式都失败了.
上一个存储器的 GitHub 动作工作流程保存在
.github/ 在此目录中由子树导入并保存为参考
那个港口 他们走了,六个平台的建构矩阵 现在生活在
仓库根 .github/workflows/_build-ffi-artifacts.yml,与
ffi-preflight.yml 作为它的人工分发干线。 没有包裹
目录由 GitHub 执行, 它从仓库读取工作流程
仅根- src/lintWiring.test.ts 如果有人回来了,就失败了.
学习更多
更多地了解: