Skip to content

Commit 9a12cf4

Browse files
committed
feat(deps): upgrade cipherstash-client from 0.33.2 to 0.34.0-alpha.4
Adapt proxy to breaking API changes in cipherstash-client 0.34: - Update ZeroKMS client initialization for new builder API - Add authentication strategy detection with AutoStrategy - Use valid UUID placeholders in example config - Add documentation URLs to config validation error messages - Use ZEROKMS log target constant for consistency - Update development docs for new credential requirements
1 parent 5dff022 commit 9a12cf4

File tree

14 files changed

+753
-345
lines changed

14 files changed

+753
-345
lines changed

Cargo.lock

Lines changed: 636 additions & 219 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ debug = true
4343

4444
[workspace.dependencies]
4545
sqltk = { version = "0.10.0" }
46-
cipherstash-client = { version = "0.33.2" }
47-
cts-common = { version = "0.4.1" }
46+
cipherstash-client = { version = "0.34.0-alpha.4" }
47+
cts-common = { version = "0.34.0-alpha.4" }
4848

4949
thiserror = "2.0.9"
5050
tokio = { version = "1.44.2", features = ["full"] }

DEVELOPMENT.md

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -501,29 +501,14 @@ Certificates are generated by `mkcert`, and live in `tests/tls/`.
501501

502502
#### Configuration: development endpoints
503503

504+
ZeroKMS and CTS host endpoints can be configured for local development using environment variables.
504505

505-
ZeroKMS and CTS host endpoints can be configured for local development.
506+
These are read directly by `cipherstash-client` and do not require proxy configuration:
506507

507-
Env variables are `CS_DEVELOPMENT__ZEROKMS_HOST` and `CS_DEVELOPMENT__CTS_HOST`.
508-
509-
510-
```toml
511-
512-
[development]
513-
# ZeroKMS host
514-
# Optional
515-
# Defaults to CipherStash Production ZeroKMS host
516-
# Env: CS_DEVELOPMENT__ZEROKMS_HOST
517-
zerokms_host = "1.1.1.1"
518-
519-
520-
# CTS host
521-
# Optional
522-
# Defaults to CipherStash Production CTS host
523-
# Env: CS_DEVELOPMENT__CTS_HOST
524-
cts_host = "1.1.1.1"
525-
526-
```
508+
| Variable | Description |
509+
|---|---|
510+
| `CS_ZEROKMS_HOST` | Override ZeroKMS endpoint (default: resolved from JWT `services` claim) |
511+
| `CS_CTS_HOST` | Override CTS auth endpoint (default: resolved from workspace CRN region) |
527512

528513

529514

cipherstash-proxy-example.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@ workspace_crn = "workspace_crn"
2424
client_access_key = "client_access_key"
2525

2626
[encrypt]
27-
default_keyset_id = "default_keyset_id"
28-
client_id = "client_id"
27+
default_keyset_id = "00000000-0000-0000-0000-000000000000"
28+
client_id = "00000000-0000-0000-0000-000000000000"
2929
client_key = "client_key"

docker-compose.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ services:
4343
- CS_PROMETHEUS__ENABLED=${CS_PROMETHEUS__ENABLED:-true}
4444
- CS_DATABASE__INSTALL_EQL=true # install EQL into the PostgreSQL database
4545
- CS_DATABASE__INSTALL_EXAMPLE_SCHEMA=true # install example schema into the PostgreSQL database
46+
- CS_CTS_HOST=${CS_CTS_HOST:-}
47+
- CS_ZEROKMS_HOST=${CS_ZEROKMS_HOST:-}
4648
networks:
4749
- cipherstash
4850

packages/cipherstash-proxy/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ tokio-util = { version = "0.7.13", features = ["rt"] }
5555
tracing = { workspace = true }
5656
tracing-subscriber = { workspace = true }
5757
uuid = { version = "1.11.0", features = ["serde", "v4"] }
58+
vitaminc-protected = "0.1.0-pre4.2"
5859
x509-parser = "0.17.0"
59-
vitaminc-protected = "0.1.0-pre2"
6060

6161

6262
[dev-dependencies]

packages/cipherstash-proxy/src/config/tandem.rs

