From c278542a3cabdb4bd3da848db293f3bfebf17e2c Mon Sep 17 00:00:00 2001 From: Leo Nash Date: Thu, 4 Jun 2026 01:46:36 +0000 Subject: [PATCH 1/7] Update bytes dependency to 1.11.1 Addresses RUSTSEC-2026-0007. --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2b9dd58..2bad385 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -220,9 +220,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cc" From 3db04bf4e27638c3ddef956d47be01e47a012479 Mon Sep 17 00:00:00 2001 From: Leo Nash Date: Thu, 4 Jun 2026 01:36:12 +0000 Subject: [PATCH 2/7] Do not log PostgreSQL credentials --- server/src/main.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/server/src/main.rs b/server/src/main.rs index 12277d2..d1512f4 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -137,10 +137,7 @@ fn main() { error!("Failed to start postgres TLS backend: {}", e); std::process::exit(-1); }); - info!( - "Connected to PostgreSQL TLS backend with DSN: {}/{}", - config.postgresql_prefix, config.vss_db - ); + info!("Connected to PostgreSQL TLS backend, database {}", config.vss_db); Arc::new(postgres_tls_backend) } else { let postgres_plaintext_backend = PostgresPlaintextBackend::new( @@ -153,10 +150,7 @@ fn main() { error!("Failed to start postgres plaintext backend: {}", e); std::process::exit(-1); }); - info!( - "Connected to PostgreSQL plaintext backend with DSN: {}/{}", - config.postgresql_prefix, config.vss_db - ); + info!("Connected to PostgreSQL plaintext backend, database {}", config.vss_db); Arc::new(postgres_plaintext_backend) }; From 529fc4e1d6956de37919a4edef1104d7eeaf80fd Mon Sep 17 00:00:00 2001 From: Leo Nash Date: Wed, 3 Jun 2026 22:52:25 +0000 Subject: [PATCH 3/7] Fix no-authorization build warnings --- server/src/main.rs | 3 +++ server/src/util/config.rs | 37 +++++++++++++++++++++++++------------ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/server/src/main.rs b/server/src/main.rs index d1512f4..70205e5 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -87,7 +87,10 @@ fn main() { }, }; + #[cfg(any(feature = "jwt", feature = "sigs"))] let mut authorizer: Option> = None; + #[cfg(not(any(feature = "jwt", feature = "sigs")))] + let authorizer: Option> = None; #[cfg(feature = "jwt")] { if let Some(rsa_pem) = config.rsa_pem { diff --git a/server/src/util/config.rs b/server/src/util/config.rs index 6560334..dbf8d8f 100644 --- a/server/src/util/config.rs +++ b/server/src/util/config.rs @@ -6,6 +6,7 @@ const BIND_ADDR_VAR: &str = "VSS_BIND_ADDRESS"; const MAX_REQUEST_BODY_SIZE_VAR: &str = "VSS_MAX_REQUEST_BODY_SIZE"; const LOG_FILE_VAR: &str = "VSS_LOG_FILE"; const LOG_LEVEL_VAR: &str = "VSS_LOG_LEVEL"; +#[cfg(feature = "jwt")] const JWT_RSA_PEM_VAR: &str = "VSS_JWT_RSA_PEM"; const PSQL_USER_VAR: &str = "VSS_PSQL_USERNAME"; const PSQL_PASS_VAR: &str = "VSS_PSQL_PASSWORD"; @@ -21,6 +22,7 @@ const PSQL_CERT_PEM_VAR: &str = "VSS_PSQL_CRT_PEM"; struct TomlConfig { server_config: Option, log_config: Option, + #[cfg(feature = "jwt")] jwt_auth_config: Option, postgresql_config: Option, } @@ -31,6 +33,7 @@ struct ServerConfig { max_request_body_size: Option, } +#[cfg(feature = "jwt")] #[derive(Deserialize)] struct JwtAuthConfig { rsa_pem: Option, @@ -61,6 +64,7 @@ struct LogConfig { pub(crate) struct Configuration { pub(crate) bind_address: String, pub(crate) max_request_body_size: Option, + #[cfg(feature = "jwt")] pub(crate) rsa_pem: Option, pub(crate) postgresql_prefix: String, pub(crate) default_db: String, @@ -90,16 +94,21 @@ fn read_config<'a, T: std::fmt::Display>( } pub(crate) fn load_configuration(config_file_path: Option<&str>) -> Result { - let TomlConfig { server_config, log_config, jwt_auth_config, postgresql_config } = - match config_file_path { - Some(path) => { - let config_file = std::fs::read_to_string(path) - .map_err(|e| format!("Failed to read configuration file: {}", e))?; - toml::from_str(&config_file) - .map_err(|e| format!("Failed to parse configuration file: {}", e))? - }, - None => TomlConfig::default(), // All fields are set to `None` - }; + let TomlConfig { + server_config, + log_config, + #[cfg(feature = "jwt")] + jwt_auth_config, + postgresql_config, + } = match config_file_path { + Some(path) => { + let config_file = std::fs::read_to_string(path) + .map_err(|e| format!("Failed to read configuration file: {}", e))?; + toml::from_str(&config_file) + .map_err(|e| format!("Failed to parse configuration file: {}", e))? + }, + None => TomlConfig::default(), // All fields are set to `None` + }; let (bind_address_config, max_request_body_size_config) = match server_config { Some(c) => (c.bind_address, c.max_request_body_size), @@ -151,8 +160,11 @@ pub(crate) fn load_configuration(config_file_path: Option<&str>) -> Result = log_config.and_then(|config| config.file); let log_file = log_file_env.or(log_file_config).unwrap_or(PathBuf::from("vss.log")); - let rsa_pem_env = read_env(JWT_RSA_PEM_VAR)?; - let rsa_pem = rsa_pem_env.or(jwt_auth_config.and_then(|config| config.rsa_pem)); + #[cfg(feature = "jwt")] + let rsa_pem = { + let rsa_pem_env = read_env(JWT_RSA_PEM_VAR)?; + rsa_pem_env.or(jwt_auth_config.and_then(|config| config.rsa_pem)) + }; let username_env = read_env(PSQL_USER_VAR)?; let password_env = read_env(PSQL_PASS_VAR)?; @@ -206,6 +218,7 @@ pub(crate) fn load_configuration(config_file_path: Option<&str>) -> Result Date: Wed, 3 Jun 2026 22:52:33 +0000 Subject: [PATCH 4/7] Document VSS setup and auth configuration Fixes #53 --- README.md | 27 +++--- docs/getting-started.md | 159 ++++++++++++++++++++++++++++------ server/vss-server-config.toml | 12 ++- 3 files changed, 154 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 90af9e2..bfa9d94 100644 --- a/README.md +++ b/README.md @@ -70,12 +70,12 @@ VSS is also integrated with [LDK-node] v0.4.x as alpha support. ### Development -* **Build & Deploy**: Refer to [docs/getting-started.md](docs/getting-started.md) for instructions related to - building and deploying VSS. +* **Build & Deploy**: Refer to [docs/getting-started.md](docs/getting-started.md) for concrete PostgreSQL setup, + authentication configuration, local no-auth development mode, and deployment commands. * **Hosting**: VSS can either be self-hosted or deployed in the cloud. If a service provider is hosting VSS for multiple users, it must be configured with **HTTPS**, **Authentication/Authorization**, and **rate-limiting**. * **Authentication and Authorization**: VSS supports authentication via - [Proof-of-Private-Key-Knowledge](#Authentication) or [JWT](https://datatracker.ietf.org/doc/html/rfc7519). + [Proof-of-Private-Key-Knowledge](#authentication) or [JWT](https://datatracker.ietf.org/doc/html/rfc7519). The API also offers hooks for simple HTTP header-based authentication. Note that the security of authentication heavily relies on using HTTPS for all requests. * **Scaling**: VSS itself is stateless and can be horizontally scaled easily. VSS can be configured to point to a @@ -99,18 +99,19 @@ VSS is also integrated with [LDK-node] v0.4.x as alpha support. ### Authentication -By default, VSS uses a simple authentication scheme whereby each client must provide a valid signature for a -client-specified public key. The public key identifies the storage that belongs to the client. This scheme does -not impose **any** restrictions on who can interact with VSS; it **only** ensures that each client can only -access *their own* storage. Therefore, this scheme **must** be paired with a network-level gatekeeper to prevent -unauthorized interactions with VSS. +Default builds include signature and JWT authentication. If `jwt_auth_config.rsa_pem` or `VSS_JWT_RSA_PEM` is +configured, VSS verifies RS256 bearer tokens from the HTTP `Authorization` header. The JWT `sub` claim identifies +the storage user. VSS only implements token verification; operators must provide their own token issuance service. -The other option offered is JWT authentication. This form of authentication validates whether a client should -be given access to VSS, *and* which storage the client has access to. VSS only implements the verification half of this -scheme, and users must provide their own JWT issuance service if this solution is chosen. +If JWT is not configured, VSS uses signature authentication. Each client provides a valid signature for a +client-specified secp256k1 public key in the HTTP `Authorization` header. The public key identifies that client's +storage. This scheme does not impose **any** restrictions on who can interact with VSS; it **only** ensures that each +client can only access *their own* storage. Therefore, this scheme **must** be paired with a network-level gatekeeper +and rate limiting to prevent unauthorized interactions with VSS. -Finally, there is an option to completely disable all forms of authentication to VSS. This option should *only* be -used in local development and testing. +Finally, there is a cfg-gated option to disable all forms of authentication for local development and testing. Do not +publicly expose no-auth builds. See [docs/getting-started.md](docs/getting-started.md#authentication-setup) for exact +config and build commands. ### Summary diff --git a/docs/getting-started.md b/docs/getting-started.md index 3b2a4d7..36d5a87 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -1,42 +1,145 @@ -# Versioned Storage Service (Rust) +# Getting Started -### Prerequisites +This guide covers a local source build and the required PostgreSQL and authentication setup. For +the threat model and auth overview, see the root [README](../README.md). -- Install Rust and Cargo (https://www.rust-lang.org/tools/install). -- Install PostgreSQL 15 (https://www.postgresql.org/download/) -- Install OpenSSL (used for TLS connections to the PostgreSQL backend: https://docs.rs/openssl/latest/openssl/#automatic) +## Prerequisites -### Building +- Rust and Cargo, using at least the repository MSRV of 1.85.0. +- PostgreSQL 15 or newer. +- OpenSSL development/runtime libraries for PostgreSQL TLS support. -``` -git clone https://github.com/lightningdevkit/vss-server.git -cd vss-server +## Quick Start with Docker PostgreSQL + +Start only the PostgreSQL service from the included Compose file: +```bash +docker compose up -d postgres cargo build --release +cargo run -- server/vss-server-config.toml +``` + +The sample config connects to `postgres:postgres@127.0.0.1:5432`, creates the `vss` database if it +does not exist, and runs schema migrations on startup. The VSS endpoint is +`http://localhost:8080/vss`; `/metrics` is available without VSS authentication: + +```bash +curl -f http://localhost:8080/metrics +``` + +The default `cargo run` command starts the server with signature authentication, because the sample +config does not include a JWT key. VSS API requests still need a valid `Authorization` header. To +exercise VSS API endpoints without auth headers in a local-only environment, use +[Local No-Auth Mode](#local-no-auth-mode). + +To run both PostgreSQL and the server in containers: + +```bash +docker compose up --build ``` -### Running -1. **Edit Configuration**: Modify `./server/vss-server-config.toml` to set application configuration and - environment variables as needed. -2. VSS will setup a PostgreSQL database on first launch if it is not found. You can also manually create the database - using the statement at `./impls/src/postgres/sql/v0_create_vss_db.sql`. -3. Start server: - ``` - cargo run server/vss-server-config.toml - ``` -4. VSS endpoint should be reachable at `http://localhost:8080/vss`. +## PostgreSQL Setup + +VSS first connects to `default_database`, then creates `vss_database` if it is missing, then connects +to `vss_database` and applies migrations. With the sample config these are `postgres` and `vss`. + +The configured PostgreSQL role must be able to connect to `default_database`. It must also either: + +- have permission to run `CREATE DATABASE vss` when `vss_database` does not exist, or +- use an already-created `vss_database` and have privileges to create/alter tables, indexes, + sequences, and rows in that database. + +For an existing local PostgreSQL instance, create the database yourself if the VSS user cannot create +databases: + +```bash +createdb -U postgres vss +``` + +Then update `[postgresql_config]` in `server/vss-server-config.toml` or set the corresponding +environment variables: + +```bash +VSS_PSQL_USERNAME=postgres +VSS_PSQL_PASSWORD=postgres +VSS_PSQL_ADDRESS=127.0.0.1:5432 +VSS_PSQL_DEFAULT_DB=postgres +VSS_PSQL_VSS_DB=vss +``` + +## Authentication Setup + +Default builds include both `jwt` and `sigs` features. At startup, VSS uses JWT auth if an RSA public +key is configured; otherwise it uses signature auth. Both schemes read the HTTP `Authorization` +header. + +### Signature Auth + +No TOML setting is required. Leave `[jwt_auth_config]` unset and the default build will require each +request to include a proof of private key knowledge in `Authorization`. The proof is the compressed +secp256k1 public key hex, followed by a compact ECDSA signature hex, followed by a Unix timestamp. +The signature covers VSS's signing constant, the public key, and the timestamp. Signature auth +isolates storage by public key, but does not decide who may create a new storage identity; +production deployments still need HTTPS, rate limiting, and an external access control layer. + +### JWT Auth + +Configure the RSA public key used to verify RS256 JWTs: + +```toml +[jwt_auth_config] +rsa_pem = """ +-----BEGIN PUBLIC KEY----- +... +-----END PUBLIC KEY----- +""" +``` + +or set `VSS_JWT_RSA_PEM`. Clients must send `Authorization: Bearer `. Tokens must be RS256, +include `sub` and `exp` claims, and omit `aud`; `sub` becomes the VSS storage user token. VSS only +verifies tokens, you must run the service that issues them. + +### Local No-Auth Mode + +For local development only, build with the cfg-gated no-op authorizer: + +```bash +RUSTFLAGS="--cfg noop_authorizer" cargo run --no-default-features -- server/vss-server-config.toml +``` + +Do not expose this mode outside a local test environment. + +## Configuration Reference + +Default builds read the following settings. Each listed TOML option can be overridden by its +environment variable. + +| TOML setting | Environment variable | Purpose | +| --- | --- | --- | +| `server_config.bind_address` | `VSS_BIND_ADDRESS` | HTTP listen address, for example `127.0.0.1:8080`. | +| `server_config.max_request_body_size` | `VSS_MAX_REQUEST_BODY_SIZE` | Request body limit in bytes. Defaults to 1 GiB. | +| `jwt_auth_config.rsa_pem` | `VSS_JWT_RSA_PEM` | RSA public key for JWT verification. Requires the `jwt` feature, which is enabled by default. | +| `postgresql_config.username` | `VSS_PSQL_USERNAME` | PostgreSQL user. | +| `postgresql_config.password` | `VSS_PSQL_PASSWORD` | PostgreSQL password. | +| `postgresql_config.address` | `VSS_PSQL_ADDRESS` | PostgreSQL host and port. | +| `postgresql_config.default_database` | `VSS_PSQL_DEFAULT_DB` | Database used for startup and database creation. | +| `postgresql_config.vss_database` | `VSS_PSQL_VSS_DB` | VSS application database. | +| `postgresql_config.tls` | `VSS_PSQL_TLS` | Enables PostgreSQL TLS with system trust roots. | +| `postgresql_config.tls.crt_pem` | `VSS_PSQL_CRT_PEM` | Adds a PEM root certificate and enables PostgreSQL TLS. | +| `log_config.level` | `VSS_LOG_LEVEL` | Log level. Defaults to `debug`. | +| `log_config.file` | `VSS_LOG_FILE` | Log file path. Defaults to `vss.log`. | -### Configuration +## Production Notes -Refer to `./server/vss-server-config.toml` to see available configuration options. +VSS is stateless and can be run behind a load balancer, but PostgreSQL is the durable state store. +Internet-facing deployments must terminate HTTPS in front of VSS, configure authentication, and add +rate limiting. -### Support +## Support -If you encounter any issues or have questions, feel free to open an issue on -the [GitHub repository](https://github.com/lightningdevkit/vss-server/issues). For further assistance or to discuss the -development of VSS, you can reach out to us in the [LDK Discord](https://discord.gg/5AcknnMfBw) in the `#vss` channel. +Open issues in the [GitHub repository](https://github.com/lightningdevkit/vss-server/issues), or use +the [LDK Discord](https://discord.gg/5AcknnMfBw) `#vss` channel. -[LDK Discord]: https://discord.gg/5AcknnMfBw +## MSRV -### MSRV -The Minimum Supported Rust Version (MSRV) is currently 1.85.0. +The Minimum Supported Rust Version (MSRV) is 1.85.0. diff --git a/server/vss-server-config.toml b/server/vss-server-config.toml index 49f6b6b..fd78d31 100644 --- a/server/vss-server-config.toml +++ b/server/vss-server-config.toml @@ -4,8 +4,14 @@ bind_address = "127.0.0.1:8080" # Optional in TOML, can be overridden by env var # Defaults to the maximum possible value of 1 GB if unset. # max_request_body_size = 1073741824 -# Uncomment the table below to verify JWT tokens in the HTTP Authorization header against the given RSA public key, -# can be overridden by env var `VSS_JWT_RSA_PEM` +# Authentication: +# - Default builds use signature auth when this JWT section is unset. Signature auth has no TOML +# setting; clients must send the required signature in the HTTP Authorization header. +# - Uncomment the table below to use JWT auth instead. JWT auth verifies Bearer tokens in the +# HTTP Authorization header against this RSA public key, and can be overridden by env var +# `VSS_JWT_RSA_PEM`. +# - For local development only, no-auth mode requires building with: +# RUSTFLAGS="--cfg noop_authorizer" cargo run --no-default-features -- server/vss-server-config.toml # [jwt_auth_config] # rsa_pem = """ # -----BEGIN PUBLIC KEY----- @@ -31,4 +37,4 @@ vss_database = "vss" # Optional in TOML, can be overridden by env var # [log_config] # level = "debug" # Uncomment, or set env var `VSS_LOG_LEVEL` to set the log level, the default is "debug" -# file = "vss.log" # Uncomment, or set env var `VSS_LOG_FILE` to set the log file path, the default is "vss.log" \ No newline at end of file +# file = "vss.log" # Uncomment, or set env var `VSS_LOG_FILE` to set the log file path, the default is "vss.log" From 6446355709b42ef6d41a448b44c3b8d30b8bb9b1 Mon Sep 17 00:00:00 2001 From: Leo Nash Date: Wed, 10 Jun 2026 20:12:59 +0000 Subject: [PATCH 5/7] Fix documentation in auth-impls signature module --- auth-impls/src/signature.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auth-impls/src/signature.rs b/auth-impls/src/signature.rs index dfc8cf6..0b62bb1 100644 --- a/auth-impls/src/signature.rs +++ b/auth-impls/src/signature.rs @@ -31,7 +31,7 @@ pub const SIGNING_CONSTANT: &'static [u8] = /// 64-byte secp256k1 ECDSA signature followed by the signing time since the UNIX epoch, encoded as /// a string. /// -/// The proof will not be valid if the provided time is more than an hour from now. +/// The proof will not be valid if the provided time is more than 24 hours from now. /// /// Because no rate-limiting of new user accounts is done, a higher-level service is required to /// ensure requests are not triggering excess new user registrations. From f1a819b80ea2511f56b0f8c69d62873109680488 Mon Sep 17 00:00:00 2001 From: Leo Nash Date: Wed, 10 Jun 2026 19:18:02 +0000 Subject: [PATCH 6/7] Move proto/vss.proto to api/src/proto/vss.proto --- README.md | 2 +- api/.gitignore | 3 --- api/build.rs | 3 --- {proto => api/src/proto}/vss.proto | 0 4 files changed, 1 insertion(+), 7 deletions(-) delete mode 100644 api/.gitignore rename {proto => api/src/proto}/vss.proto (100%) diff --git a/README.md b/README.md index bfa9d94..163e60b 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,7 @@ If you encounter any issues or have questions, feel free to open an issue on the [GitHub repository](https://github.com/lightningdevkit/vss-server/issues). For further assistance or to discuss the development of VSS, you can reach out to us in the [LDK Discord] in the `#vss` channel. -[VSS API contract]: https://github.com/lightningdevkit/vss-server/blob/main/proto/vss.proto +[VSS API contract]: https://github.com/lightningdevkit/vss-server/blob/main/api/src/proto/vss.proto [VSS-client]: https://github.com/lightningdevkit/vss-client diff --git a/api/.gitignore b/api/.gitignore deleted file mode 100644 index a3cf438..0000000 --- a/api/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -Cargo.lock -target/** -src/proto/** diff --git a/api/build.rs b/api/build.rs index 4dd8b9a..eb0e7ba 100644 --- a/api/build.rs +++ b/api/build.rs @@ -11,9 +11,6 @@ fn main() { #[cfg(genproto)] fn generate_protos() { - fs::create_dir_all("src/proto").unwrap(); - fs::copy("../proto/vss.proto", "src/proto/vss.proto").unwrap(); - prost_build::Config::new() .bytes(&["."]) .compile_protos(&["src/proto/vss.proto"], &["src/"]) diff --git a/proto/vss.proto b/api/src/proto/vss.proto similarity index 100% rename from proto/vss.proto rename to api/src/proto/vss.proto From 2cd972811eb4ad7ff4af7475e544ca2cf2322367 Mon Sep 17 00:00:00 2001 From: Leo Nash Date: Wed, 3 Jun 2026 22:52:37 +0000 Subject: [PATCH 7/7] Cut 0.1.0-alpha.0 Rename crates for publishing to crates.io. Add description, license, homepage, and repository fields. --- CHANGELOG.md | 32 +++++++ Cargo.lock | 94 +++++++++---------- Cargo.toml | 10 ++ LICENSE-APACHE | 201 +++++++++++++++++++++++++++++++++++++++++ LICENSE => LICENSE-MIT | 0 api/Cargo.toml | 10 +- auth-impls/Cargo.toml | 12 ++- impls/Cargo.toml | 14 ++- server/Cargo.toml | 16 ++-- 9 files changed, 324 insertions(+), 65 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 LICENSE-APACHE rename LICENSE => LICENSE-MIT (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..50c59ed --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,32 @@ +# 0.1.0-alpha.0 - Jun. 11, 2026 + +- VSS service implementing VSS protocol version 0. (#34, #35) +- Rust workspace for the VSS server, API contract types, authentication implementations, and storage backend + implementations. (#34, #35, #43, #72, #79, #101) +- PostgreSQL storage backend with database initialization, migrations, TLS support, key-level versioning, store-level + global versioning, transactional writes, deletes, and paginated key-version listing. (#35, #55, #67, #96) +- Signature-based and JWT-based authorization implementations, with cfg-gated no-op authorization for local development + and tests. (#34, #43, #72, #79, #87) +- Configuration through TOML file and environment variables, including bind address, request body size, logging, JWT + RSA public key, and PostgreSQL settings. (#46, #67, #72, #73, #76, #87) +- Server logging to stdout/stderr and file, with SIGHUP log-file reopening and shutdown on CTRL-C/SIGTERM. (#34, #87) +- Prometheus-compatible `/metrics` health metric. (#99) +- Docker and Docker Compose files for local deployment. (#76, #80) +- Getting-started documentation. (#102) + +In total, this release features 42 files changed, 7956 insertions from 14 authors in alphabetical order: + +- Andrei +- Arik +- benthecarman +- dzdidi +- Elias Rohrer +- Enigbe +- fmar +- G8XSU +- Gursharan Singh +- Jeffrey Czyz +- Leo Nash +- Matt Corallo +- Steve Lee +- tankyleo diff --git a/Cargo.lock b/Cargo.lock index 2bad385..f5fd43a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,17 +26,6 @@ version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" -[[package]] -name = "api" -version = "0.1.0" -dependencies = [ - "async-trait", - "bytes", - "prost", - "prost-build", - "rand 0.8.5", -] - [[package]] name = "arrayvec" version = "0.7.6" @@ -60,23 +49,6 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" -[[package]] -name = "auth-impls" -version = "0.1.0" -dependencies = [ - "api", - "async-trait", - "base64", - "bitcoin_hashes 1.0.0", - "hex-conservative 1.0.1", - "jsonwebtoken", - "openssl", - "secp256k1 0.31.1", - "serde", - "serde_json", - "tokio", -] - [[package]] name = "autocfg" version = "1.5.0" @@ -606,21 +578,6 @@ dependencies = [ "cc", ] -[[package]] -name = "impls" -version = "0.1.0" -dependencies = [ - "api", - "async-trait", - "bytes", - "chrono", - "log", - "native-tls", - "postgres-native-tls", - "tokio", - "tokio-postgres", -] - [[package]] name = "indexmap" version = "2.13.0" @@ -1742,6 +1699,34 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "vss-api" +version = "0.1.0-alpha.0" +dependencies = [ + "async-trait", + "bytes", + "prost", + "prost-build", + "rand 0.8.5", +] + +[[package]] +name = "vss-auth-impls" +version = "0.1.0-alpha.0" +dependencies = [ + "async-trait", + "base64", + "bitcoin_hashes 1.0.0", + "hex-conservative 1.0.1", + "jsonwebtoken", + "openssl", + "secp256k1 0.31.1", + "serde", + "serde_json", + "tokio", + "vss-api", +] + [[package]] name = "vss-client-ng" version = "0.5.0" @@ -1783,26 +1768,41 @@ dependencies = [ "tokio", ] +[[package]] +name = "vss-impls" +version = "0.1.0-alpha.0" +dependencies = [ + "async-trait", + "bytes", + "chrono", + "log", + "native-tls", + "postgres-native-tls", + "tokio", + "tokio-postgres", + "vss-api", +] + [[package]] name = "vss-server" -version = "0.1.0" +version = "0.1.0-alpha.0" dependencies = [ - "api", - "auth-impls", "bytes", "chrono", "http-body-util", "hyper", "hyper-util", - "impls", "log", "prost", "rand 0.9.2", "serde", "tokio", "toml", + "vss-api", + "vss-auth-impls", "vss-client-ng 0.5.0", "vss-client-ng 0.6.0", + "vss-impls", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 899bd26..407070b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,17 @@ members = ["server", "api", "impls", "auth-impls"] default-members = ["server"] [workspace.package] +version = "0.1.0-alpha.0" rust-version = "1.85.0" +edition = "2021" +license = "MIT OR Apache-2.0" +homepage = "https://lightningdevkit.org/" +repository = "https://github.com/lightningdevkit/vss-server/" + +[workspace.dependencies] +api = { package = "vss-api", version = "0.1.0-alpha.0", path = "./api" } +auth-impls = { package = "vss-auth-impls", version = "0.1.0-alpha.0", path = "./auth-impls" } +impls = { package = "vss-impls", version = "0.1.0-alpha.0", path = "./impls" } [profile.release] panic = "abort" diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/LICENSE b/LICENSE-MIT similarity index 100% rename from LICENSE rename to LICENSE-MIT diff --git a/api/Cargo.toml b/api/Cargo.toml index b34be8d..d3b5b12 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -1,8 +1,12 @@ [package] -name = "api" -version = "0.1.0" -edition = "2021" +name = "vss-api" +description = "API contracts for VSS." +version.workspace = true rust-version.workspace = true +edition.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true [dependencies] async-trait = "0.1.77" diff --git a/auth-impls/Cargo.toml b/auth-impls/Cargo.toml index 5f95667..7a11104 100644 --- a/auth-impls/Cargo.toml +++ b/auth-impls/Cargo.toml @@ -1,15 +1,19 @@ [package] -name = "auth-impls" -version = "0.1.0" -edition = "2021" +name = "vss-auth-impls" +description = "Authentication implementations for VSS." +version.workspace = true rust-version.workspace = true +edition.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true [features] jwt = [ "base64", "serde", "serde_json", "openssl" ] sigs = [ "bitcoin_hashes", "hex-conservative", "secp256k1" ] [dependencies] -api = { path = "../api" } +api = { workspace = true } async-trait = "0.1.77" base64 = { version = "0.22.1", optional = true, default-features = false, features = ["std"] } bitcoin_hashes = { version = "1.0", optional = true, default-features = false } diff --git a/impls/Cargo.toml b/impls/Cargo.toml index 9172cd8..92c098a 100644 --- a/impls/Cargo.toml +++ b/impls/Cargo.toml @@ -1,12 +1,16 @@ [package] -name = "impls" -version = "0.1.0" -edition = "2021" +name = "vss-impls" +description = "Backend KV store implementations for VSS." +version.workspace = true rust-version.workspace = true +edition.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true [dependencies] async-trait = "0.1.77" -api = { path = "../api" } +api = { workspace = true } chrono = "0.4.38" tokio-postgres = { version = "0.7.12", features = ["with-chrono-0_4"] } bytes = "1.4.0" @@ -17,4 +21,4 @@ log = { version = "0.4.29", default-features = false } [dev-dependencies] tokio = { version = "1.38.0", default-features = false, features = ["rt-multi-thread", "macros"] } -api = { path = "../api", features = ["_test_utils"] } +api = { workspace = true, features = ["_test_utils"] } diff --git a/server/Cargo.toml b/server/Cargo.toml index 57739c0..70a97a9 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -1,8 +1,12 @@ [package] name = "vss-server" -version = "0.1.0" -edition = "2021" +description = "VSS HTTP server implementation." +version.workspace = true rust-version.workspace = true +edition.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true [features] jwt = ["auth-impls/jwt"] @@ -10,9 +14,9 @@ sigs = ["auth-impls/sigs"] default = [ "jwt", "sigs" ] [dependencies] -api = { path = "../api" } -auth-impls = { path = "../auth-impls" } -impls = { path = "../impls" } +api = { workspace = true } +auth-impls = { workspace = true } +impls = { workspace = true } hyper = { version = "1", default-features = false, features = ["server", "http1"] } http-body-util = { version = "0.1", default-features = false } @@ -27,7 +31,7 @@ chrono = { version = "0.4", default-features = false, features = ["clock"] } rand = { version = "0.9.2", default-features = false } [target.'cfg(noop_authorizer)'.dependencies] -api = { path = "../api", features = ["_test_utils"] } +api = { workspace = true, features = ["_test_utils"] } [target.'cfg(vss_client_v050_compatibility)'.dev-dependencies] vss-client-v050 = { package = "vss-client-ng", version = "=0.5.0" }