Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add api key whitelist hot reloading and small touch-up #458

Merged
merged 7 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions notary-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ futures = "0.3"
futures-util = "0.3.28"
http = "0.2.9"
hyper = { version = "0.14", features = ["client", "http1", "server", "tcp"] }
notify = { version = "6.1.1", default-features = false, features = ["macos_kqueue"] }
opentelemetry = { version = "0.19" }
p256 = "0.13"
rstest = "0.18"
Expand Down
4 changes: 4 additions & 0 deletions notary-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ Currently, both the private key (and cert) used to establish TLS connection with
#### Authorization
An optional authorization module is available to only allow requests with valid API key attached in the authorization header. The API key whitelist path (as well as the flag to enable/disable this module) can be changed in the config (`authorization` field).

Hot reloading of the whitelist is supported, i.e. modification of the whitelist file will be automatically applied without needing to restart the server. Please take note of the following
- Avoid using auto save mode when editing the whitelist to prevent spamming hot reloads
yuroitaki marked this conversation as resolved.
Show resolved Hide resolved
- Once the edit is saved, ensure that it has been reloaded successfully by checking the server log

#### Optional TLS
TLS between prover and notary is currently manually handled in the server, though it can be turned off if any of the following is true
- This server is run locally
Expand Down
8 changes: 8 additions & 0 deletions notary-server/config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ server:
name: "notary-server"
host: "0.0.0.0"
port: 7047
html-info: |
<h1>Notary Server {version}!</h1>
<ul>
<li>git commit hash: <a href="https://github.com/tlsnotary/tlsn/commit/{git_commit_hash}">{git_commit_hash}</a></li>
<li>git commit timestamp: {git_commit_timestamp}</li>
<li>public key: <pre>{public_key}</pre></li>
</ul>
<a href="/healthcheck">health check</a> - <a href="/info">info</a><br/>

notarization:
max-transcript-size: 20480
Expand Down
17 changes: 10 additions & 7 deletions notary-server/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use serde::Deserialize;

#[derive(Clone, Debug, Deserialize)]
#[derive(Clone, Debug, Deserialize, Default)]
#[serde(rename_all = "kebab-case")]
pub struct NotaryServerProperties {
/// Name and address of the notary server
Expand All @@ -17,7 +17,7 @@ pub struct NotaryServerProperties {
pub authorization: AuthorizationProperties,
}

#[derive(Clone, Debug, Deserialize)]
#[derive(Clone, Debug, Deserialize, Default)]
#[serde(rename_all = "kebab-case")]
pub struct AuthorizationProperties {
/// Switch to turn on or off auth middleware
Expand All @@ -26,23 +26,26 @@ pub struct AuthorizationProperties {
pub whitelist_csv_path: String,
}

#[derive(Clone, Debug, Deserialize)]
#[derive(Clone, Debug, Deserialize, Default)]
#[serde(rename_all = "kebab-case")]
pub struct NotarizationProperties {
/// Global limit for maximum transcript size in bytes
pub max_transcript_size: usize,
}

#[derive(Clone, Debug, Deserialize)]
#[derive(Clone, Debug, Deserialize, Default)]
#[serde(rename_all = "kebab-case")]
pub struct ServerProperties {
/// Used for testing purpose
pub name: String,
pub host: String,
pub port: u16,
/// Static html response returned from API root endpoint "/". Default html response contains
/// placeholder strings that will be replaced with actual values in server.rs, e.g. {version}, {public_key}
pub html_info: String,
}

#[derive(Clone, Debug, Deserialize)]
#[derive(Clone, Debug, Deserialize, Default)]
#[serde(rename_all = "kebab-case")]
pub struct TLSProperties {
/// Flag to turn on/off TLS between prover and notary (should always be turned on unless TLS is handled by external setup e.g. reverse proxy, cloud)
Expand All @@ -51,14 +54,14 @@ pub struct TLSProperties {
pub certificate_pem_path: String,
}

#[derive(Clone, Debug, Deserialize)]
#[derive(Clone, Debug, Deserialize, Default)]
#[serde(rename_all = "kebab-case")]
pub struct NotarySigningKeyProperties {
pub private_key_pem_path: String,
pub public_key_pem_path: String,
}

#[derive(Clone, Debug, Deserialize)]
#[derive(Clone, Debug, Deserialize, Default)]
#[serde(rename_all = "kebab-case")]
pub struct LoggingProperties {
/// Log verbosity level of the default filtering logic, which is notary_server=<level>,tlsn_verifier=<level>,tls_mpc=<level>
Expand Down
4 changes: 2 additions & 2 deletions notary-server/src/domain/auth.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use serde::Deserialize;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// Structure of each whitelisted record of the API key whitelist for authorization purpose
#[derive(Clone, Debug, Deserialize)]
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct AuthorizationWhitelistRecord {
pub name: String,
Expand Down
9 changes: 5 additions & 4 deletions notary-server/src/domain/notary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use std::{collections::HashMap, sync::Arc};
use chrono::{DateTime, Utc};
use p256::ecdsa::SigningKey;
use serde::{Deserialize, Serialize};
use tokio::sync::Mutex;
use std::sync::Mutex;
use tokio::sync::Mutex as AsyncMutex;

use crate::{config::NotarizationProperties, domain::auth::AuthorizationWhitelistRecord};

Expand Down Expand Up @@ -57,16 +58,16 @@ pub struct NotaryGlobals {
pub notary_signing_key: SigningKey,
pub notarization_config: NotarizationProperties,
/// A temporary storage to store configuration data, mainly used for WebSocket client
pub store: Arc<Mutex<HashMap<String, SessionData>>>,
pub store: Arc<AsyncMutex<HashMap<String, SessionData>>>,
sinui0 marked this conversation as resolved.
Show resolved Hide resolved
/// Whitelist of API keys for authorization purpose
pub authorization_whitelist: Option<Arc<HashMap<String, AuthorizationWhitelistRecord>>>,
pub authorization_whitelist: Option<Arc<Mutex<HashMap<String, AuthorizationWhitelistRecord>>>>,
}

impl NotaryGlobals {
pub fn new(
notary_signing_key: SigningKey,
notarization_config: NotarizationProperties,
authorization_whitelist: Option<Arc<HashMap<String, AuthorizationWhitelistRecord>>>,
authorization_whitelist: Option<Arc<Mutex<HashMap<String, AuthorizationWhitelistRecord>>>>,
) -> Self {
Self {
notary_signing_key,
Expand Down
1 change: 1 addition & 0 deletions notary-server/src/middleware.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ where

match auth_header {
Some(auth_header) => {
let whitelist = whitelist.lock().unwrap();
if api_key_is_valid(auth_header, &whitelist) {
trace!("Request authorized.");
Ok(Self)
Expand Down
Loading
Loading