Skip to content
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
2 changes: 1 addition & 1 deletion .github/workflows/build-and-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,4 @@ jobs:
MTLS_ENABLED: true
MTLS_REQUEST_CERT: true
MTLS_REJECT_UNAUTHORIZED: false
KMS_URL: 'https://localhost:3000/'
KEY_PROVIDER_URL: 'https://localhost:3000/'
6 changes: 3 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Advanced Wallet Manager is a secure cryptocurrency signing server with two opera

- Lightweight server focused solely on secure signing operations
- Runs on port 3080 by default
- Integrates with KMS for key management
- Integrates with advanced wallets key provider for key management
- Handles cryptographic operations securely
- Exposes minimal endpoints focused on key generation and signing

Expand All @@ -56,7 +56,7 @@ Advanced Wallet Manager is a secure cryptocurrency signing server with two opera
- `src/initConfig.ts` - Configuration loading and validation
- `src/routes/` - Express routes for both modes
- `src/api/` - API implementation for both modes
- `src/kms/` - KMS client and operations
- `src/advancedWalletManager/keyProviderClient/` - key provider client and operations
- `src/shared/` - Shared utilities and types

### Configuration
Expand All @@ -73,7 +73,7 @@ Configuration is managed through environment variables with defaults defined in
#### Advanced Wallet Manager Mode Specific

- `ADVANCED_WALLET_MANAGER_PORT` - Port to listen on (default: 3080)
- `KMS_URL` - Required KMS service URL
- `KEY_PROVIDER_URL` - Required key provider service URL

#### Master Express Mode Specific

Expand Down
58 changes: 29 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Advanced wallets operate in two modes:
Key features include:

- **Complete Infrastructure Control** - Host and manage all components in your own secure environment.
- **KMS/HSM Integration** - Bring your own KMS or HSM by implementing the provided [KMS API interface specification](./kms-api-spec.yaml). Reference implementations available for [AWS HSM](./demo-kms-script/aws-interface.md) and [Dinamo HSM](./demo-kms-script/dinamo-interface.md).
- **KMS/HSM Integration** - Bring your own KMS or HSM by implementing the provided [advanced wallets key provider API interface specification](./key-provider-api-spec.yaml). Reference implementations available for [AWS HSM](./demo-key-provider-script/aws-interface.md) and [Dinamo HSM](./demo-key-provider-script/dinamo-interface.md).
- **Network Isolation** - Advanced Wallet Manager operates in a completely isolated network segment with no external internet access.
- **mTLS Security** - Optional mutual TLS with client certificate validation for secure inter-service communications.
- **Flexible Configuration** - Environment-based setup with file or variable-based certificates.
Expand All @@ -38,7 +38,7 @@ Key features include:

## Architecture

