fix: inject/run 仅注入 secrets 字段,不含 metadata
Some checks failed
Secrets CLI - Build & Release / 版本 & Release (push) Successful in 3s
Secrets CLI - Build & Release / 质量检查 (fmt / clippy / test) (push) Successful in 2m36s
Secrets CLI - Build & Release / Build (macOS aarch64 + x86_64) (push) Successful in 1m3s
Secrets CLI - Build & Release / Build (x86_64-unknown-linux-musl) (push) Successful in 1m15s
Secrets CLI - Build & Release / 发布草稿 Release (push) Has been cancelled
Secrets CLI - Build & Release / Build (x86_64-pc-windows-msvc) (push) Has been cancelled
Some checks failed
Secrets CLI - Build & Release / 版本 & Release (push) Successful in 3s
Secrets CLI - Build & Release / 质量检查 (fmt / clippy / test) (push) Successful in 2m36s
Secrets CLI - Build & Release / Build (macOS aarch64 + x86_64) (push) Successful in 1m3s
Secrets CLI - Build & Release / Build (x86_64-unknown-linux-musl) (push) Successful in 1m15s
Secrets CLI - Build & Release / 发布草稿 Release (push) Has been cancelled
Secrets CLI - Build & Release / Build (x86_64-pc-windows-msvc) (push) Has been cancelled
- build_injected_env_map 不再合并 metadata - 删除 build_metadata_env_map 及其测试 - 更新 README、AGENTS.md 文档 - bump 版本至 0.9.5 Made-with: Cursor
This commit is contained in:
@@ -30,7 +30,7 @@ secrets/
|
||||
update.rs # update 命令:增量更新,secrets 行级 UPSERT/DELETE,CAS 并发保护
|
||||
rollback.rs # rollback 命令:按 entry_version 恢复 entry + secrets
|
||||
history.rs # history 命令:查看 entry 变更历史列表
|
||||
run.rs # inject / run 命令:逐字段解密 + key_ref 引用解析
|
||||
run.rs # inject / run 命令:仅 secrets 逐字段解密 + key_ref 引用解析(不含 metadata)
|
||||
upgrade.rs # upgrade 命令:检查、校验摘要并下载最新版本,自动替换二进制
|
||||
export_cmd.rs # export 命令:批量导出记录,支持 JSON/TOML/YAML,含解密明文
|
||||
import_cmd.rs # import 命令:批量导入记录,冲突检测,dry-run,重新加密写入
|
||||
@@ -440,7 +440,7 @@ secrets rollback -n refining --kind service --name gitea --to-version 3
|
||||
|
||||
### inject — 输出临时环境变量
|
||||
|
||||
敏感值仅打印到 stdout,不持久化、不写入当前 shell。
|
||||
仅注入 secrets 表中的加密字段(解密后),不含 metadata。敏感值仅打印到 stdout,不持久化、不写入当前 shell。
|
||||
|
||||
```bash
|
||||
# 参数说明
|
||||
@@ -451,7 +451,7 @@ secrets rollback -n refining --kind service --name gitea --to-version 3
|
||||
# --prefix 变量名前缀(留空则以记录 name 作前缀)
|
||||
# -o / --output text(默认 KEY=VALUE)| json | json-compact
|
||||
|
||||
# 打印单条记录的所有变量(KEY=VALUE 格式)
|
||||
# 打印单条记录的 secrets 变量(KEY=VALUE 格式)
|
||||
secrets inject -n refining --kind service --name gitea
|
||||
|
||||
# 自定义前缀
|
||||
@@ -468,7 +468,7 @@ eval $(secrets inject -n refining --kind service --name gitea)
|
||||
|
||||
### run — 向子进程注入 secrets 并执行命令
|
||||
|
||||
secrets 仅作用于子进程环境,不修改当前 shell,进程退出码透传。
|
||||
仅注入 secrets 表中的加密字段(解密后),不含 metadata。secrets 仅作用于子进程环境,不修改当前 shell,进程退出码透传。
|
||||
|
||||
```bash
|
||||
# 参数说明
|
||||
|
||||
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -1836,7 +1836,7 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "secrets"
|
||||
version = "0.9.4"
|
||||
version = "0.9.5"
|
||||
dependencies = [
|
||||
"aes-gcm",
|
||||
"anyhow",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "secrets"
|
||||
version = "0.9.4"
|
||||
version = "0.9.5"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -69,7 +69,7 @@ secrets inject -n refining --kind service --name gitea
|
||||
secrets run -n refining --kind service --name gitea -- printenv
|
||||
```
|
||||
|
||||
`search` 展示 metadata 与 secrets 的字段名,不展示 secret 值本身;需要值时用 `inject` / `run`。
|
||||
`search` 展示 metadata 与 secrets 的字段名,不展示 secret 值本身;需要 secret 值时用 `inject` / `run`(仅注入加密字段,不含 metadata)。
|
||||
|
||||
### 输出格式
|
||||
|
||||
@@ -314,7 +314,7 @@ src/
|
||||
delete.rs # 删除(CASCADE 删除 secrets)
|
||||
update.rs # 增量更新(tags/metadata + secrets 行级 UPSERT/DELETE)
|
||||
rollback.rs # rollback / history:按 entry_version 恢复
|
||||
run.rs # inject / run,逐字段解密 + key_ref 引用解析
|
||||
run.rs # inject / run,仅 secrets 逐字段解密 + key_ref 引用解析(不含 metadata)
|
||||
upgrade.rs # 从 Gitea Release 自更新
|
||||
export_cmd.rs # export:批量导出,支持 JSON/TOML/YAML,含解密明文
|
||||
import_cmd.rs # import:批量导入,冲突检测,dry-run,重新加密写入
|
||||
|
||||
@@ -24,7 +24,7 @@ pub struct RunArgs<'a> {
|
||||
pub command: &'a [String],
|
||||
}
|
||||
|
||||
/// Fetch entries matching the filter and build a flat env map (metadata + decrypted secrets).
|
||||
/// Fetch entries matching the filter and build a flat env map (decrypted secrets only, no metadata).
|
||||
pub async fn collect_env_map(
|
||||
pool: &PgPool,
|
||||
namespace: Option<&str>,
|
||||
|
||||
@@ -312,25 +312,7 @@ fn env_prefix(entry: &Entry, prefix: &str) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
/// Build a flat KEY=VALUE map from metadata only (no master key required).
|
||||
pub fn build_metadata_env_map(entry: &Entry, prefix: &str) -> HashMap<String, String> {
|
||||
let effective_prefix = env_prefix(entry, prefix);
|
||||
let mut map = HashMap::new();
|
||||
|
||||
if let Some(meta) = entry.metadata.as_object() {
|
||||
for (k, v) in meta {
|
||||
let key = format!(
|
||||
"{}_{}",
|
||||
effective_prefix,
|
||||
k.to_uppercase().replace(['-', '.'], "_")
|
||||
);
|
||||
map.insert(key, json_value_to_env_string(v));
|
||||
}
|
||||
}
|
||||
map
|
||||
}
|
||||
|
||||
/// Build a flat KEY=VALUE map from metadata + decrypted secret fields.
|
||||
/// Build a flat KEY=VALUE map from decrypted secret fields only.
|
||||
/// Resolves key_ref: if metadata.key_ref is set, merges secret fields from that key entry.
|
||||
pub async fn build_injected_env_map(
|
||||
pool: &PgPool,
|
||||
@@ -340,7 +322,7 @@ pub async fn build_injected_env_map(
|
||||
fields: &[SecretField],
|
||||
) -> Result<HashMap<String, String>> {
|
||||
let effective_prefix = env_prefix(entry, prefix);
|
||||
let mut map = build_metadata_env_map(entry, prefix);
|
||||
let mut map = HashMap::new();
|
||||
|
||||
// Decrypt each secret field and add to env map.
|
||||
for f in fields {
|
||||
@@ -565,22 +547,6 @@ mod tests {
|
||||
assert!(err.to_string().contains("sensitive"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn metadata_env_map_excludes_secret_values() {
|
||||
let entry = sample_entry();
|
||||
let map = build_metadata_env_map(&entry, "");
|
||||
|
||||
assert_eq!(
|
||||
map.get("GITEA_MAIN_URL").map(String::as_str),
|
||||
Some("https://code.example.com")
|
||||
);
|
||||
assert_eq!(
|
||||
map.get("GITEA_MAIN_ENABLED").map(String::as_str),
|
||||
Some("true")
|
||||
);
|
||||
assert!(!map.contains_key("GITEA_MAIN_TOKEN"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn to_json_full_includes_secrets_schema() {
|
||||
let entry = sample_entry();
|
||||
|
||||
Reference in New Issue
Block a user