ai-cortex-sdk
Rust SDK for AI Cortex server — authentication, authorization, and software store APIs.
Installation
Add to your Cargo.toml:
[]
= { = "../crates/ai-cortex-sdk" }
Quick Start
use ;
async
Configuration
// server_url, PAT, software_id(软件身份,心跳/下载按该软件许可证校验)
let config = new;
// Custom timeout
let config = new
.with_timeout;
API Reference
Authentication
| Method | Description |
|---|---|
client.login(username, password) |
Login and store session token |
client.logout() |
Logout and clear session |
client.is_logged_in() |
Check if currently authenticated |
Authorization
| Method | Description |
|---|---|
client.get_auth_info() |
Get current user's auth records and associated apps |
client.check_auth(app_key) |
Check if current user is authorized for a specific app |
Software Store
| Method | Description |
|---|---|
client.list_software() |
List all software with latest versions |
client.get_latest_version(software_id) |
Get latest version of a software |
client.download(version_id) |
Get download URL for a version (requires auth) |
Auto Update (自动更新)
提供 Pull(轮询) 和 Push(SSE 订阅) 两种更新检测方式。两者都需对该 software 持有有效许可证。
| Method | Description |
|---|---|
client.check_update(platform, current_version, channel) |
主动检查更新(Pull),返回 UpdateInfo |
client.open_update_events(software_id, last_event_id) |
打开更新事件 SSE 流(Push),返回 UpdateEventStream |
Pull — check_update
// 按 platform + channel 与 current_version 比较;channel 传 None 默认 "stable"
let info = client.check_update.await?;
// UpdateInfo { has_update, force_update, current_version, target_version: Option<VersionBrief> }
println!;
if let Some = &info.target_version
// force_update 阻塞语义:为 true 时客户端应阻止启动,引导用户升级后再放行
Push — open_update_events(SSE 长连接)
服务端通过 GET /api/softwares/sdk-update-events(text/event-stream,PAT 鉴权)主动推送新版本事件,
无需客户端轮询。返回的流需配合 futures_util::StreamExt 使用:
use StreamExt;
// software_id 传 None 订阅全部;last_event_id 用于断线重连补播
let mut stream = client.open_update_events.await?;
while let Some = stream.next.await
说明:
- SSE 是长连接,内部使用无读超时的 HTTP 客户端(绕过
CortexConfig.timeout的 30s 默认值), 靠服务端 15s keepalive 注释帧保活。 - 断线重连时把最后一次收到的
event.id作为last_event_id传入,服务端补播id > last的事件。 - 服务端会下发
: keepalive/: lagged注释帧,SDK 内部自动忽略。
Error Handling
use SdkError;
match client.login.await
Examples
See examples/ directory for complete usage examples.
basic.rs— Software store browsing, download, device listingauth_check.rs— Verify a PAT is validoffline_license.rs— Fetch and verify an offline licenseauto_update.rs— Check update (Pull) + subscribe SSE events (Push)
Run an example:
离线许可证
服务端可在 PAT 鉴权下通过 POST /api/offline-licenses/issue 下发一份签名许可证文件,
让客户端在受限网络/断网环境下仍能本地证明自己持有有效授权。文件结构:
payload 是 OfflineLicensePayload 的 snake_case JSON,包含
license_id / user_id / software_id / fingerprint / max_devices / expire_time / issued_at。
签名是对 payload 字符串 UTF-8 字节的 Ed25519 签名。
流程
use ;
// 1. 配置(可选钉扎公钥,增强防替换)
let config = new
.with_software_public_key;
let client = new;
let fp = collect.fingerprint;
// 2. 在线拉取(需联网 + 有效 PAT + 有效软件授权)
let file = client.fetch_offline_license.await?;
// 3. 本地验签:Ed25519 验签 → 解析 payload → 校验 software_id/fingerprint → 校验未过期
let payload = verify_offline_license?;
// 或用 client.verify_offline_license(&file, &fp) 自动带入配置的 software_id 与钉扎公钥
撤销语义与短 TTL
许可证的 expire_time = issued_at + 86400(1 天 TTL)。撤销依赖在线刷新:
许可证本身是自包含签名文件,服务端无法主动吊销已下发的离线文件;通过短 TTL 强制客户端
周期性联网 fetch_offline_license 重新换取。若服务端撤销了用户的软件授权或解绑了该设备指纹,
下一次 fetch 将失败,客户端即失去有效许可证,从而实现“软撤销”。
可选公钥钉扎
默认情况下客户端信任 issue 响应中下发的 public_key(依赖 TLS 保证传输不被篡改)。
对安全敏感场景,可通过 CortexConfig::with_software_public_key(hex) 钉扎一个预期公钥:
设置后 verify_offline_license 会要求下发公钥与之严格相等,否则直接判定为
LicenseFieldMismatch,可防御 TLS 被绕过/中间人替换公钥的攻击。不设置时则退化为信任下发公钥。
校验顺序
verify_offline_license 按以下顺序校验,任一失败立即返回对应 SdkError:
- 公钥钉扎(若提供)——
public_key必须与钉扎值相等 - Ed25519 验签 ——
public_key对payload字节验签 - 解析 payload JSON
- 字段匹配 ——
software_id与fingerprint必须与期望值一致 - 过期校验 ——
expire_time > now