- **Advanced Wallet Manager** (Port 3080) - An isolated signing server with no internet access that only connects to your KMS API implementation for key operations.
- **Advanced Wallet Manager** (Port 3080) - An isolated signing server with no internet access that only connects to your key provider API implementation for key operations.
- **Master Express** (Port 3081) - An API gateway providing end-to-end wallet creation and transaction support, integrating [BitGo APIs](https://developers.bitgo.com/reference/overview#/) with secure communication to Advanced Wallet Manager.

## Installation
Expand All @@ -49,9 +49,9 @@ Key features include:
- **npm** or **yarn** package manager.
- **OpenSSL** for certificate generation.
- **Docker** and **Docker Compose** for containerized deployment (or you can use **Podman** as alternative to Docker).
- **KMS API Implementation** - You must implement the [KMS API interface specification](./kms-api-spec.yaml) to connect your KMS/HSM to the Advanced Wallet Manager. Reference implementations available:
- [AWS HSM Implementation Example](./demo-kms-script/aws-interface.md)
- [Dinamo HSM Implementation Example](./demo-kms-script/dinamo-interface.md)
- **key provider API implementation** - You must implement the [key provider API interface specification](./key-provider-api-spec.yaml) to connect your KMS/HSM to the Advanced Wallet Manager. Reference implementations available:
- [AWS HSM Implementation Example](./demo-key-provider-script/aws-interface.md)
- [Dinamo HSM Implementation Example](./demo-key-provider-script/dinamo-interface.md)

### Setup

Expand Down Expand Up @@ -119,7 +119,7 @@ TLS_MODE=disabled \
BITGO_ENV=test \
APP_MODE=advanced-wallet-manager \
ADVANCED_WALLET_MANAGER_PORT=3080 \
KMS_URL=http://localhost:3000 \
KEY_PROVIDER_URL=http://localhost:3000 \
npm start
```

Expand Down Expand Up @@ -168,9 +168,9 @@ curl -X POST http://localhost:3081/ping/advancedWalletManager
| Variable | Description | Default | Required |
| ------------------------------ | ---------------------------------- | ------- | -------- |
| `ADVANCED_WALLET_MANAGER_PORT` | Port to listen on | `3080` | ❌ |
| `KMS_URL` | URL to your KMS API implementation | - | ✅ |
| `KEY_PROVIDER_URL` | URL to your key provider API implementation | - | ✅ |

> **Note:** The `KMS_URL` points to your implementation of the KMS API interface. You must implement this interface to connect your KMS/HSM. See [Prerequisites](#prerequisites) for the specification and examples.
> **Note:** The `KEY_PROVIDER_URL` points to your implementation of the key provider API interface. You must implement this interface to connect your KMS/HSM. See [Prerequisites](#prerequisites) for the specification and examples.

### Master Express Settings

Expand Down Expand Up @@ -232,17 +232,17 @@ curl -X POST http://localhost:3081/ping/advancedWalletManager
| `AWM_SERVER_CA_CERT` | AWM server CA certificate (alternative) | PEM string |
| `AWM_SERVER_CERT_ALLOW_SELF_SIGNED` | Allow self-signed AWM server certificates | Boolean (default: `false`) |

**For Advanced Wallet Manager → KMS:**
**For Advanced Wallet Manager → key provider:**

| Variable | Description | Format |
| ----------------------------------- | ----------------------------------------- | -------------------------- |
| `KMS_CLIENT_TLS_KEY_PATH` | Client private key file path | File path |
| `KMS_CLIENT_TLS_KEY` | Client private key (alternative) | PEM string |
| `KMS_CLIENT_TLS_CERT_PATH` | Client certificate file path | File path |
| `KMS_CLIENT_TLS_CERT` | Client certificate (alternative) | PEM string |
| `KMS_SERVER_CA_CERT_PATH` | KMS server CA certificate file path | File path |
| `KMS_SERVER_CA_CERT` | KMS server CA certificate (alternative) | PEM string |
| `KMS_SERVER_CERT_ALLOW_SELF_SIGNED` | Allow self-signed KMS server certificates | Boolean (default: `false`) |
| Variable | Description | Format |
| ------------------------------------------- | -------------------------------------------------- | -------------------------- |
| `KEY_PROVIDER_CLIENT_TLS_KEY_PATH` | Client private key file path | File path |
| `KEY_PROVIDER_CLIENT_TLS_KEY` | Client private key (alternative) | PEM string |
| `KEY_PROVIDER_CLIENT_TLS_CERT_PATH` | Client certificate file path | File path |
| `KEY_PROVIDER_CLIENT_TLS_CERT` | Client certificate (alternative) | PEM string |
| `KEY_PROVIDER_SERVER_CA_CERT_PATH` | Key provider server CA certificate file path | File path |
| `KEY_PROVIDER_SERVER_CA_CERT` | Key provider server CA certificate (alternative) | PEM string |
| `KEY_PROVIDER_SERVER_CERT_ALLOW_SELF_SIGNED` | Allow self-signed key provider server certificates | Boolean (default: `false`) |

> **Note:** For security reasons, when `TLS_MODE=mtls`, outbound client certificates are required and cannot reuse server certificates. When `TLS_MODE=disabled`, these certificates aren't required.

Expand Down Expand Up @@ -276,7 +276,7 @@ podman run -d \
-e TLS_MODE=mtls \
-e SERVER_TLS_KEY_PATH=/app/certs/advanced-wallet-manager-key.pem \
-e SERVER_TLS_CERT_PATH=/app/certs/advanced-wallet-manager-cert.pem \
-e KMS_URL=host.containers.internal:3000 \
-e KEY_PROVIDER_URL=host.containers.internal:3000 \
-e NODE_ENV=development \
-e CLIENT_CERT_ALLOW_SELF_SIGNED=true \
advanced-wallet-manager
Expand Down Expand Up @@ -351,7 +351,7 @@ The setup creates two distinct networks:
### Prerequisites

1. **Install Docker and Docker Compose**
2. **Ensure your KMS API implementation is running** on your host machine (typically on port 3000)
2. **Ensure your key provider API implementation is running** on your host machine (typically on port 3000)

### Quick Start

Expand Down Expand Up @@ -424,17 +424,17 @@ For production deployments with proper mTLS security:
export APP_MODE=advanced-wallet-manager
export TLS_MODE=mtls
export ADVANCED_WALLET_MANAGER_PORT=3080
export KMS_URL=https://production-kms.example.com:3000
export KEY_PROVIDER_URL=https://production-key-provider.example.com:3000
# Server certificates for incoming mTLS connections
export SERVER_TLS_KEY_PATH=/secure/certs/awm-server.key
export SERVER_TLS_CERT_PATH=/secure/certs/awm-server.crt
# Client certificates for outbound connections to KMS
export KMS_CLIENT_TLS_KEY_PATH=/secure/certs/awm-kms-client.key
export KMS_CLIENT_TLS_CERT_PATH=/secure/certs/awm-kms-client.crt
export KMS_SERVER_CA_CERT_PATH=/secure/certs/kms-ca.crt
# Client certificates for outbound connections to key provider
export KEY_PROVIDER_CLIENT_TLS_KEY_PATH=/secure/certs/awm-key-provider-client.key
export KEY_PROVIDER_CLIENT_TLS_CERT_PATH=/secure/certs/awm-key-provider-client.crt
export KEY_PROVIDER_SERVER_CA_CERT_PATH=/secure/certs/key-provider-ca.crt
# Security settings - production-grade
export CLIENT_CERT_ALLOW_SELF_SIGNED=false
export KMS_SERVER_CERT_ALLOW_SELF_SIGNED=false
export KEY_PROVIDER_SERVER_CERT_ALLOW_SELF_SIGNED=false
export MTLS_ALLOWED_CLIENT_FINGERPRINTS=sha256:1a2b3c...,sha256:4d5e6f...
export BITGO_ENV=prod
npm start
Expand Down Expand Up @@ -490,7 +490,7 @@ curl --cert /path/to/client-cert.crt --key /path/to/client-key.key \
For local testing, you can generate and use demo certificates with the self-signed configuration flags:

- Generate demo certificates: `npm run generate-test-ssl` (creates `demo.key` and `demo.crt`).
- Set `CLIENT_CERT_ALLOW_SELF_SIGNED=true`, `KMS_SERVER_CERT_ALLOW_SELF_SIGNED=true`, and `AWM_SERVER_CERT_ALLOW_SELF_SIGNED=true`.
- Set `CLIENT_CERT_ALLOW_SELF_SIGNED=true`, `KEY_PROVIDER_SERVER_CERT_ALLOW_SELF_SIGNED=true`, and `AWM_SERVER_CERT_ALLOW_SELF_SIGNED=true`.
- Use the demo certificates for all certificate paths (server and client).
- **Important:** Demo certificates and self-signed configurations should never be used in production.

Expand All @@ -499,7 +499,7 @@ For local testing, you can generate and use demo certificates with the self-sign
1. **Use CA-signed certificates** instead of self-signed.
2. **Set `CLIENT_CERT_ALLOW_SELF_SIGNED=false`** and server-specific allow self-signed flags to `false` in production.
3. **Configure client certificate allowlisting** with `MTLS_ALLOWED_CLIENT_FINGERPRINTS`.
4. **Use separate certificates** for each service (server, AWM client, KMS client).
4. **Use separate certificates** for each service (server, AWM client, key provider client).
5. **Regularly rotate certificates**.
6. **Secure private key storage** and use appropriate file permissions.
7. **Always use `TLS_MODE=mtls`** in production environments.
Expand All @@ -519,7 +519,7 @@ The output format is: `sha256:AB:CD:EF:...` which you can use in the configurati
#### Certificate Requirements for Production

- All certificates should be CA-signed certificates issued by your organization's PKI.
- Each service must use separate certificates (server cert, AWM client cert, KMS client cert).
- Each service must use separate certificates (server cert, AWM client cert, key provider client cert).
- Client certificates for outbound connections must be different from server certificates.
- Store private keys in secure locations with restricted file permissions:
```bash
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# AWS HSM KMS Implementation Documentation
# AWS HSM Key Provider Implementation Documentation

This document provides a reference implementation for integrating the 4 KMS API's with AWS HSM, covering the complete request-response flow from API handlers to HSM operations.
This document provides a reference implementation for integrating the 4 key provider API's with AWS HSM, covering the complete request-response flow from API handlers to HSM operations.

## ⚠️ Security Recommendation

For production KMS implementations, consider implementing the KMS-API in a C++ like language, because JavaScript does not support low-level memory management. Depending on your solution, direct memory management with explicit memory allocation/deallocation might be desirable.
For production key provider implementations, consider implementing the key provider API in a C++ like language, because JavaScript does not support low-level memory management. Depending on your solution, direct memory management with explicit memory allocation/deallocation might be desirable.

Also consider implementing low level cryptographic operations using low-level languages like C++ or Rust. They typically provide easier and more efficient data manipulation and transaformation.

Expand All @@ -14,7 +14,7 @@ When working with AWS HSM, adhere to their guidances and best practices for the

## API Overview

The KMS API provides secure key management through four main endpoints that integrate with AWS HSM:
The key provider API provides secure key management through four main endpoints that integrate with AWS HSM:

- `POST /key` - Store private keys using envelope encryption
- `GET /key/{pub}` - Retrieve private keys using envelope decryption
Expand All @@ -25,10 +25,10 @@ The KMS API provides secure key management through four main endpoints that inte
All 4 API's implementation should follow roughly the same dataflow as outlined bellow:

```
API Request → Handler → KMS Provider → AWS HSM → KMS Provider → Database (if required) → Response
API Request → Handler → key provider → AWS HSM → key provider → Database (if required) → Response
```

A KMS provider is the implementation of the code that is in charge of making the necessary calls to the HSM directly. You might have multiple providers in your solution, one for each 3rd party HSM that you wish to use, for example.
A key provider is the implementation of the code that is in charge of making the necessary calls to the HSM directly. You might have multiple providers in your solution, one for each 3rd party HSM that you wish to use, for example.

### Handler-to-Provider Mapping

Expand All @@ -41,10 +41,10 @@ A KMS provider is the implementation of the code that is in charge of making the

## Envelope Encryption Pattern (Recommended)

We recommend using a 3 level key encryption to store and protect the private keys of your advanced wallets.
The 3 levels consist of the root-level key from the KMS, 2nd level data keys generated by the root level key, and the 3rd level private keys used by your wallets directly.
We recommend using a 3 level key encryption to store and protect the private keys of your advanced wallets.
The 3 levels consist of the root-level key from the KMS/HSM, 2nd level data keys generated by the root level key, and the 3rd level private keys used by your wallets directly.

### Layer 1: KMS Keys (AWS HSM)
### Layer 1: Root Keys (AWS HSM)
- **Key spec**: `SYMMETRIC_DEFAULT`
- **Algorithm**: AES-256-GCM, used by keys generated using the specification `SYMMETRIC_DEFAULT`
- **Generation**: AWS HSM
Expand All @@ -67,7 +67,7 @@ The 3 levels consist of the root-level key from the KMS, 2nd level data keys gen

### Root Key Creation

This following needs to be only run once. The KMS should be functional with just one root-level key.
This following needs to be only run once. The key provider should be functional with just one root-level key.

```typescript
import * as awskms from '@aws-sdk/client-kms';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# Dinamo HSM KMS Implementation Documentation
# Dinamo HSM Key Provider Implementation Documentation

## ⚠️ Security Recommendation

**For production KMS implementations, consider implementing the KMS-API in a C++ like language, or use typed arrays like Uint8Array for all sensitive data because JavaScript does not support secure memory management.**
**For production key provider implementations, consider implementing the key provider API in a C++ like language, or use typed arrays like Uint8Array for all sensitive data because JavaScript does not support secure memory management.**

**Recommended Alternatives:**
- **C++/Rust**: Languages with explicit memory management and secure allocation
- **Node.js Typed Arrays**: Use `Uint8Array` for sensitive data with explicit zeroing
- **Native Addons**: Implement cryptographic operations in native C++ modules
- **Hardware Security**: Use HSM-backed secure memory when available

This document provides a reference implementation for integrating the 4 KMS API's with Dinamo HSM, covering the complete request-response flow from API handlers to HSM operations.
This document provides a reference implementation for integrating the 4 key provider API's with Dinamo HSM, covering the complete request-response flow from API handlers to HSM operations.

## Demo Scripts

Expand All @@ -20,7 +20,7 @@ This document provides a reference implementation for integrating the 4 KMS API'

## Quick Overview

The KMS API provides secure key management through four main endpoints that integrate with Dinamo HSM:
The key provider API provides secure key management through four main endpoints that integrate with Dinamo HSM:

- `POST /key` - Store private keys using envelope encryption
- `GET /key/{pub}` - Retrieve private keys using envelope decryption
Expand All @@ -30,7 +30,7 @@ The KMS API provides secure key management through four main endpoints that inte
## Architecture Flow

```
API Request → Handler → KMS Provider → Dinamo HSM → Database → Response
API Request → Handler → key provider → Dinamo HSM → Database → Response
```

### Handler-to-Provider Mapping
Expand Down
20 changes: 10 additions & 10 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@ services:
- TLS_MODE=disabled
- CLIENT_CERT_ALLOW_SELF_SIGNED=true

# KMS settings (required)
- KMS_URL=http://172.20.0.1:3000 # UPDATE TO YOUR OWN KMS URL
- KMS_SERVER_CERT_ALLOW_SELF_SIGNED=true

# Optional KMS TLS settings (uncomment if using mTLS with KMS)
# - KMS_SERVER_CA_CERT_PATH=/path/to/kms-ca-cert.pem
# - KMS_CLIENT_TLS_KEY_PATH=/path/to/kms-client-key.pem
# - KMS_CLIENT_TLS_CERT_PATH=/path/to/kms-client-cert.pem
# - KMS_CLIENT_TLS_KEY=<key-content>
# - KMS_CLIENT_TLS_CERT=<cert-content>
# Key provider settings (required)
- KEY_PROVIDER_URL=http://172.20.0.1:3000 # UPDATE TO YOUR OWN key provider URL
- KEY_PROVIDER_SERVER_CERT_ALLOW_SELF_SIGNED=true

# Optional key provider TLS settings (uncomment if using mTLS with key provider)
# - KEY_PROVIDER_SERVER_CA_CERT_PATH=/path/to/key-provider-ca-cert.pem
# - KEY_PROVIDER_CLIENT_TLS_KEY_PATH=/path/to/key-provider-client-key.pem
# - KEY_PROVIDER_CLIENT_TLS_CERT_PATH=/path/to/key-provider-client-cert.pem
# - KEY_PROVIDER_CLIENT_TLS_KEY=<key-content>
# - KEY_PROVIDER_CLIENT_TLS_CERT=<cert-content>

# Optional server TLS settings (uncomment if using mTLS)
# - SERVER_TLS_KEY_PATH=/path/to/server-key.pem
Expand Down
Loading
Loading