buckyos
v0.7.122
Published
BuckyOS WebSDK for browser and Node.js environments
Maintainers
Readme
BuckyOS SDK 与 Tool
buckyos npm 包同时提供 browser/node/provision SDK 和项目本地 CLI。App 开发者只需项目已有的
Node.js,不需要安装 Deno,也不需要 checkout BuckyOS 或本仓库:
npm install buckyos
npx buckyos --version
npx buckyos pikg init . --owner did:bns:alice --kind static-web --source ./dist
npm run build
npx buckyos pikg build ./dapp_meta
npx buckyos pikg pack ./dapp_dist
npx buckyos pikg info ./dapp_dist/example-0.1.0.pikg
npx buckyos app install ./dapp_dist/example-0.1.0.pikg --policy local-developer
npx buckyos task wait <task-id>
npx buckyos app status example
npx buckyos log tail --app example当命令需要读取项目目录和 Tool 包目录之外的源码时,通过可重复的全局参数显式授权:
npx buckyos --allow-read ../shared-assets --allow-read /opt/app-source pikg build ./dapp_meta--allow-read 只增加读权限,不会增加写权限。
npx buckyos 和 npm scripts 中的 buckyos 固定使用项目 lockfile 对应的 Tool。PATH 中裸 buckyos
由 BuckyOS 系统安装器管理并指向 $BUCKYOS_ROOT/bin/buckyos;文档不推荐全局
npm install -g buckyos。两种分发运行同一套命令实现,互不覆盖、互不调用、也不会自更新。
遇到本地构建或目标配置问题,先运行 npx buckyos pikg doctor。--version --verbose 会打印 实际
executable、Node/Deno host、distribution、Tool/SDK/协议版本和本地 policy。
身份验证
然后在浏览器中允许的,属于dApp的页面,都应使用BuckyOS SDK提供的登陆功能来获得一个有效身份。 身份验证流程如下:
路径1:1.浏览器发送请求 --HTTPs--> 2.cyfs-gateway进行验证 --Local HTTP--> 3.dApp Server使用BuckyOS Rust SDK进行验证。 路径2:1. App -->http@bdt--> 2.cyfs-gateway进行验证 -- Local HTTP--> 3.dApp Server使用BuckyOS Rust SDK进行验证。 路径2 依赖有客户端身份的App/CYFS 浏览器,暂未实现 路径3:1.App Service --RPC@http--> 2. system_service(验证rpc.token,系统调用验证,不走cyfs-gateway)
cyfs-gateway的验证
cyfs-gateway会根据HTTP Request的Host字段和cookie中的buckyos_token字段来进行验证。 该buckyos_token通常是有相对较长有效期的普通权限jwt. 对POST请求,验证首先要得到jwt格式的rpc.token,然后进一步验证该rpc请求是否有正确的授权。涉及到敏感操作的rpc.jwt通常是短期的,甚至是一次性的,并有sudo级别权限。
验证方根据buckyos_token / rpc_token得到appid,userid,resource,OP组成四元组,到RBAC库中查询对应权限,并进行验证。 RBCL需要的四元组:
appid,来自http request的host字段,web sdk里不可设置
userid:必填
resource:来自http request的path字段.完整写法是app://appid/http_path/,各种系统调用都有自己构造path的方法,与参数有关。jwt中通常不包resource信息,除非特别敏感的一次性sudo操作
OP: 来自http request的method字段 (GET/POST/PUT/DELETE/...),jwt中是可以包含的。cyfs-gateway会根据这四元组,到RBAC库中查询对应权限,并进行验证。其验证方法是先判断appid是否有权限,再判断userid是否有权限。任何一个不通过,都会返回权限不足。
cyfs-gateway对于需要http验证的请求,如果没有buckyos_token字段,会重定向到一个预设的访问登陆页,引导用户登陆成功后,再重定向回原URL。该登陆页面通常是支持guest访问的。
buckyos_token字段的生成
// at feedlist.excample.com
await buckyos.loginByBrowserSSO()
// 当前窗口会跳转到 sys.$zoneid/sso/login
// SSO 成功并跳回当前页后,再读取当前账号状态
let user_info = await buckyos.getAccountInfo()
let bucky_token = user_info?.session_token
let user_id = user_info?.user_id
let rpc_client = new buckyos.kRPCClient(feedlist_api_url, bucky_token)
let user_feeds = rpc_client.get_user_feeds(user_id)执行高权限操作
on_click_change_password(){
let new_password = get_new_password();
let bucky_token =await buckyos.authClient.request("change password");
let rpc_client = new buckyos.kRPCClient(account_api_url,bucky_token);
//高权限操作的所有参数都在bucky_token的payload中
rpc_client.change_password(bucky_token);
}下面是feedlist_api的实现
on_request(request,response){
let user_id = request.params.user_id
let token = request.bucky_token;
payload = verify_token(token,verify_hub.public_key);
if payload.userid != user_id {
response.send(403,"permission denied");
}
if payload.appid != "feedlist" {
response.send(403,"permission denied");
}
response.send(user_feeds);
}buckyos.authClient的实现
authClient主要靠系统的内置verify_hub服务来完成功能,其基本逻辑是
- 在当前窗口直接跳转到标准的
sys.$zoneid/sso/login页面,该页面会根据 login 时的参数调整一些行为 - 用户在跳转后的页面中完成登录,有2种方法 a. 使用用户名密码向verify_hub发起请求,verify_hub会根据其掌握的账号信息返回必要的jwt验证信息 b. 要求用户输入一个加密后的私钥,当用户输入正确的解密密码后,可以用该私钥来构造jwt
bucky_token jwt payload的内容
签名都是verify_hub服务完成的
{
"appid": "$appid",
"userid": "$did",
"key":"$aes_key", 用verify_hub的公钥加密的aes key,也用来做session key
"iss": "verify_hub", 或 "$did",使用用户的私钥来构造jwt时,会使用用户的sudo权限
"exp": "$exp"
}防御jwt的重放攻击
因为会工作在http环境,因此会用明文发送jwt.
namelib 与 provision(身份文档构造)
SDK 自带 Rust name-lib 的 TS 镜像(namelib,universal 导出),以及 buckycli 构造侧命令的 TS
镜像(buckyos/provision,node-only,要求 Node >= 22.13 或 Deno >= 2.2,依赖
node:sqlite)。格式与 Rust 端逐字节对齐 (Ed25519 PKCS8 PEM / JWK / EdDSA JWT),由 golden fixture
单测保障 (tests/fixtures/provision/)。
Quickstart:keygen → createUserEnv → createNodeConfigs
import { namelib } from 'buckyos'
import { createNodeConfigs, createSnConfigs, createUserEnv } from 'buckyos/provision'
// 1. 生成 Ed25519 身份密钥(私钥 PKCS8 PEM + 公钥 JWK)
const { privateKeyPem, publicKeyJwk } = await namelib.generateEd25519KeyPair()
// 2. 构造用户/zone 环境(user_config.json、zone_config.json、zone TXT record 等)
await createUserEnv({
username: 'alice',
hostname: 'alice.bns.did',
oodName: 'ood1',
snBaseHost: 'devtests.org',
outputDir: '/tmp/alice-env',
})
// 3. 构造节点身份(node_identity.json、device_mini_config.jwt、start_config.json)
await createNodeConfigs({ deviceName: 'ood1', envDir: '/tmp/alice-env' })其它能力:createSnConfigs / registerUserToSn / registerDeviceToSn(SN 侧)、 setPkgMeta /
MetaIndexDb(pkg meta 索引库)、buildDidDocs(内核服务 did docs)、 createCa /
createCertFromCa(旧 CertManager 兼容 TLS 证书),以及 IdentityRoots /
createIdentityCertFromCa(按 identity path 协议写入
$BUCKYOS_IDENTITY_ROOT/{encoded raw host URI}/server.* 和
$BUCKYOS_SECURITY_ROOT/{encoded raw host URI}/server.private.pem;现阶段不生成
server.keyref.json)。
注意:buckyos/provision 导出的 DEV_TEST_KEYS / dev EVM account helper 是仅供本地开发
的公开测试密钥,使用固定 dev 助记词按 Rust name-lib 的 mnemonic 派生规则构造,严禁用于
真实激活流程;浏览器 bundle 不包含 provision。
构建与发布
本地构建
构建项目并生成类型定义文件:
# 使用 pnpm(推荐)
pnpm run build:all
# 或使用 npm
npm run build:all该命令会执行以下操作:
- 运行
vite build构建项目,生成dist/index.*、dist/browser.*、dist/node.* - 运行
tsc -p tsconfig.build.json生成对应的 TypeScript 类型定义文件 - 生成与 package version 一致的 Tool 版本文件,并构建 Node CLI bundle
构建产物位于 dist/ 目录。
AppClient Demo
仓库里带了一个最小可运行的 AppClient 示例:examples/app_client_demo.ts。
它会:
- 使用本机私钥目录初始化
AppClient - 向真实运行中的
system_config读取boot/config - 打印当前
session_token的 claims 和boot/config的顶层 key
运行方式:
pnpm run demo:app-client可选环境变量:
BUCKYOS_TEST_APP_ID=buckycli
BUCKYOS_SYSTEM_CONFIG_URL=http://127.0.0.1:3200/kapi/system_config如果你是在已发布的 SDK 包里使用,同样的示例代码应从 buckyos/node 导入,而不是仓库内的相对路径。
发布到 GitHub
1. 更新版本号
在 package.json 中更新版本号:
# 使用 npm version 自动更新版本号并创建 git tag
npm version patch # 1.0.0 -> 1.0.1
npm version minor # 1.0.0 -> 1.1.0
npm version major # 1.0.0 -> 2.0.02. 构建项目
确保构建产物是最新的:
pnpm run build:all3. 提交并推送
# 提交更改
git add .
git commit -m "chore: release v1.0.1"
# 推送代码和标签到 GitHub
git push
git push --tags4. 创建 GitHub Release(可选)
- 访问 GitHub 仓库页面
- 点击 "Releases" -> "Create a new release"
- 选择刚才推送的 tag
- 填写 Release 标题和描述
- 上传构建产物(
dist/目录下的文件)作为附件(可选)
发布到 npm
发布工作流使用 npm Trusted Publishing/provenance、最小权限和 npm 账号 2FA。首次包含 Tool 的
版本只能进入 next/beta,不得直接覆盖 latest:
pnpm run build
pnpm run check:cli
pnpm run test:cli
pnpm run test:cli-conformance
pnpm run test:tarball
pnpm run test:release-manifest
npm publish --tag next --provenance系统打包必须固定这次 CI 生成的原始 npm tarball、CycloneDX SBOM、release manifest 和 Deno digest,不得重新 checkout 或重建。真实 App/DV、系统离线安装、升级和回滚验收通过后,只移动 dist-tag:
npm dist-tag add buckyos@<已验证版本> latest回滚 dist-tag 不会改变已经安装的 BuckyOS system Tool;系统 Tool 只随 installer/updater 事务 更新或回滚。
