Skip to content

Commit

Permalink
Add support for mTLS
Browse files Browse the repository at this point in the history
There is a need to secure the Action Cache for production builds which is
not possible with out authentication of the store.  This can be provided
by mTLS and the ability to make the action cache read only for some servers.
  • Loading branch information
chrisstaite-menlo committed Dec 12, 2023
1 parent 2259251 commit 3b83cfe
Show file tree
Hide file tree
Showing 19 changed files with 742 additions and 84 deletions.
392 changes: 384 additions & 8 deletions Cargo.Bazel.lock

Large diffs are not rendered by default.

81 changes: 75 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ rustls-pemfile = "1.0.4"
scopeguard = "1.2.0"
serde_json5 = "0.1.0"
tokio = { version = "1.34.0", features = ["rt-multi-thread", "signal"] }
tokio-rustls = "0.24.1"
tonic = { version = "0.9.2", features = ["gzip"] }
tokio-rustls = "0.25.0"
tonic = { version = "0.9.2", features = ["gzip", "tls"] }
tower = "0.4.13"
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
2 changes: 2 additions & 0 deletions nativelink-config/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ rust_library(
],
visibility = ["//visibility:public"],
deps = [
"//error",
"@crate_index//:serde",
"@crate_index//:shellexpand",
"@crate_index//:tonic",
],
)

Expand Down
3 changes: 3 additions & 0 deletions nativelink-config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@ version = "0.0.0"
edition = "2021"

[dependencies]
error = { path = "../error" }

serde = { version = "1.0.193", features = ["derive"] }
shellexpand = "3.1.0"
tonic = { version = "0.9.2", features = ["tls"] }
41 changes: 30 additions & 11 deletions nativelink-config/src/cas_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ use serde::Deserialize;

use crate::schedulers::SchedulerConfig;
use crate::serde_utils::{
convert_numeric_with_shellexpand, convert_optinoal_numeric_with_shellexpand, convert_string_with_shellexpand,
convert_numeric_with_shellexpand, convert_optional_numeric_with_shellexpand,
convert_optional_string_with_shellexpand, convert_string_with_shellexpand,
};
use crate::stores::{StoreConfig, StoreRefName};
use crate::stores::{ClientTlsConfig, StoreConfig, StoreRefName};

/// Name of the scheduler. This type will be used when referencing a
/// scheduler in the `CasConfig::schedulers`'s map key.
Expand Down Expand Up @@ -75,6 +76,11 @@ pub struct AcStoreConfig {
/// This store name referenced here may be reused multiple times.
#[serde(deserialize_with = "convert_string_with_shellexpand")]
pub ac_store: StoreRefName,

/// Whether the Action Cache store may be written to, this if set to false
/// it is only possible to read from the Action Cache.
#[serde(default)]
pub read_only: bool,
}

#[derive(Deserialize, Debug)]
Expand Down Expand Up @@ -215,6 +221,16 @@ pub struct TlsConfig {
/// Path to the private key file.
#[serde(deserialize_with = "convert_string_with_shellexpand")]
pub key_file: String,

/// Path to the certificate authority for mTLS, if client authentication is
/// required for this endpoint.
#[serde(default, deserialize_with = "convert_optional_string_with_shellexpand")]
pub client_ca_file: Option<String>,

/// Path to the certificate revocation list for mTLS, if client
/// authentication is required for this endpoint.
#[serde(default, deserialize_with = "convert_optional_string_with_shellexpand")]
pub client_crl_file: Option<String>,
}

