Skip to content

Commit 32a5e2c

Browse files
committed
fix(server): preserve credential key names in redacted provider responses
redact_provider_credentials used HashMap::clear() which removed both keys and values, causing provider list/get to report 0 credential keys. Replace with value-only redaction so key names and counts are preserved while secret values remain hidden. Refs: #350
1 parent f37b69b commit 32a5e2c

File tree

1 file changed

+30
-12
lines changed

1 file changed

+30
-12
lines changed

crates/openshell-server/src/grpc.rs

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3997,11 +3997,14 @@ fn hmac_sha256(key: &[u8], data: &[u8]) -> String {
39973997
// Provider CRUD
39983998
// ---------------------------------------------------------------------------
39993999

4000-
/// Strip credential values from a provider before returning it in a gRPC
4001-
/// response. Internal server paths (inference routing, sandbox env injection)
4002-
/// read credentials from the store directly and are unaffected.
4000+
/// Redact credential values from a provider before returning it in a gRPC
4001+
/// response. Key names are preserved so callers can display credential counts
4002+
/// and key listings. Internal server paths (inference routing, sandbox env
4003+
/// injection) read credentials from the store directly and are unaffected.
40034004
fn redact_provider_credentials(mut provider: Provider) -> Provider {
4004-
provider.credentials.clear();
4005+
for value in provider.credentials.values_mut() {
4006+
*value = "REDACTED".to_string();
4007+
}
40054008
provider
40064009
}
40074010

@@ -4472,10 +4475,16 @@ mod tests {
44724475
.await
44734476
.unwrap();
44744477
assert_eq!(updated.id, provider_id);
4475-
// Credentials are redacted in responses.
4476-
assert!(
4477-
updated.credentials.is_empty(),
4478-
"credentials must be redacted in gRPC responses"
4478+
// Credential keys are preserved but values are redacted in responses.
4479+
assert_eq!(updated.credentials.len(), 2);
4480+
assert_eq!(
4481+
updated.credentials.get("API_TOKEN"),
4482+
Some(&"REDACTED".to_string()),
4483+
"credential values must be redacted in gRPC responses"
4484+
);
4485+
assert_eq!(
4486+
updated.credentials.get("SECONDARY"),
4487+
Some(&"REDACTED".to_string()),
44794488
);
44804489
// Verify the store still has full credentials.
44814490
let stored: Provider = store
@@ -4581,8 +4590,12 @@ mod tests {
45814590

45824591
assert_eq!(updated.id, persisted.id);
45834592
assert_eq!(updated.r#type, "nvidia");
4584-
// Credentials are redacted in responses.
4585-
assert!(updated.credentials.is_empty());
4593+
// Credential keys are preserved but values are redacted in responses.
4594+
assert_eq!(updated.credentials.len(), 2);
4595+
assert_eq!(
4596+
updated.credentials.get("API_TOKEN"),
4597+
Some(&"REDACTED".to_string())
4598+
);
45864599
assert_eq!(updated.config.len(), 2);
45874600
assert_eq!(
45884601
updated.config.get("endpoint"),
@@ -4621,8 +4634,13 @@ mod tests {
46214634
.await
46224635
.unwrap();
46234636

4624-
// Credentials are redacted in responses.
4625-
assert!(updated.credentials.is_empty());
4637+
// Credential keys are preserved but values are redacted; SECONDARY was deleted.
4638+
assert_eq!(updated.credentials.len(), 1);
4639+
assert_eq!(
4640+
updated.credentials.get("API_TOKEN"),
4641+
Some(&"REDACTED".to_string())
4642+
);
4643+
assert!(updated.credentials.get("SECONDARY").is_none());
46264644
assert_eq!(updated.config.len(), 1);
46274645
assert_eq!(
46284646
updated.config.get("endpoint"),

0 commit comments

Comments
 (0)