Lines changed: 53 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::Args;
99
use cipherstash_client::config::vars::{
1010
CS_CLIENT_ACCESS_KEY, CS_CLIENT_ID, CS_CLIENT_KEY, CS_DEFAULT_KEYSET_ID, CS_WORKSPACE_CRN,
1111
};
12+
use cipherstash_client::zerokms::ClientKey;
1213
use config::{Config, Environment};
1314
use cts_common::Crn;
1415
use regex::Regex;
@@ -42,7 +43,7 @@ pub struct AuthConfig {
4243

4344
#[derive(Debug, Deserialize, Clone, PartialEq)]
4445
pub struct EncryptConfig {
45-
pub client_id: String,
46+
pub client_id: Uuid,
4647
pub client_key: String,
4748
pub default_keyset_id: Option<Uuid>,
4849
}
@@ -66,12 +67,6 @@ pub struct DevelopmentConfig {
6667

6768
#[serde(default)]
6869
pub enable_mapping_errors: bool,
69-
70-
#[serde(default)]
71-
pub zerokms_host: Option<String>,
72-
73-
#[serde(default)]
74-
pub cts_host: Option<String>,
7570
}
7671

7772
/// Config defaults to a file called `tandem` in the current directory.
@@ -191,7 +186,7 @@ impl TandemConfig {
191186
}
192187

193188
// Source order is important!
194-
let config = Config::builder()
189+
let config: TandemConfig = Config::builder()
195190
.add_source(config::File::with_name(&args.config_file_path).required(false))
196191
.add_source(cs_env_source)
197192
.add_source(stash_setup_source)
@@ -203,7 +198,16 @@ impl TandemConfig {
203198
// - missing parameters are returned by at least two different errors, depending the source of the error
204199
// Easier to inspect the error message.
205200
match err.to_string() {
206-
s if s.contains("UUID parsing failed") => ConfigError::InvalidDatasetId,
201+
s if s.contains("UUID parsing failed") => {
202+
if s.contains("client_id") && !s.contains("keyset") {
203+
ConfigError::InvalidParameter {
204+
name: "client_id".to_string(),
205+
value: "invalid UUID".to_string(),
206+
}
207+
} else {
208+
ConfigError::InvalidDefaultKeysetId
209+
}
210+
}
207211
s if s.contains("missing field") => {
208212
let (field, key) = extract_missing_field_and_key(&s);
209213
match (field, key) {
@@ -222,6 +226,8 @@ impl TandemConfig {
222226
}
223227
})?;
224228

229+
config.encrypt.build_client_key()?;
230+
225231
Ok(config)
226232
}
227233

@@ -246,18 +252,6 @@ impl TandemConfig {
246252
}
247253
}
248254

249-
pub fn zerokms_host(&self) -> Option<String> {
250-
self.development
251-
.as_ref()
252-
.and_then(|dev| dev.zerokms_host.clone())
253-
}
254-
255-
pub fn cts_host(&self) -> Option<String> {
256-
self.development
257-
.as_ref()
258-
.and_then(|dev| dev.cts_host.clone())
259-
}
260-
261255
pub fn use_structured_logging(&self) -> bool {
262256
matches!(self.log.format, LogFormat::Structured)
263257
}
@@ -326,8 +320,8 @@ impl TandemConfig {
326320
client_access_key: "test".to_string(),
327321
},
328322
encrypt: EncryptConfig {
329-
client_id: "test".to_string(),
330-
client_key: "test".to_string(),
323+
client_id: Uuid::parse_str("00000000-0000-0000-0000-000000000001").unwrap(),
324+
client_key: "a4627031a16b7065726d75746174696f6e900e05030d0608090007020c04010b0a0f6770325f66726f6da16b7065726d75746174696f6e900608000a0204030f01070d090e0b0c056570325f746fa16b7065726d75746174696f6e90000908060701030a05040e020d0b0c0f627033a16b7065726d75746174696f6e982107181d130d05181f08040a181c1002181e010311181818200b0f0e0915181b0c16171819060012181a14".to_string(),
331325
default_keyset_id: Some(
332326
Uuid::parse_str("00000000-0000-0000-0000-000000000000").unwrap(),
333327
),
@@ -340,6 +334,13 @@ impl TandemConfig {
340334
}
341335
}
342336

337+
impl EncryptConfig {
338+
pub fn build_client_key(&self) -> Result<ClientKey, Error> {
339+
ClientKey::from_hex_v1(self.client_id, &self.client_key)
340+
.map_err(|_| Error::from(ConfigError::InvalidClientKey))
341+
}
342+
}
343+
343344
impl PrometheusConfig {
344345
pub fn default_port() -> u16 {
345346
9930
@@ -426,9 +427,12 @@ mod tests {
426427
temp_env::with_vars(
427428
[
428429
// Orignal recipe ENV var
429-
("CS_ENCRYPT__CLIENT_ID", Some("CS_ENCRYPT__CLIENT_ID")),
430-
(CS_CLIENT_ID, Some("CS_CLIENT_ID")),
431-
(CS_CLIENT_KEY, Some("CS_CLIENT_KEY")),
430+
(
431+
"CS_ENCRYPT__CLIENT_ID",
432+
Some("11111111-1111-1111-1111-111111111111"),
433+
),
434+
(CS_CLIENT_ID, Some("22222222-2222-2222-2222-222222222222")),
435+
(CS_CLIENT_KEY, Some("a4627031a16b7065726d75746174696f6e900e05030d0608090007020c04010b0a0f6770325f66726f6da16b7065726d75746174696f6e900608000a0204030f01070d090e0b0c056570325f746fa16b7065726d75746174696f6e90000908060701030a05040e020d0b0c0f627033a16b7065726d75746174696f6e982107181d130d05181f08040a181c1002181e010311181818200b0f0e0915181b0c16171819060012181a14")),
432436
(
433437
CS_DEFAULT_KEYSET_ID,
434438
Some("dd0a239f-02e2-4c8e-ba20-d9f0f85af9ac"),
@@ -440,7 +444,10 @@ mod tests {
440444
TandemConfig::build_path("tests/config/cipherstash-proxy-test.toml")
441445
.unwrap();
442446

443-
assert_eq!(config.encrypt.client_id, "CS_CLIENT_ID".to_string());
447+
assert_eq!(
448+
config.encrypt.client_id,
449+
Uuid::parse_str("22222222-2222-2222-2222-222222222222").unwrap()
450+
);
444451

445452
assert_eq!(
446453
config.auth.client_access_key,
@@ -474,8 +481,8 @@ mod tests {
474481
.unwrap();
475482

476483
assert_eq!(
477-
&config.encrypt.client_id,
478-
"dd0a239f-02e2-4c8e-ba20-d9f0f85af9ac"
484+
config.encrypt.client_id,
485+
Uuid::parse_str("dd0a239f-02e2-4c8e-ba20-d9f0f85af9ac").unwrap()
479486
);
480487
},
481488
);
@@ -512,6 +519,22 @@ mod tests {
512519
});
513520
}
514521

522+
#[test]
523+
fn invalid_client_id_uuid() {
524+
with_no_cs_vars(|| {
525+
let result =
526+
TandemConfig::build_path("tests/config/cipherstash-proxy-bad-client-id.toml");
527+
assert!(result.is_err());
528+
let err = result.unwrap_err();
529+
// Should produce InvalidParameter for client_id, not InvalidDatasetId
530+
assert!(
531+
err.to_string().contains("Invalid client_id"),
532+
"Expected 'Invalid client_id' but got: {}",
533+
err
534+
);
535+
});
536+
}
537+
515538
#[test]
516539
fn prometheus_config() {
517540
with_no_cs_vars(|| {
@@ -584,7 +607,7 @@ mod tests {
584607
fn default_env_vars() -> Vec<(&'static str, Option<&'static str>)> {
585608
vec![
586609
("CS_CLIENT_ID", Some("00000000-0000-0000-0000-000000000000")),
587-
("CS_CLIENT_KEY", Some("CS_CLIENT_KEY")),
610+
("CS_CLIENT_KEY", Some("a4627031a16b7065726d75746174696f6e900e05030d0608090007020c04010b0a0f6770325f66726f6da16b7065726d75746174696f6e900608000a0204030f01070d090e0b0c056570325f746fa16b7065726d75746174696f6e90000908060701030a05040e020d0b0c0f627033a16b7065726d75746174696f6e982107181d130d05181f08040a181c1002181e010311181818200b0f0e0915181b0c16171819060012181a14")),
588611
(
589612
"CS_DEFAULT_KEYSET_ID",
590613
Some("00000000-0000-0000-0000-000000000000"),

packages/cipherstash-proxy/src/error.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@ pub enum Error {
1515
#[error("Connection closed after cancel request")]
1616
CancelRequest,
1717

18-
#[error(transparent)]
19-
Client(#[from] cipherstash_client::config::errors::ConfigError),
20-
2118
#[error(transparent)]
2219
Config(#[from] ConfigError),
2320

@@ -72,6 +69,9 @@ pub enum ZeroKMSError {
7269
#[error("ZeroKMS authentication failed. Check the configured credentials. For help visit {}#zerokms-authentication-failed", ERROR_DOC_BASE_URL)]
7370
AuthenticationFailed,
7471

72+
#[error(transparent)]
73+
Builder(#[from] cipherstash_client::zerokms::ZeroKMSBuilderError),
74+
7575
#[error(transparent)]
7676
System(#[from] cipherstash_client::zerokms::Error),
7777
}
@@ -116,17 +116,20 @@ pub enum ConfigError {
116116
#[error(transparent)]
117117
Certificate(#[from] rustls_pki_types::pem::Error),
118118

119-
#[error(transparent)]
120-
EncryptConfig(#[from] cipherstash_client::config::errors::ConfigError),
121-
122119
#[error(transparent)]
123120
Database(#[from] tokio_postgres::Error),
124121

125122
#[error(transparent)]
126123
FileOrEnvironment(#[from] config::ConfigError),
127124

128-
#[error("Dataset id is not a valid UUID.")]
129-
InvalidDatasetId,
125+
#[error("Client key is not valid. For help visit {}", ERROR_DOC_CONFIG_URL)]
126+
InvalidClientKey,
127+
128+
#[error(
129+
"default_keyset_id is not a valid UUID. For help visit {}",
130+
ERROR_DOC_CONFIG_URL
131+
)]
132+
InvalidDefaultKeysetId,
130133

131134
#[error("Server host {name} is not a valid server name")]
132135
InvalidServerName { name: String },
@@ -436,6 +439,12 @@ impl From<config::ConfigError> for Error {
436439
}
437440
}
438441

442+
impl From<cipherstash_client::zerokms::ZeroKMSBuilderError> for Error {
443+
fn from(e: cipherstash_client::zerokms::ZeroKMSBuilderError) -> Self {
444+
Error::ZeroKMS(e.into())
445+
}
446+
}
447+
439448
impl From<cipherstash_client::encryption::TypeParseError> for Error {
440449
fn from(e: cipherstash_client::encryption::TypeParseError) -> Self {
441450
Error::Encrypt(e.into())

packages/cipherstash-proxy/src/proxy/mod.rs

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,10 @@ pub trait EncryptionService: Send + Sync {
168168

169169
#[cfg(test)]
170170
mod tests {
171-
use super::*;
172171
use crate::config::TandemConfig;
173172
use crate::test_helpers::with_no_cs_vars;
174-
use cts_common::WorkspaceId;
173+
174+
use super::zerokms;
175175

176176
fn build_tandem_config(env: Vec<(&str, Option<&str>)>) -> TandemConfig {
177177
with_no_cs_vars(|| {
@@ -195,28 +195,23 @@ mod tests {
195195
}
196196

197197
#[test]
198-
fn build_zerokms_config_with_crn() {
198+
fn init_zerokms_client_with_crn() {
199199
with_no_cs_vars(|| {
200200
let mut env = default_env_vars();
201-
env.push(("CS_CLIENT_ACCESS_KEY", Some("client-access-key")));
201+
env.push(("CS_CLIENT_ACCESS_KEY", Some("CSAKtestKeyId.testKeySecret")));
202202
env.push((
203203
"CS_WORKSPACE_CRN",
204204
Some("crn:ap-southeast-2.aws:3KISDURL3ZCWYZ2O"),
205205
));
206206

207207
let tandem_config = build_tandem_config(env);
208208

209-
let zerokms_config = zerokms::build_zerokms_config(&tandem_config).unwrap();
210-
211-
assert_eq!(
212-
WorkspaceId::try_from("3KISDURL3ZCWYZ2O").unwrap(),
213-
zerokms_config.workspace_id()
209+
let result = zerokms::init_zerokms_client(&tandem_config);
210+
assert!(
211+
result.is_ok(),
212+
"init_zerokms_client failed: {:?}",
213+
result.err()
214214
);
215-
216-
assert!(zerokms_config
217-
.base_url()
218-
.to_string()
219-
.contains("ap-southeast-2.aws"));
220215
});
221216
}
222217
}

0 commit comments

Comments
 (0)