/// Advanced Http configurations. These are generally should not be set.
Expand All @@ -225,29 +241,29 @@ pub struct TlsConfig {
/// specified.
#[derive(Deserialize, Debug, Default)]
pub struct HttpServerConfig {
#[serde(default, deserialize_with = "convert_optinoal_numeric_with_shellexpand")]
#[serde(default, deserialize_with = "convert_optional_numeric_with_shellexpand")]
pub http2_max_pending_accept_reset_streams: Option<u32>,
#[serde(default, deserialize_with = "convert_optinoal_numeric_with_shellexpand")]
#[serde(default, deserialize_with = "convert_optional_numeric_with_shellexpand")]
pub http2_initial_stream_window_size: Option<u32>,
#[serde(default, deserialize_with = "convert_optinoal_numeric_with_shellexpand")]
#[serde(default, deserialize_with = "convert_optional_numeric_with_shellexpand")]
pub http2_initial_connection_window_size: Option<u32>,
#[serde(default)]
pub http2_adaptive_window: Option<bool>,
#[serde(default, deserialize_with = "convert_optinoal_numeric_with_shellexpand")]
#[serde(default, deserialize_with = "convert_optional_numeric_with_shellexpand")]
pub http2_max_frame_size: Option<u32>,
#[serde(default, deserialize_with = "convert_optinoal_numeric_with_shellexpand")]
#[serde(default, deserialize_with = "convert_optional_numeric_with_shellexpand")]
pub http2_max_concurrent_streams: Option<u32>,
/// Note: This is in seconds.
#[serde(default, deserialize_with = "convert_optinoal_numeric_with_shellexpand")]
#[serde(default, deserialize_with = "convert_optional_numeric_with_shellexpand")]
pub http2_keep_alive_interval: Option<u32>,
/// Note: This is in seconds.
#[serde(default, deserialize_with = "convert_optinoal_numeric_with_shellexpand")]
#[serde(default, deserialize_with = "convert_optional_numeric_with_shellexpand")]
pub http2_keep_alive_timeout: Option<u32>,
#[serde(default, deserialize_with = "convert_optinoal_numeric_with_shellexpand")]
#[serde(default, deserialize_with = "convert_optional_numeric_with_shellexpand")]
pub http2_max_send_buf_size: Option<u32>,
#[serde(default)]
pub http2_enable_connect_protocol: Option<bool>,
#[serde(default, deserialize_with = "convert_optinoal_numeric_with_shellexpand")]
#[serde(default, deserialize_with = "convert_optional_numeric_with_shellexpand")]
pub http2_max_header_list_size: Option<u32>,
}

Expand Down Expand Up @@ -307,6 +323,9 @@ pub struct EndpointConfig {
/// Timeout in seconds that a request should take.
/// Default: 5 (seconds)
pub timeout: Option<f32>,

/// The TLS configuration to use to connect to the endpoint.
pub tls_config: Option<ClientTlsConfig>,
}

#[derive(Copy, Clone, Deserialize, Debug, Default)]
Expand Down
6 changes: 5 additions & 1 deletion nativelink-config/src/schedulers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use std::collections::HashMap;
use serde::Deserialize;

use crate::serde_utils::{convert_numeric_with_shellexpand, convert_string_with_shellexpand};
use crate::stores::{Retry, StoreRefName};
use crate::stores::{ClientTlsConfig, Retry, StoreRefName};

#[allow(non_camel_case_types)]
#[derive(Deserialize, Debug)]
Expand Down Expand Up @@ -128,9 +128,13 @@ pub struct GrpcScheduler {
/// The upstream scheduler to forward requests to.
#[serde(deserialize_with = "convert_string_with_shellexpand")]
pub endpoint: String,

/// Retry configuration to use when a network request fails.
#[serde(default)]
pub retry: Retry,

/// The TLS configuration to use to connect to the endpoint.
pub tls_config: Option<ClientTlsConfig>,
}

#[derive(Deserialize, Debug)]
Expand Down
16 changes: 15 additions & 1 deletion nativelink-config/src/serde_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ where
}

/// Same as convert_numeric_with_shellexpand, but supports Option<T>.
pub fn convert_optinoal_numeric_with_shellexpand<'de, D, T, E>(deserializer: D) -> Result<Option<T>, D::Error>
pub fn convert_optional_numeric_with_shellexpand<'de, D, T, E>(deserializer: D) -> Result<Option<T>, D::Error>
where
D: Deserializer<'de>,
E: fmt::Display,
Expand Down Expand Up @@ -106,3 +106,17 @@ pub fn convert_string_with_shellexpand<'de, D: Deserializer<'de>>(deserializer:
let value = String::deserialize(deserializer)?;
Ok((*(shellexpand::env(&value).map_err(de::Error::custom)?)).to_string())
}

/// Same as convert_string_with_shellexpand, but supports Option<String>.
pub fn convert_optional_string_with_shellexpand<'de, D: Deserializer<'de>>(
deserializer: D,
) -> Result<Option<String>, D::Error> {
let value = Option::<String>::deserialize(deserializer)?;
if let Some(value) = value {
Ok(Some(
(*(shellexpand::env(&value).map_err(de::Error::custom)?)).to_string(),
))
} else {
Ok(None)
}
}
Loading

0 comments on commit 3b83cfe

Please sign in to comment.