SecretSpec 0.13:面向 Python、Node.js、Go、Ruby 和 Haskell 的 SDK
摘要
SecretSpec 0.13 发布了针对 Python、Node.js/TypeScript、Go、Ruby 和 Haskell 的原生 SDK,使应用程序能够直接解析 secretspec.toml 中声明的机密,而无需依赖 CLI。
<p><a href="https://lobste.rs/s/5r5ebh/secretspec_0_13_sdks_for_python_node_js_go">评论</a></p>
查看缓存全文
缓存时间: 2026/07/04 16:43
# SecretSpec 0.13:Python、Node.js、Go、Ruby 和 Haskell 的 SDK
来源:https://secretspec.dev/blog/secretspec-0-13-sdks/
SecretSpec 将应用程序需要*哪些*秘密(在 `secretspec.toml` 中声明)与*值存放何处*(如系统钥匙串、1Password 或 Vault 等提供程序)分离。在此之前,运行时读取这些已解析的秘密只能通过 CLI 或 Rust SDK。如果你的服务是用 Python 或 Go 编写的,你只能通过 `secretspec run` 来调用,或者自己重新实现解析逻辑。
SecretSpec 0.13 (https://github.com/cachix/secretspec/releases/tag/v0.13.0) 填补了这一空白。它提供了五种语言的原生 SDK:Python、Node.js / TypeScript、Go、Ruby 和 Haskell。每个 SDK 都能精确解析清单中声明的秘密,使用与 CLI 相同的提供程序、配置文件、后备链和生成器,无需按语言进行额外配置。
## 一个解析器之上的原生绑定
节选自“一个解析器之上的原生绑定” (https://secretspec.dev/blog/secretspec-0-13-sdks/#native-bindings-over-one-resolver)
每个 SDK 都是与 CLI 相同的 Rust 核心之上的轻量级客户端。绑定中不包含任何提供程序逻辑、配置文件解析、链式回退、`as_path` 物化或秘密生成逻辑。每当 SecretSpec 新增一个提供程序,该提供程序在发布当天即可在所有语言中工作,并且所有 SDK 的行为完全一致。
每种生态系统的绑定策略各不相同:
- **Python**:一个 pyo3 扩展,静态链接,以独立的 `cp39-abi3` wheel 形式发布。
- **Node.js**:一个 napi-rs 插件,附带预构建的跨平台包。
- **Ruby**:一个原生 C 扩展(mkmf),解析器静态链接到平台 gem 中。
- **Go**:`secretspec-ffi` C ABI 通过 purego (https://github.com/ebitengine/purego) 在运行时加载(无需 cgo)。
- **Haskell**:相同的 C ABI,在构建时通过 Haskell FFI 链接。
## 相同的三个步骤,使用你的语言
节选自“相同的三个步骤,使用你的语言” (https://secretspec.dev/blog/secretspec-0-13-sdks/#the-same-three-steps-in-your-language)
每个 SDK 都模仿了 Rust derive crate 的词汇:一个构建器,接受提供程序、配置文件和访问原因,然后调用 `load()` 进行解析,最后返回一个可读或可导出到环境中的秘密映射。
```python
# Python
from secretspec import SecretSpec
resolved = (
SecretSpec.builder()
.with_provider("keyring://")
.with_profile("production")
.with_reason("boot web app")
.load()
)
print(resolved.secrets["DATABASE_URL"].get) # 值,或 as_path 对应的文件路径
resolved.set_as_env() # 导出到 os.environ
```
```javascript
// Node.js / TypeScript
const { SecretSpec } = require('secretspec');
const resolved = SecretSpec.builder()
.withProvider('keyring://')
.withProfile('production')
.withReason('boot web app')
.load();
console.log(resolved.secrets.DATABASE_URL.get()); // 值,或 as_path 文件路径
resolved.setAsEnv(); // 导出到 process.env
```
```go
// Go
resolved, err := secretspec.New().
WithProvider("keyring://").
WithProfile("production").
WithReason("boot web app").
Load()
fmt.Println(resolved.Secrets["DATABASE_URL"].Get()) // 值,或 as_path 文件路径
resolved.SetAsEnv() // 导出到环境变量
```
```ruby
# Ruby
resolved = Secretspec::SecretSpec.builder
.with_provider("keyring://")
.with_profile("production")
.with_reason("boot web app")
.load
puts resolved.secrets["DATABASE_URL"].get # 值,或 as_path 文件路径
resolved.set_as_env! # 导出到 ENV
```
```haskell
-- Haskell
resolved <-
S.load
( S.builder
& S.withProvider "keyring://"
& S.withProfile "production"
& S.withReason "boot web app"
)
S.setAsEnv resolved -- 导出到环境变量
```
在所有 SDK 中,`load()` 解析每个声明的秘密,缺少必需的秘密会抛出类型化的 `MissingRequiredError`,而 `as_path` 秘密会返回一个可读的文件路径,并附带清理临时文件的机制。访问原因会提供给与 0.12 (https://secretspec.dev/blog/secretspec-0-12-audit-logs-and-coding-agents/) 相同的审计日志和 `require_reason` 策略,因此 Go 服务与 CLI 一样可审计。
## 编写你自己的绑定
节选自“编写你自己的绑定” (https://secretspec.dev/blog/secretspec-0-13-sdks/#write-your-own-binding)
所有五个 SDK 底层都是一个新 crate:`secretspec-ffi`,一个用于解析秘密的小型、带版本号的 C ABI。如果你使用的语言我们尚未支持,你可以直接绑定到它。它还公开了 SDK 共享的公共 Rust 构建块:`Secrets::resolve()` 和 `Secrets::report()`,因此 Rust 程序可以使用相同的带值和不带值入口点。
## 类型化秘密,一种模式适用于所有语言
节选自“类型化秘密,一种模式适用于所有语言” (https://secretspec.dev/blog/secretspec-0-13-sdks/#typed-secrets-one-schema-for-every-language)
`secretspec.toml` 已经知道你的秘密结构,因此 0.13 可以将该结构传递给你的类型系统。`secretspec schema` 会为你的清单生成一个 JSON Schema,可以包含所有配置文件的联合,或者使用 `--profile` 指定单个配置文件。通过 quicktype (https://quicktype.io/) 可以生成任何语言的惯用类型化类,然后使用每个 SDK 的 `fields()` 映射来填充它们:
```
secretspec schema | quicktype -s schema --top-level SecretSpec --lang python -o secrets_gen.py
```
```python
typed = Secrets.from_dict(resolved.fields())
print(typed.database_url) # 类型化的 str
```
一个模式驱动所有语言的类型系统,无需为每种语言手写发射器。
```
pip install secretspec # Python
npm install secretspec # Node.js / TypeScript
gem install secretspec # Ruby
go get github.com/cachix/secretspec/secretspec-go # Go
```
对于 Haskell,将 Hackage 上的 `secretspec` 添加到你的 `build-depends` 中。CLI 和 Rust SDK 按常规升级:
有关每种语言的指南,请参阅 SDK 概览 (https://secretspec.dev/sdk/overview/)。有问题或反馈?加入我们的 Discord (https://discord.gg/naMgvexb6q)。
相似文章
github/spec-kit
Spec Kit 是 GitHub 推出的一款开源工具包,支持规范驱动开发,允许开发人员利用 AI 编码代理直接从可执行规范生成可运行的软件实现。
@rohanpaul_ai:GitHub 最近发布了这个仓库 SpecKit,一个开源工具包,用于修复 vibe coding 的一个大弱点:即 AI 经常……
GitHub 发布了 SpecKit,这是一个开源工具包,通过强制采用规范优先的工作流程来解决 AI 编码的一个弱点,将产品规格转化为 AI 代理的可执行开发合同。
DeepSpec - deepseek-ai 集合
DeepSeek AI 在 Hugging Face 上发布了 DeepSpec 集合,包含基于 Qwen3 和 Gemma4 的各种尺寸(1B-3B)的推测解码模型(dspark, dflash, eagle3)。
@charles_irl: 这是spec火热夏天
DeepSeek 开源了 DeepSpec,一个用于训练和评估推测解码模型的完整技术栈代码库。
LemmaScript:通过 Dafny 验证 TypeScript 的工具链
LemmaScript 是一套全新工具链,可将 TypeScript 编译为 Dafny 进行形式化验证,无需改动运行时,并已通过验证 Hono 框架中一个 CVE 修复实例加以演示。