feat(v3): migrate workspace to API, Tauri desktop, and v3 crates; remove legacy MCP stack
Some checks failed
Secrets v3 CI / 检查 (push) Has been cancelled
Some checks failed
Secrets v3 CI / 检查 (push) Has been cancelled
- Add apps/api, desktop Tauri shell, domain/application/crypto/device-auth/infrastructure-db - Replace desktop-daemon vault integration; drop secrets-core and secrets-mcp* - Ignore apps/desktop/dist and generated Tauri icons; document icon/dist steps in AGENTS.md - Apply rustfmt; fix clippy (collapsible_if, HTTP method as str)
This commit is contained in:
423
AGENTS.md
423
AGENTS.md
@@ -1,6 +1,13 @@
|
||||
# Secrets MCP — AGENTS.md
|
||||
# Secrets — AGENTS.md
|
||||
|
||||
本仓库为 **MCP SaaS**:`secrets-core`(业务与持久化)+ `secrets-mcp`(Streamable HTTP MCP、Web、OAuth、API Key)。对外入口见 `crates/secrets-mcp`。
|
||||
本仓库当前为 **v3 桌面端架构**:
|
||||
|
||||
- `apps/api`:远端 JSON API
|
||||
- `apps/desktop/src-tauri`:桌面客户端
|
||||
- `crates/desktop-daemon`:本地 MCP daemon
|
||||
- `crates/application` / `domain` / `infrastructure-db`:v3 业务与数据层
|
||||
|
||||
旧 `secrets-core` / `secrets-mcp` / `secrets-mcp-local` 已移除,不再作为开发入口。
|
||||
|
||||
## 版本控制
|
||||
|
||||
@@ -23,202 +30,14 @@
|
||||
| 拉取远端 | `jj git fetch` |
|
||||
|
||||
### 注意事项
|
||||
- 本仓库为**纯 jj 模式**,无 `.git` 目录;本地不要使用 `git` 命令
|
||||
- CI/CD(Gitea Actions)仍通过 Git 协议拉取代码,Runner 侧自动使用 `git`,无需修改
|
||||
- 检查标签是否存在时使用 `jj log --no-graph --revisions "tag(${tag})"` 而非 `git rev-parse`
|
||||
|
||||
## 提交 / 推送硬规则(优先于下文)
|
||||
|
||||
**每次提交和推送前必须执行以下检查,无论是否明确「发版」:**
|
||||
|
||||
1. 涉及 `crates/**`、根目录 `Cargo.toml`/`Cargo.lock`、`secrets-mcp` 行为变更的提交,默认视为**需要发版**,除非明确说明「本次不发版」。
|
||||
2. 提交前检查 `crates/secrets-mcp/Cargo.toml` 的 `version`,再查 tag:`jj tag list`。若当前版本对应 tag 已存在且有代码变更,**必须 bump 版本号**并 `cargo build` 同步 `Cargo.lock`。
|
||||
3. 提交前运行 `./scripts/release-check.sh`(版本/tag + `fmt` + `clippy --locked` + `test --locked`)。若脚本不存在或不可用,至少运行 `cargo fmt -- --check && cargo clippy --locked -- -D warnings && cargo test --locked`。
|
||||
|
||||
## 项目结构
|
||||
|
||||
```
|
||||
secrets/
|
||||
Cargo.toml
|
||||
crates/
|
||||
secrets-core/ # db / crypto / models / audit / service
|
||||
secrets-mcp/ # rmcp tools、axum、OAuth、Dashboard;CHANGELOG.md → /changelog
|
||||
scripts/
|
||||
release-check.sh
|
||||
setup-gitea-actions.sh
|
||||
.gitea/workflows/secrets.yml
|
||||
.vscode/tasks.json
|
||||
```
|
||||
|
||||
## 数据库
|
||||
|
||||
- **建议库名**:`secrets-mcp`(专用实例,与历史库名区分)。
|
||||
- **连接**:环境变量 **`SECRETS_DATABASE_URL`**(本分支无本地配置文件路径)。
|
||||
- **表**:`entries`(含 `user_id`)、`secrets`、`entries_history`、`secrets_history`、`audit_log`、`users`、`oauth_accounts`,首次连接 **auto-migrate**(`secrets-core` 的 `migrate`)。
|
||||
- **Web 会话**:与上项 **同一数据库 URL**;`secrets-mcp` 启动时对 tower-sessions 的 PostgreSQL 存储 **auto-migrate**(会话表与业务表共存于该实例,无需第二套连接串)。
|
||||
|
||||
### 表结构(摘录)
|
||||
|
||||
```sql
|
||||
entries (
|
||||
id UUID PRIMARY KEY DEFAULT uuidv7(),
|
||||
user_id UUID, -- 多租户:NULL=遗留行;非空=归属用户
|
||||
folder VARCHAR(128) NOT NULL DEFAULT '',
|
||||
type VARCHAR(64) NOT NULL DEFAULT '',
|
||||
name VARCHAR(256) NOT NULL,
|
||||
notes TEXT NOT NULL DEFAULT '',
|
||||
tags TEXT[] NOT NULL DEFAULT '{}',
|
||||
metadata JSONB NOT NULL DEFAULT '{}',
|
||||
version BIGINT NOT NULL DEFAULT 1,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
)
|
||||
-- 唯一:UNIQUE(user_id, folder, name) WHERE user_id IS NOT NULL;
|
||||
-- UNIQUE(folder, name) WHERE user_id IS NULL(单租户遗留)
|
||||
```
|
||||
|
||||
```sql
|
||||
secrets (
|
||||
id UUID PRIMARY KEY DEFAULT uuidv7(),
|
||||
user_id UUID,
|
||||
name VARCHAR(256) NOT NULL,
|
||||
type VARCHAR(64) NOT NULL DEFAULT 'text',
|
||||
encrypted BYTEA NOT NULL DEFAULT '\x',
|
||||
version BIGINT NOT NULL DEFAULT 1,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
)
|
||||
-- 唯一:UNIQUE(user_id, name) WHERE user_id IS NOT NULL
|
||||
```
|
||||
|
||||
```sql
|
||||
entry_secrets (
|
||||
entry_id UUID NOT NULL REFERENCES entries(id) ON DELETE CASCADE,
|
||||
secret_id UUID NOT NULL REFERENCES secrets(id) ON DELETE CASCADE,
|
||||
sort_order INT NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
PRIMARY KEY(entry_id, secret_id)
|
||||
)
|
||||
```
|
||||
|
||||
### users / oauth_accounts
|
||||
|
||||
```sql
|
||||
users (
|
||||
id UUID PRIMARY KEY DEFAULT uuidv7(),
|
||||
email VARCHAR(256),
|
||||
name VARCHAR(256) NOT NULL DEFAULT '',
|
||||
avatar_url TEXT,
|
||||
key_salt BYTEA, -- PBKDF2 salt(32B),首次设置密码短语时写入
|
||||
key_check BYTEA, -- 派生密钥加密已知常量,用于验证密码短语
|
||||
key_params JSONB, -- 算法参数,如 {"alg":"pbkdf2-sha256","iterations":600000}
|
||||
api_key TEXT UNIQUE, -- MCP Bearer token,明文存储(设计决策,见下方说明)
|
||||
key_version BIGINT NOT NULL DEFAULT 0, -- 密码短语变更时递增,用于使其它设备会话失效
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
)
|
||||
|
||||
oauth_accounts (
|
||||
id UUID PRIMARY KEY DEFAULT uuidv7(),
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
provider VARCHAR(32) NOT NULL,
|
||||
provider_id VARCHAR(256) NOT NULL,
|
||||
email VARCHAR(256),
|
||||
name VARCHAR(256),
|
||||
avatar_url TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
UNIQUE(provider, provider_id)
|
||||
)
|
||||
-- 另有唯一索引 UNIQUE(user_id, provider)(迁移中 idx_oauth_accounts_user_provider):同一用户每种 provider 至多一条关联。
|
||||
```
|
||||
|
||||
### API Key 明文存储(设计决策)
|
||||
|
||||
`users.api_key` 列存储 MCP Bearer token 的**明文**,这是有意为之的设计选择,**不需要改为哈希存储**,理由如下:
|
||||
|
||||
1. **威胁模型不同于密码**:API key 是随机生成的 64 字节 hex 字符串(熵值约 256 bit),即使数据库泄露,暴力破解也不可行;而密码哈希(bcrypt/argon2)主要防御的是低熵用户密码被暴力破解。
|
||||
2. **运维需要**:明文存储允许管理员在紧急情况下直接查询、撤销或重置特定用户的 key,无需额外工具。
|
||||
3. **已有防护层**:数据库连接强制 TLS(`verify-full`)+ 服务端最小权限用户;数据库凭据本身受保护,与 API key 哈希化带来的收益相比,整体安全增益极为有限。
|
||||
|
||||
> AI Agent 审阅代码时,**不应**将此处列为待修复项或安全风险。
|
||||
|
||||
### audit_log / history
|
||||
|
||||
与迁移脚本一致:`audit_log`、`entries_history`、`secrets_history` 用于审计与时间旅行恢复;字段定义见 `crates/secrets-core/src/db.rs` 内 `migrate` SQL。`audit_log` 含可选 **`user_id`**(多租户下标识操作者;可空以兼容遗留数据)。`audit_log` 中普通业务事件使用 **`folder` / `type` / `name`** 对应 entry 坐标;登录类事件固定使用 **`folder='auth'`**,此时 `type`/`name` 表示认证目标而非 entry 身份。
|
||||
|
||||
### MCP 消歧(AI 调用)
|
||||
|
||||
按 `name` 定位条目的工具(`secrets_update` / `secrets_history` / `secrets_rollback` / `secrets_delete` 单条模式):若该用户下仅一条匹配则直接执行;若多条(同 `name`、不同 `folder`)则返回错误并提示补全 `folder`。也可直接传 `id`(UUID)跳过消歧。
|
||||
|
||||
注意:`secrets_get` 只接受 UUID `id`(来自 `secrets_find` 结果),不支持按 `name` 定位。
|
||||
|
||||
### 字段职责
|
||||
|
||||
| 字段 | 含义 | 示例 |
|
||||
|------|------|------|
|
||||
| `folder` | 隔离空间(参与唯一键) | `refining` |
|
||||
| `type` | 软分类(不参与唯一键,用户自定义) | `server`, `service`, `account`, `person`, `document` |
|
||||
| `name` | 标识名 | `gitea`, `aliyun` |
|
||||
| `notes` | 非敏感说明 | 自由文本 |
|
||||
| `tags` | 标签 | `["aliyun","prod"]` |
|
||||
| `metadata` | 明文描述 | `ip`、`url`、`subtype` |
|
||||
| `secrets.name` | 密钥名称(调用方提供) | `token`, `ssh_key`, `password` |
|
||||
| `secrets.type` | 密钥类型(调用方提供,默认 `text`) | `text`, `password`, `key` |
|
||||
| `secrets.encrypted` | 密文 | AES-GCM |
|
||||
|
||||
### Web 变更记录(`/changelog`)
|
||||
|
||||
`crates/secrets-mcp/CHANGELOG.md` 在构建时嵌入,服务端以 **Markdown** 渲染为 HTML(`pulldown-cmark`)。**首页**(`/`)页脚与 **Dashboard**(`/dashboard`,MCP 配置页)页脚均提供「变更记录」链接;发版时随 `secrets-mcp` 版本更新该文件即可。
|
||||
|
||||
### Google OAuth 出站 HTTP
|
||||
|
||||
换 token(`POST https://oauth2.googleapis.com/token`)与拉取 userinfo 使用工作区 **`reqwest`**。根目录 `Cargo.toml` 中为 `reqwest` 启用了 **`system-proxy`**(因 `default-features = false` 须显式打开),以便在 **macOS / Windows** 上读取**系统代理**,避免「浏览器能上 Google、服务端换 token 超时」这类代理不一致。若仅提供端口代理、系统代理未生效,可设 **`HTTPS_PROXY` / `NO_PROXY`**,见 `deploy/.env.example`。
|
||||
|
||||
### Web JSON API 与会话
|
||||
|
||||
除页面路由使用的 `require_valid_user`(未登录或 `key_version` 与库不一致时重定向 `/login`)外,JSON API(`/api/...`)使用等价校验:会话中的 `key_version` 须与 `users.key_version` 一致,否则返回 **401** JSON,避免仅校验 `user_id` 时与页面行为不一致。
|
||||
|
||||
### Web 条目页表格列(`/entries`)
|
||||
|
||||
列表仅展示非敏感字段;**名称**与**操作**列为固定列(不可在「显示列」中关闭)。**文件夹**(对应 `entries.folder`)、类型、备注、标签、关联、密文等为**可选列**,由用户在「显示列」面板中勾选;可见性保存在浏览器 `localStorage`,键为 **`entries_col_vis`**。新增列会并入默认:若用户曾保存过旧版配置,缺失的列键会按当前默认补齐。**文件夹**列默认**显示**,便于在「全部」等跨 folder 视图下区分条目所属隔离空间。
|
||||
|
||||
筛选栏支持查询参数 **`tags`**(逗号分隔,多标签 **AND**,语义同 `SearchParams.tags` / `tags @> ARRAY[...]`);分页与 folder 标签计数与当前筛选一致。
|
||||
|
||||
### 导出 / 导入文件
|
||||
|
||||
JSON/TOML/YAML 导出可在每条目上包含 `secret_types`(secret 名 → `text` / `password` / `key` 等),导入时写回 `secrets.type`;**旧版导出无该字段**时导入仍成功,类型按 **`text`** 默认。
|
||||
|
||||
### 共享密钥(N:N 关联)
|
||||
|
||||
多个 entry 可共享同一 secret 字段,通过 `entry_secrets` 中间表关联。
|
||||
添加条目时通过 `link_secret_names` 参数指定要关联的已有 secret name(按 `(user_id, name)` 精确匹配)。
|
||||
删除 entry 时仅解除关联,secret 本身若仍被引用则保留;不再被任何 entry 引用时自动清理。
|
||||
|
||||
## 代码规范
|
||||
|
||||
- 错误:业务层 `anyhow::Result`,避免生产路径 `unwrap()`。
|
||||
- 异步:`tokio` + `sqlx` async。
|
||||
- SQL:`sqlx::query` / `query_as` 参数绑定;动态 WHERE 仍须用占位符绑定。
|
||||
- 日志:运维用 `tracing`;面向用户的 Web 响应走 axum handler。tracing 字段风格:变量名即字段名时用简写(`%var`、`?var`、`var`),否则用显式形式(`field = %expr`)。
|
||||
- 审计:写操作成功后尽量 `audit::log_tx`;失败可 `warn`,不掩盖主错误。
|
||||
- 加密:密钥由用户密码短语通过 **PBKDF2-SHA256(600k 次)** 在客户端派生,服务端只存 `key_salt`/`key_check`/`key_params`,不持有原始密钥。Web 客户端在浏览器本地完成加解密;MCP 客户端通过 `X-Encryption-Key` 请求头传递密钥,服务端临时解密后返回明文。
|
||||
- MCP:tools 参数与 JSON Schema(`schemars`)保持同步,鉴权以请求扩展中的用户上下文为准。
|
||||
|
||||
## 生产 CORS
|
||||
|
||||
生产环境 CORS 使用显式请求头白名单(`build_cors_layer`),而非 `allow_headers(Any)`,
|
||||
因为 `tower-http` 禁止 `allow_credentials(true)` 与 `allow_headers(Any)` 同时使用。
|
||||
|
||||
**维护约束**:若 MCP 协议或客户端新增自定义请求头,必须同步更新 `production_allowed_headers()`。
|
||||
当前允许的请求头:`Authorization`、`Content-Type`、`X-Encryption-Key`、`mcp-session-id`、`x-mcp-session`。
|
||||
- 本仓库为纯 `jj` 模式,本地不要使用 `git` 命令。
|
||||
- CI Runner 侧仍可能使用 `git` 拉代码,这不影响本地开发。
|
||||
- 检查 tag 是否存在时,使用 `jj log --no-graph --revisions "tag(${tag})"`。
|
||||
|
||||
## 提交前检查
|
||||
|
||||
```bash
|
||||
./scripts/release-check.sh
|
||||
```
|
||||
|
||||
或手动:
|
||||
每次提交前至少运行:
|
||||
|
||||
```bash
|
||||
cargo fmt -- --check
|
||||
@@ -226,41 +45,197 @@ cargo clippy --locked -- -D warnings
|
||||
cargo test --locked
|
||||
```
|
||||
|
||||
发版前确认未重复 tag:
|
||||
也可以直接运行:
|
||||
|
||||
```bash
|
||||
grep '^version' crates/secrets-mcp/Cargo.toml
|
||||
jj tag list
|
||||
./scripts/release-check.sh
|
||||
```
|
||||
|
||||
## CI/CD
|
||||
## 项目结构
|
||||
|
||||
- **触发**:任意分支 `push`,且路径含 `crates/**`、`deploy/**`、根目录 `Cargo.toml`、`Cargo.lock`、`.gitea/workflows/**`(见 `.gitea/workflows/secrets.yml`)。
|
||||
- **版本与 tag**:从 `crates/secrets-mcp/Cargo.toml` 读版本;构建成功后打 `secrets-mcp-<version>`:若远端已存在同名 tag,CI 会先删后于**当前提交**重建并推送(覆盖式发版)。
|
||||
- **质量与构建**:`fmt` / `clippy --locked` / `test --locked` → `x86_64-unknown-linux-musl` 发布构建 `secrets-mcp`。
|
||||
- **Release(可选)**:`secrets.RELEASE_TOKEN`(Gitea PAT)用于通过 API **创建或更新**该 tag 的 Release(非 draft)、上传 `tar.gz` + `.sha256`;未配置则跳过 API Release,仅 tag + 构建。
|
||||
- **部署(可选)**:仅 `main`、`feat/mcp`、`mcp` 分支在构建成功时跑 `deploy-mcp`;需 `vars.DEPLOY_HOST`、`vars.DEPLOY_USER`、`secrets.DEPLOY_SSH_KEY`。勿把 OAuth/DB 等写进 workflow,用 `deploy/.env.example` 在目标机配置。
|
||||
- **Secrets 写法**:Actions **secrets 须为原始值**(PEM、PAT 明文),**勿** base64;否则 SSH/Release 会失败。**勿**在 CI 中保存 `GOOGLE_CLIENT_SECRET`、DB 密码。
|
||||
- **通知**:`vars.WEBHOOK_URL`(可选,飞书)。
|
||||
```text
|
||||
secrets/
|
||||
Cargo.toml
|
||||
apps/
|
||||
api/ # 远端 JSON API
|
||||
desktop/src-tauri/ # 桌面端
|
||||
crates/
|
||||
application/ # v3 应用服务
|
||||
client-integrations/ # Cursor / Claude Code 配置注入
|
||||
crypto/ # 通用加密辅助
|
||||
desktop-daemon/ # 本地 MCP daemon
|
||||
device-auth/ # 设备登录 / Desktop OAuth 辅助
|
||||
domain/ # v3 领域模型
|
||||
infrastructure-db/ # 数据库与迁移
|
||||
deploy/
|
||||
scripts/
|
||||
.gitea/workflows/
|
||||
.vscode/tasks.json
|
||||
```
|
||||
|
||||
## 环境变量(secrets-mcp)
|
||||
## 数据库
|
||||
|
||||
| 变量 | 说明 |
|
||||
|------|------|
|
||||
| `SECRETS_DATABASE_URL` | **必填**。PostgreSQL URL。 |
|
||||
| `SECRETS_DATABASE_SSL_MODE` | 可选但强烈建议生产必填。推荐 `verify-full`(至少 `verify-ca`)。 |
|
||||
| `SECRETS_DATABASE_SSL_ROOT_CERT` | 可选。私有 CA 或自签链路时指定 CA 根证书路径。 |
|
||||
| `SECRETS_DATABASE_POOL_SIZE` | 可选。连接池最大连接数,默认 `10`。 |
|
||||
| `SECRETS_DATABASE_ACQUIRE_TIMEOUT` | 可选。获取连接超时秒数,默认 `5`。 |
|
||||
| `SECRETS_ENV` | 可选。设为 `prod` / `production` 时会拒绝弱 PostgreSQL TLS 模式。 |
|
||||
| `BASE_URL` | 对外基址;OAuth 回调 `${BASE_URL}/auth/google/callback`。 |
|
||||
| `SECRETS_MCP_BIND` | 监听地址,默认 `127.0.0.1:9315`(容器/远程直接暴露时需改为 `0.0.0.0:9315`)。 |
|
||||
| `GOOGLE_CLIENT_ID` / `GOOGLE_CLIENT_SECRET` | 可选;仅运行时配置。 |
|
||||
| `RUST_LOG` | 如 `secrets_mcp=debug`。 |
|
||||
| `RATE_LIMIT_GLOBAL_PER_SECOND` | 可选。全局限流速率,默认 `100` req/s。 |
|
||||
| `RATE_LIMIT_GLOBAL_BURST` | 可选。全局限流突发量,默认 `200`。 |
|
||||
| `RATE_LIMIT_IP_PER_SECOND` | 可选。单 IP 限流速率,默认 `20` req/s。 |
|
||||
| `RATE_LIMIT_IP_BURST` | 可选。单 IP 限流突发量,默认 `40`。 |
|
||||
| `TRUST_PROXY` | 可选。设为 `1`/`true`/`yes` 时从 `X-Forwarded-For` / `X-Real-IP` 提取客户端 IP。 |
|
||||
- 建议数据库名:`secrets-v3`
|
||||
- 连接串:`SECRETS_DATABASE_URL`
|
||||
- 首次连接会自动运行 `secrets-infrastructure-db::migrate_current_schema`
|
||||
|
||||
> `SERVER_MASTER_KEY` 已不再需要。新架构下密钥由用户密码短语在客户端派生,服务端不持有。
|
||||
当前 v3 主要表:
|
||||
|
||||
- `users`
|
||||
- `oauth_accounts`
|
||||
- `devices`
|
||||
- `device_login_tokens`
|
||||
- `auth_events`
|
||||
- `vault_objects`
|
||||
- `vault_object_revisions`
|
||||
|
||||
### 当前模型约束
|
||||
|
||||
- 服务端只保存同步所需的密文对象与版本信息
|
||||
- 搜索、详情、reveal、history 主要在 desktop 本地 vault 中完成
|
||||
- 删除通过对象级 `deleted_at` / tombstone 传播
|
||||
- 历史服务端保留在 `vault_object_revisions`,本地另有 `vault_object_history`
|
||||
|
||||
### 字段职责
|
||||
|
||||
| 字段 | 含义 | 示例 |
|
||||
|------|------|------|
|
||||
| `object_id` | 同步对象标识 | `UUID` |
|
||||
| `object_kind` | 当前对象类别 | `cipher` |
|
||||
| `revision` | 对象版本号 | `12` |
|
||||
| `cipher_version` | 密文封装版本 | `1` |
|
||||
| `ciphertext` | 密文对象载荷 | AES-GCM 密文 |
|
||||
| `content_hash` | 密文内容摘要 | `sha256:...` |
|
||||
| `deleted_at` | 对象删除时间 | `2026-04-14T12:00:00Z` |
|
||||
|
||||
## Google 登录
|
||||
|
||||
当前登录流为 **Google Desktop OAuth**:
|
||||
|
||||
- 桌面端使用系统浏览器拉起 Google 授权
|
||||
- 使用本地 loopback callback
|
||||
- 使用 `PKCE`
|
||||
- 桌面端换取 Google token 后调用 API 的桌面登录接口
|
||||
- API 校验 Google userinfo 后发放本地 device token
|
||||
|
||||
桌面端优先读取:
|
||||
|
||||
- `GOOGLE_OAUTH_CLIENT_FILE`
|
||||
|
||||
默认开发文件名:
|
||||
|
||||
- `client_secret_738964258008-0svfo4g7ta347iedrf6r9see87a8u3hn.apps.googleusercontent.com.json`
|
||||
|
||||
## MCP
|
||||
|
||||
本地 MCP 入口由 `crates/desktop-daemon` 提供,默认地址:
|
||||
|
||||
```text
|
||||
http://127.0.0.1:9515/mcp
|
||||
```
|
||||
|
||||
当前暴露的工具:
|
||||
|
||||
- `secrets_entry_find`
|
||||
- `secrets_entry_get`
|
||||
- `secrets_entry_add`
|
||||
- `secrets_entry_update`
|
||||
- `secrets_entry_delete`
|
||||
- `secrets_entry_restore`
|
||||
- `secrets_secret_add`
|
||||
- `secrets_secret_update`
|
||||
- `secrets_secret_delete`
|
||||
- `secrets_secret_history`
|
||||
- `secrets_secret_rollback`
|
||||
- `target_exec`
|
||||
|
||||
当前不保留:
|
||||
|
||||
- `secrets_env_map`
|
||||
|
||||
兼容别名:
|
||||
|
||||
- `secrets_find`
|
||||
- `secrets_add`
|
||||
- `secrets_update`
|
||||
|
||||
### `target_exec`
|
||||
|
||||
`target_exec` 会显式读取 entry 当前 secrets 的真实值,并从 metadata / secrets 派生标准环境变量,例如:
|
||||
|
||||
- `TARGET_ENTRY_ID`
|
||||
- `TARGET_NAME`
|
||||
- `TARGET_FOLDER`
|
||||
- `TARGET_TYPE`
|
||||
- `TARGET_HOST`
|
||||
- `TARGET_PORT`
|
||||
- `TARGET_USER`
|
||||
- `TARGET_BASE_URL`
|
||||
- `TARGET_API_KEY`
|
||||
- `TARGET_TOKEN`
|
||||
- `TARGET_SSH_KEY`
|
||||
|
||||
## 桌面端
|
||||
|
||||
桌面端当前支持:
|
||||
|
||||
- Google 登录
|
||||
- 自动写入 `Cursor` / `Claude Code` 的 `mcp.json`
|
||||
- 新建条目
|
||||
- 搜索、按 type 筛选
|
||||
- 右侧原地编辑
|
||||
- secret 新增、编辑、删除
|
||||
- secret 明文显示 / 复制
|
||||
- secret 历史查看与回滚
|
||||
- 删除到最近删除与恢复
|
||||
- 登录态仅在当前 desktop 进程内有效,不做自动恢复登录
|
||||
- desktop 进程退出后,本地 daemon 所有工具不可用
|
||||
|
||||
### 配置注入
|
||||
|
||||
桌面端会把本地 daemon 配置写入:
|
||||
|
||||
- `~/.cursor/mcp.json`
|
||||
- `~/.claude/mcp.json`
|
||||
|
||||
写入策略:
|
||||
|
||||
- 保留现有其它 `mcpServers`
|
||||
- 仅覆盖同名 `secrets` 节点
|
||||
|
||||
### 图标与前端 dist(本地 / CI)
|
||||
|
||||
版本库为减小噪音,**不提交** Tauri 生成的多尺寸图标包,以及 **`apps/desktop/dist/`** 前端打包目录(见根目录 `.gitignore`)。
|
||||
|
||||
- **图标**:仅跟踪 `apps/desktop/src-tauri/icons/icon.png` 作为源图(建议 **1024×1024** PNG)。检出代码后,若需要完整 `icons/`(例如打包、验证窗口/托盘图标),在 **`apps/desktop/src-tauri`** 下执行:
|
||||
|
||||
```bash
|
||||
cd apps/desktop/src-tauri
|
||||
cargo tauri icon icons/icon.png
|
||||
```
|
||||
|
||||
需已安装 **Tauri CLI**(例如 `cargo install tauri-cli`,或与项目一致的 `cargo-tauri` 版本)。
|
||||
|
||||
- **前端 dist**:`tauri.conf.json` 中 `build.frontendDist` 指向 `../dist`。本地或 CI 在运行 `cargo tauri dev` / `cargo tauri build` 前,需先按项目约定生成或同步 **`apps/desktop/dist/`** 内容;流水线构建桌面端时,在 Tauri 步骤之前加入对应的前端产物步骤即可。
|
||||
|
||||
## 代码规范
|
||||
|
||||
- 业务层优先使用 `anyhow::Result`
|
||||
- 避免生产路径 `unwrap()`
|
||||
- 使用 `tokio` + `sqlx` async
|
||||
- SQL 使用参数绑定,不要手拼用户输入
|
||||
- 运维日志使用 `tracing`
|
||||
- 变更后优先跑最小必要验证,不要只改不测
|
||||
|
||||
## CI / 脚本
|
||||
|
||||
- `.gitea/workflows/secrets.yml` 现在是 v3 workspace 级 CI
|
||||
- `scripts/release-check.sh` 只做 workspace 质量检查
|
||||
- `deploy/.env.example` 反映当前 v3 API / daemon / desktop 登录配置
|
||||
|
||||
## 安全约束
|
||||
|
||||
- 不要把 Google `client_secret` 提交到受版本控制的配置文件中
|
||||
- 不要把 device token、数据库密码、真实生产密钥提交入库
|
||||
- 数据库生产环境优先使用 `verify-full`
|
||||
- AI 审查时,不要把“随机高熵 token 明文存储”机械地当成密码学问题处理,必须结合当前架构和威胁模型判断
|
||||
|
||||
Reference in New Issue
Block a user