|
1 | | -# Enclaved Express |
| 1 | +# Enclaved BitGo Express |
2 | 2 |
|
3 | | -Enclaved Express is a secure signer implementation for cryptocurrency operations. It's designed to run in a secure enclave environment with flexible security options. |
| 3 | +A secure, mTLS-enabled cryptocurrency signing server with two operational modes: Enclaved Express (dedicated signer) and Master Express (API gateway with integrated signing capabilities). |
4 | 4 |
|
5 | 5 | ## Overview |
6 | 6 |
|
7 | | -This module provides a lightweight, dedicated signing server with these features: |
| 7 | +This application provides secure cryptocurrency operations with mutual TLS (mTLS) authentication: |
8 | 8 |
|
9 | | -- Focused on signing operations only - no BitGo API dependencies |
10 | | -- Optional TLS security for secure connections |
11 | | -- Client certificate validation when operating in mTLS mode |
12 | | -- Simple configuration and deployment |
| 9 | +- **Enclaved Mode**: Lightweight signing server for secure key operations |
| 10 | +- **Master Express Mode**: Full BitGo Express functionality with integrated signing |
| 11 | +- **mTLS Security**: Client certificate validation for secure communications |
| 12 | +- **Flexible Configuration**: Environment-based setup with file or variable-based certificates |
13 | 13 |
|
14 | | -## Supported Operations |
| 14 | +## Architecture |
15 | 15 |
|
16 | | -Currently, the following operations are supported: |
17 | | - |
18 | | -- `/ping` - Health check endpoint |
| 16 | +- **Enclaved Express** (Port 3080): Focused signing operations with KMS integration |
| 17 | +- **Master Express** (Port 3081): Full BitGo API functionality with secure communication to Enclaved Express |
19 | 18 |
|
20 | 19 | ## Configuration |
21 | 20 |
|
22 | | -Configuration is done via environment variables: |
| 21 | +Configuration is managed through environment variables: |
23 | 22 |
|
24 | 23 | ### Required Settings |
25 | 24 |
|
26 | | -- `APP_MODE` - Application mode (required, must be either "enclaved" or "master-express") |
| 25 | +- `APP_MODE` - Application mode (required: "enclaved" or "master-express") |
27 | 26 |
|
28 | 27 | ### Network Settings |
29 | 28 |
|
30 | | -- `PORT` - Port to listen on (default: 3080) |
31 | 29 | - `BIND` - Address to bind to (default: localhost) |
32 | 30 | - `TIMEOUT` - Request timeout in milliseconds (default: 305000) |
| 31 | +- `KEEP_ALIVE_TIMEOUT` - Keep-alive timeout (optional) |
| 32 | +- `HEADERS_TIMEOUT` - Headers timeout (optional) |
33 | 33 |
|
34 | | -### TLS Settings |
| 34 | +#### Enclaved Mode Specific |
35 | 35 |
|
36 | | -- `MASTER_BITGO_EXPRESS_KEYPATH` - Path to server key file (required for TLS) |
37 | | -- `MASTER_BITGO_EXPRESS_CRTPATH` - Path to server certificate file (required for TLS) |
38 | | -- `MTLS_ENABLED` - Enable mTLS mode (default: false) |
39 | | -- `MTLS_REQUEST_CERT` - Whether to request client certificates (default: false) |
40 | | -- `MTLS_REJECT_UNAUTHORIZED` - Whether to reject unauthorized connections (default: false) |
41 | | -- `MTLS_ALLOWED_CLIENT_FINGERPRINTS` - Comma-separated list of allowed client certificate fingerprints (optional) |
| 36 | +- `ENCLAVED_EXPRESS_PORT` - Port to listen on (default: 3080) |
| 37 | +- `KMS_URL` - KMS service URL (required) |
| 38 | + |
| 39 | +#### Master Express Mode Specific |
| 40 | + |
| 41 | +- `MASTER_EXPRESS_PORT` - Port to listen on (default: 3081) |
| 42 | +- `BITGO_ENV` - BitGo environment (default: test) |
| 43 | +- `BITGO_DISABLE_ENV_CHECK` - Disable environment check (default: true) |
| 44 | +- `BITGO_AUTH_VERSION` - Authentication version (default: 2) |
| 45 | +- `BITGO_CUSTOM_ROOT_URI` - Custom BitGo API root URI (optional) |
| 46 | +- `BITGO_CUSTOM_BITCOIN_NETWORK` - Custom Bitcoin network (optional) |
| 47 | +- `ENCLAVED_EXPRESS_URL` - Enclaved Express server URL (required) |
| 48 | +- `ENCLAVED_EXPRESS_CERT` - Path to Enclaved Express server certificate (required) |
| 49 | + |
| 50 | +### TLS/mTLS Configuration |
| 51 | + |
| 52 | +Both modes use the same TLS configuration variables: |
| 53 | + |
| 54 | +#### TLS Mode |
42 | 55 |
|
43 | | -### Master Express Settings |
| 56 | +- `TLS_MODE` - Set to either "mtls" or "disabled" (defaults to "mtls" if not set) |
44 | 57 |
|
45 | | -- `BITGO_PORT` - Port to listen on (default: 3080) |
46 | | -- `BITGO_BIND` - Address to bind to (default: localhost) |
47 | | -- `BITGO_ENV` - Environment name (default: test) |
48 | | -- `BITGO_ENABLE_SSL` - Enable SSL and certificate verification (default: true) |
49 | | -- `BITGO_ENABLE_PROXY` - Enable proxy (default: true) |
50 | | -- `ENCLAVED_EXPRESS_URL` - URL of the enclaved express server (required) |
51 | | -- `ENCLAVED_EXPRESS_SSL_CERT` - Path to the enclaved express server's SSL certificate (required) |
| 58 | +#### Certificate Configuration (required when TLS_MODE=mtls) |
52 | 59 |
|
53 | | -### Other Settings |
| 60 | +**Option 1: Certificate Files** |
| 61 | + |
| 62 | +- `TLS_KEY_PATH` - Path to private key file |
| 63 | +- `TLS_CERT_PATH` - Path to certificate file |
| 64 | + |
| 65 | +**Option 2: Environment Variables** |
| 66 | + |
| 67 | +- `TLS_KEY` - Private key content (PEM format) |
| 68 | +- `TLS_CERT` - Certificate content (PEM format) |
| 69 | + |
| 70 | +#### mTLS Settings (when TLS_MODE=mtls) |
| 71 | + |
| 72 | +- `MTLS_REQUEST_CERT` - Request client certificates (default: true) |
| 73 | +- `ALLOW_SELF_SIGNED` - Allow self-signed certificates (default: false) |
| 74 | +- `MTLS_ALLOWED_CLIENT_FINGERPRINTS` - Comma-separated list of allowed client certificate fingerprints (optional) |
| 75 | + |
| 76 | +### Logging and Debug |
54 | 77 |
|
55 | 78 | - `LOGFILE` - Path to log file (optional) |
56 | | -- `DEBUG` - Debug namespaces to enable (e.g., 'enclaved:\*') |
| 79 | +- `DEBUG_NAMESPACE` - Debug namespaces to enable (e.g., 'enclaved:\*') |
| 80 | + |
| 81 | +## Quick Start |
57 | 82 |
|
58 | | -## Running Enclaved Express |
| 83 | +### 1. Generate Test Certificates |
59 | 84 |
|
60 | | -### Basic Setup (HTTP only) |
| 85 | +First, create self-signed certificates for testing: |
61 | 86 |
|
62 | 87 | ```bash |
63 | | -yarn start --port 3080 |
64 | | -``` |
| 88 | +# Generate private key |
| 89 | +openssl genrsa -out server.key 2048 |
65 | 90 |
|
66 | | -### TLS Setup (with mTLS) |
| 91 | +# Generate certificate |
| 92 | +openssl req -new -x509 -key server.key -out server.crt -days 365 -subj "/CN=localhost" |
| 93 | +``` |
67 | 94 |
|
68 | | -For testing purposes, you can use self-signed certificates with relaxed verification: |
| 95 | +### 2. Start Enclaved Express |
69 | 96 |
|
70 | 97 | ```bash |
71 | 98 | APP_MODE=enclaved \ |
72 | | -MASTER_BITGO_EXPRESS_PORT=3080 \ |
73 | | -MASTER_BITGO_EXPRESS_BIND=localhost \ |
74 | | -MASTER_BITGO_EXPRESS_KEYPATH=./test-ssl-key.pem \ |
75 | | -MASTER_BITGO_EXPRESS_CRTPATH=./test-ssl-cert.pem \ |
76 | | -MTLS_ENABLED=true \ |
| 99 | +KMS_URL=https://your-kms-service \ |
| 100 | +TLS_KEY_PATH=./server.key \ |
| 101 | +TLS_CERT_PATH=./server.crt \ |
77 | 102 | MTLS_REQUEST_CERT=true \ |
78 | | -MTLS_REJECT_UNAUTHORIZED=false \ |
| 103 | +ALLOW_SELF_SIGNED=true \ |
79 | 104 | yarn start |
80 | 105 | ``` |
81 | 106 |
|
82 | | -### Connecting from Master Express |
| 107 | +### 3. Start Master Express |
83 | 108 |
|
84 | | -To connect to Enclaved Express from the Master Express server: |
| 109 | +In a separate terminal: |
85 | 110 |
|
86 | 111 | ```bash |
87 | 112 | APP_MODE=master-express \ |
88 | | -BITGO_PORT=3080 \ |
89 | | -BITGO_BIND=localhost \ |
90 | 113 | BITGO_ENV=test \ |
91 | | -BITGO_KEYPATH=./test-ssl-key.pem \ |
92 | | -BITGO_CRTPATH=./test-ssl-cert.pem \ |
93 | | -ENCLAVED_EXPRESS_URL=https://localhost:4000 \ |
94 | | -ENCLAVED_EXPRESS_SSL_CERT=./enclaved-express-cert.pem \ |
95 | | -BITGO_ENABLE_SSL=false \ |
| 114 | +TLS_KEY_PATH=./server.key \ |
| 115 | +TLS_CERT_PATH=./server.crt \ |
| 116 | +ENCLAVED_EXPRESS_URL=https://localhost:3080 \ |
| 117 | +ENCLAVED_EXPRESS_CERT=./server.crt \ |
| 118 | +MTLS_REQUEST_CERT=false \ |
| 119 | +ALLOW_SELF_SIGNED=true \ |
| 120 | +yarn start |
| 121 | +``` |
| 122 | + |
| 123 | +### 4. Test the Connection |
| 124 | + |
| 125 | +Test that Master Express can communicate with Enclaved Express: |
| 126 | + |
| 127 | +```bash |
| 128 | +curl -k -X POST https://localhost:3081/ping/enclavedExpress |
| 129 | +``` |
| 130 | + |
| 131 | +## Production Configuration |
| 132 | + |
| 133 | +### Security Best Practices |
| 134 | + |
| 135 | +1. **Use CA-signed certificates** instead of self-signed |
| 136 | +2. **Set `ALLOW_SELF_SIGNED=false`** in production |
| 137 | +3. **Configure client certificate allowlisting** with `MTLS_ALLOWED_CLIENT_FINGERPRINTS` |
| 138 | +4. **Use separate certificates** for each service |
| 139 | +5. **Regularly rotate certificates** |
| 140 | +6. **Secure private key storage** |
| 141 | + |
| 142 | +### Production Setup Example |
| 143 | + |
| 144 | +#### Enclaved Express (Production) |
| 145 | + |
| 146 | +```bash |
| 147 | +APP_MODE=enclaved \ |
| 148 | +KMS_URL=https://production-kms.example.com \ |
| 149 | +TLS_KEY_PATH=/secure/path/enclaved.key \ |
| 150 | +TLS_CERT_PATH=/secure/path/enclaved.crt \ |
| 151 | +MTLS_REQUEST_CERT=true \ |
| 152 | +ALLOW_SELF_SIGNED=false \ |
| 153 | +MTLS_ALLOWED_CLIENT_FINGERPRINTS=ABC123...,DEF456... \ |
96 | 154 | yarn start |
97 | 155 | ``` |
98 | 156 |
|
99 | | -## Understanding mTLS Configuration |
| 157 | +#### Master Express (Production) |
100 | 158 |
|
101 | | -### Server Side (Enclaved Express) |
| 159 | +```bash |
| 160 | +APP_MODE=master-express \ |
| 161 | +BITGO_ENV=prod \ |
| 162 | +TLS_KEY_PATH=/secure/path/master.key \ |
| 163 | +TLS_CERT_PATH=/secure/path/master.crt \ |
| 164 | +ENCLAVED_EXPRESS_URL=https://enclaved.internal.example.com:3080 \ |
| 165 | +ENCLAVED_EXPRESS_CERT=/secure/path/enclaved.crt \ |
| 166 | +MTLS_REQUEST_CERT=true \ |
| 167 | +ALLOW_SELF_SIGNED=false \ |
| 168 | +yarn start |
| 169 | +``` |
102 | 170 |
|
103 | | -- Uses both certificate and key files |
104 | | -- The key file (`test-ssl-key.pem`) is used to prove the server's identity |
105 | | -- The certificate file (`test-ssl-cert.pem`) is what the server presents to clients |
| 171 | +## API Endpoints |
106 | 172 |
|
107 | | -### Client Side (Regular Express) |
| 173 | +### Enclaved Express (Port 3080) |
108 | 174 |
|
109 | | -- For testing, only needs the server's certificate |
110 | | -- `rejectUnauthorized: false` allows testing without strict certificate verification |
111 | | -- In production, proper client certificates should be used |
| 175 | +- `POST /ping` - Health check |
| 176 | +- `GET /version` - Version information |
| 177 | +- `POST /:coin/key/independentKey` - Generate independent keychain |
112 | 178 |
|
113 | | -## Security Considerations |
| 179 | +### Master Express (Port 3081) |
114 | 180 |
|
115 | | -- The testing configuration (`MTLS_REJECT_UNAUTHORIZED=false`) should only be used in development |
116 | | -- In production: |
117 | | - - Use proper CA-signed certificates |
118 | | - - Enable strict certificate verification |
119 | | - - Use client certificate allowlisting |
120 | | - - Keep private keys secure |
121 | | - - Regularly rotate certificates |
| 181 | +- `POST /ping` - Health check |
| 182 | +- `GET /version` - Version information |
| 183 | +- `POST /ping/enclavedExpress` - Test connection to Enclaved Express |
| 184 | +- `POST /api/:coin/wallet/generate` - Generate wallet (with Enclaved Express integration) |
122 | 185 |
|
123 | 186 | ## Troubleshooting |
124 | 187 |
|
125 | 188 | ### Common Issues |
126 | 189 |
|
127 | | -1. **Certificate Errors** |
| 190 | +#### 1. Certificate Loading Errors |
128 | 191 |
|
129 | | - - Ensure paths to certificate files are correct |
130 | | - - Check file permissions on certificate files |
131 | | - - Verify certificate format is correct |
| 192 | +```bash |
| 193 | +# Check certificate file paths and permissions |
| 194 | +ls -la /path/to/certificates/ |
| 195 | +# Verify certificate format |
| 196 | +openssl x509 -in certificate.crt -text -noout |
| 197 | +``` |
| 198 | + |
| 199 | +#### 2. mTLS Authentication Failures |
| 200 | + |
| 201 | +- Verify client certificates are provided |
| 202 | +- Check `ALLOW_SELF_SIGNED` setting matches certificate type |
| 203 | +- Confirm client certificate fingerprints are in allowlist |
| 204 | +- Ensure both services use compatible TLS settings |
| 205 | + |
| 206 | +#### 3. Connection Refused |
| 207 | + |
| 208 | +- Verify both services are running on correct ports |
| 209 | +- Check firewall settings |
| 210 | +- Confirm URLs use `https://` prefix |
| 211 | +- Test basic connectivity with curl |
132 | 212 |
|
133 | | -2. **Connection Issues** |
| 213 | +#### 4. Environment Variable Issues |
134 | 214 |
|
135 | | - - Verify ports are not in use |
136 | | - - Check firewall settings |
137 | | - - Ensure URLs are correct (including https:// prefix) |
| 215 | +```bash |
| 216 | +# Check that required variables are set |
| 217 | +env | grep -E "(APP_MODE|KMS_URL|ENCLAVED_EXPRESS|TLS_)" |
| 218 | +``` |
| 219 | + |
| 220 | +### Debug Mode |
138 | 221 |
|
139 | | -3. **mTLS Errors** |
140 | | - - Verify mTLS is enabled on both sides |
141 | | - - Check certificate configuration |
142 | | - - Ensure client certificate is trusted by server |
| 222 | +Enable debug logging for detailed troubleshooting: |
| 223 | + |
| 224 | +```bash |
| 225 | +DEBUG_NAMESPACE=enclaved:*,master:* yarn start |
| 226 | +``` |
143 | 227 |
|
144 | 228 | ## License |
145 | 229 |
|
|
0 commit comments