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