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 并发保护
|
update.rs # update 命令:增量更新,secrets 行级 UPSERT/DELETE,CAS 并发保护
|
||||||
rollback.rs # rollback 命令:按 entry_version 恢复 entry + secrets
|
rollback.rs # rollback 命令:按 entry_version 恢复 entry + secrets
|
||||||
history.rs # history 命令:查看 entry 变更历史列表
|
history.rs # history 命令:查看 entry 变更历史列表
|
||||||
run.rs # inject / run 命令:逐字段解密 + key_ref 引用解析
|
run.rs # inject / run 命令:仅 secrets 逐字段解密 + key_ref 引用解析(不含 metadata)
|
||||||
upgrade.rs # upgrade 命令:检查、校验摘要并下载最新版本,自动替换二进制
|
upgrade.rs # upgrade 命令:检查、校验摘要并下载最新版本,自动替换二进制
|
||||||
export_cmd.rs # export 命令:批量导出记录,支持 JSON/TOML/YAML,含解密明文
|
export_cmd.rs # export 命令:批量导出记录,支持 JSON/TOML/YAML,含解密明文
|
||||||
import_cmd.rs # import 命令:批量导入记录,冲突检测,dry-run,重新加密写入
|
import_cmd.rs # import 命令:批量导入记录,冲突检测,dry-run,重新加密写入
|
||||||
@@ -440,7 +440,7 @@ secrets rollback -n refining --kind service --name gitea --to-version 3
|
|||||||
|
|
||||||
### inject — 输出临时环境变量
|
### inject — 输出临时环境变量
|
||||||
|
|
||||||
敏感值仅打印到 stdout,不持久化、不写入当前 shell。
|
仅注入 secrets 表中的加密字段(解密后),不含 metadata。敏感值仅打印到 stdout,不持久化、不写入当前 shell。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 参数说明
|
# 参数说明
|
||||||
@@ -451,7 +451,7 @@ secrets rollback -n refining --kind service --name gitea --to-version 3
|
|||||||
# --prefix 变量名前缀(留空则以记录 name 作前缀)
|
# --prefix 变量名前缀(留空则以记录 name 作前缀)
|
||||||
# -o / --output text(默认 KEY=VALUE)| json | json-compact
|
# -o / --output text(默认 KEY=VALUE)| json | json-compact
|
||||||
|
|
||||||
# 打印单条记录的所有变量(KEY=VALUE 格式)
|
# 打印单条记录的 secrets 变量(KEY=VALUE 格式)
|
||||||
secrets inject -n refining --kind service --name gitea
|
secrets inject -n refining --kind service --name gitea
|
||||||
|
|
||||||
# 自定义前缀
|
# 自定义前缀
|
||||||
@@ -468,7 +468,7 @@ eval $(secrets inject -n refining --kind service --name gitea)
|
|||||||
|
|
||||||
### run — 向子进程注入 secrets 并执行命令
|
### run — 向子进程注入 secrets 并执行命令
|
||||||
|
|
||||||
secrets 仅作用于子进程环境,不修改当前 shell,进程退出码透传。
|
仅注入 secrets 表中的加密字段(解密后),不含 metadata。secrets 仅作用于子进程环境,不修改当前 shell,进程退出码透传。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 参数说明
|
# 参数说明
|
||||||
|
|||||||
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -1836,7 +1836,7 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "secrets"
|
name = "secrets"
|
||||||
version = "0.9.4"
|
version = "0.9.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes-gcm",
|
"aes-gcm",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "secrets"
|
name = "secrets"
|
||||||
version = "0.9.4"
|
version = "0.9.5"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ secrets inject -n refining --kind service --name gitea
|
|||||||
secrets run -n refining --kind service --name gitea -- printenv
|
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)
|
delete.rs # 删除(CASCADE 删除 secrets)
|
||||||
update.rs # 增量更新(tags/metadata + secrets 行级 UPSERT/DELETE)
|
update.rs # 增量更新(tags/metadata + secrets 行级 UPSERT/DELETE)
|
||||||
rollback.rs # rollback / history:按 entry_version 恢复
|
rollback.rs # rollback / history:按 entry_version 恢复
|
||||||
run.rs # inject / run,逐字段解密 + key_ref 引用解析
|
run.rs # inject / run,仅 secrets 逐字段解密 + key_ref 引用解析(不含 metadata)
|
||||||
upgrade.rs # 从 Gitea Release 自更新
|
upgrade.rs # 从 Gitea Release 自更新
|
||||||
export_cmd.rs # export:批量导出,支持 JSON/TOML/YAML,含解密明文
|
export_cmd.rs # export:批量导出,支持 JSON/TOML/YAML,含解密明文
|
||||||
import_cmd.rs # import:批量导入,冲突检测,dry-run,重新加密写入
|
import_cmd.rs # import:批量导入,冲突检测,dry-run,重新加密写入
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ pub struct RunArgs<'a> {
|
|||||||
pub command: &'a [String],
|
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(
|
pub async fn collect_env_map(
|
||||||
pool: &PgPool,
|
pool: &PgPool,
|
||||||
namespace: Option<&str>,
|
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).
|
/// Build a flat KEY=VALUE map from decrypted secret fields only.
|
||||||
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.
|
|
||||||
/// Resolves key_ref: if metadata.key_ref is set, merges secret fields from that key entry.
|
/// Resolves key_ref: if metadata.key_ref is set, merges secret fields from that key entry.
|
||||||
pub async fn build_injected_env_map(
|
pub async fn build_injected_env_map(
|
||||||
pool: &PgPool,
|
pool: &PgPool,
|
||||||
@@ -340,7 +322,7 @@ pub async fn build_injected_env_map(
|
|||||||
fields: &[SecretField],
|
fields: &[SecretField],
|
||||||
) -> Result<HashMap<String, String>> {
|
) -> Result<HashMap<String, String>> {
|
||||||
let effective_prefix = env_prefix(entry, prefix);
|
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.
|
// Decrypt each secret field and add to env map.
|
||||||
for f in fields {
|
for f in fields {
|
||||||
@@ -565,22 +547,6 @@ mod tests {
|
|||||||
assert!(err.to_string().contains("sensitive"));
|
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]
|
#[test]
|
||||||
fn to_json_full_includes_secrets_schema() {
|
fn to_json_full_includes_secrets_schema() {
|
||||||
let entry = sample_entry();
|
let entry = sample_entry();
|
||||||
|
|||||||
Reference in New Issue
Block a user