-
Notifications
You must be signed in to change notification settings - Fork 0
feat: setup enclaved bitgo express with mTLS support #1
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
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
89f60fc
feat: initial project setup
pranavjain97 b8c1fc7
feat: add core express implementation with mTLS
pranavjain97 44e3eff
chore: add config type to request
pranavjain97 1a36767
chore: cleanup modules, compilable state
pranavjain97 442c3ce
feat: add README to test it with master express
pranavjain97 e5c1d09
chore: add CI for lint, build and tests
pranavjain97 daaa741
chore: add the pull request yaml to use github workflows
pranavjain97 bb3ecd0
chore: add yarn.lock
pranavjain97 00bdafa
chore: fix all linting issues
pranavjain97 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| module.exports = { | ||
| parser: '@typescript-eslint/parser', | ||
| extends: ['plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'], | ||
| parserOptions: { | ||
| ecmaVersion: 2018, | ||
| sourceType: 'module', | ||
| }, | ||
| rules: { | ||
| '@typescript-eslint/explicit-function-return-type': 'off', | ||
| '@typescript-eslint/no-explicit-any': 'off', | ||
| '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], | ||
| }, | ||
| ignorePatterns: ['dist/**/*', 'node_modules/**/*'], | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| name: Build & Test (CI) | ||
|
|
||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| node-version: | ||
| description: 'Node.js version to use' | ||
| type: string | ||
| default: '20.18.0' | ||
|
|
||
| jobs: | ||
| build: | ||
| name: Build | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: ${{ inputs.node-version }} | ||
| cache: 'yarn' | ||
|
|
||
| - name: Install dependencies | ||
| run: yarn install | ||
|
|
||
| - name: Build | ||
| run: yarn build | ||
|
|
||
| lint: | ||
| name: Run lint | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: ${{ inputs.node-version }} | ||
| cache: 'yarn' | ||
|
|
||
| - name: Install dependencies | ||
| run: yarn install | ||
|
|
||
| - name: Lint | ||
| run: yarn lint | ||
|
|
||
| test: | ||
| name: Test | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: ${{ inputs.node-version }} | ||
| cache: 'yarn' | ||
|
|
||
| - name: Install dependencies | ||
| run: yarn install | ||
|
|
||
| - name: Generate test SSL certificates | ||
| run: yarn generate-test-ssl | ||
|
|
||
| - name: Test | ||
| run: yarn test | ||
| env: | ||
| MASTER_BITGO_EXPRESS_KEYPATH: ./test-ssl-key.pem | ||
| MASTER_BITGO_EXPRESS_CRTPATH: ./test-ssl-cert.pem | ||
| MTLS_ENABLED: true | ||
| MTLS_REQUEST_CERT: true | ||
| MTLS_REJECT_UNAUTHORIZED: false |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| name: on_pr | ||
| run-name: "on_pr: ${{ github.event.pull_request.number }}" | ||
|
|
||
| on: | ||
| pull_request: | ||
|
|
||
| permissions: | ||
| actions: read # required by BitGo/build-system | ||
| contents: read # required by BitGo/build-system | ||
| id-token: write # required by BitGo/build-system | ||
| pull-requests: write # required by Grype PR commenter | ||
| packages: read # required for ArgoCD deploy | ||
|
|
||
| jobs: | ||
| build-and-test: | ||
| name: Build & Test (CI) | ||
| uses: ./.github/workflows/build-and-test.yaml |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| dist/ | ||
| node_modules/ | ||
| coverage/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| !dist/ | ||
| .nyc_output/ | ||
| tsconfig.json | ||
| src/ | ||
| test/ | ||
| *.tgz |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "singleQuote": true, | ||
| "trailingComma": "all", | ||
| "printWidth": 100, | ||
| "tabWidth": 2, | ||
| "semi": true | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,120 @@ | ||
| # enclaved-bitgo-express | ||
| Enclaved BitGo Express for Advanced Key Management | ||
| # Enclaved Express | ||
|
|
||
| Enclaved Express is a secure signer implementation for cryptocurrency operations. It's designed to run in a secure enclave environment with flexible security options. | ||
|
|
||
| ## Overview | ||
|
|
||
| This module provides a lightweight, dedicated signing server with these features: | ||
|
|
||
| - Focused on signing operations only - no BitGo API dependencies | ||
| - Optional TLS security for secure connections | ||
| - Client certificate validation when operating in mTLS mode | ||
| - Simple configuration and deployment | ||
|
|
||
| ## Supported Operations | ||
|
|
||
| Currently, the following operations are supported: | ||
|
|
||
| - `/ping` - Health check endpoint | ||
|
|
||
| ## Configuration | ||
|
|
||
| Configuration is done via environment variables: | ||
|
|
||
| ### Network Settings | ||
|
|
||
| - `PORT` - Port to listen on (default: 3080) | ||
| - `BIND` - Address to bind to (default: localhost) | ||
| - `TIMEOUT` - Request timeout in milliseconds (default: 305000) | ||
|
|
||
| ### TLS Settings | ||
|
|
||
| - `MASTER_BITGO_EXPRESS_KEYPATH` - Path to server key file (required for TLS) | ||
| - `MASTER_BITGO_EXPRESS_CRTPATH` - Path to server certificate file (required for TLS) | ||
| - `MTLS_ENABLED` - Enable mTLS mode (default: false) | ||
| - `MTLS_REQUEST_CERT` - Whether to request client certificates (default: false) | ||
| - `MTLS_REJECT_UNAUTHORIZED` - Whether to reject unauthorized connections (default: false) | ||
| - `MTLS_ALLOWED_CLIENT_FINGERPRINTS` - Comma-separated list of allowed client certificate fingerprints (optional) | ||
|
|
||
| ### Other Settings | ||
|
|
||
| - `LOGFILE` - Path to log file (optional) | ||
| - `DEBUG` - Debug namespaces to enable (e.g., 'enclaved:*') | ||
|
|
||
| ## Running Enclaved Express | ||
|
|
||
| ### Basic Setup (HTTP only) | ||
|
|
||
| ```bash | ||
| yarn start --port 3080 | ||
| ``` | ||
|
|
||
| ### TLS Setup (with mTLS) | ||
|
|
||
| For testing purposes, you can use self-signed certificates with relaxed verification: | ||
|
|
||
| ```bash | ||
| MASTER_BITGO_EXPRESS_KEYPATH=./test-ssl-key.pem \ | ||
| MASTER_BITGO_EXPRESS_CRTPATH=./test-ssl-cert.pem \ | ||
| MTLS_ENABLED=true \ | ||
| MTLS_REQUEST_CERT=true \ | ||
| MTLS_REJECT_UNAUTHORIZED=false \ | ||
| yarn start --port 3080 | ||
| ``` | ||
|
|
||
| ### Connecting from Regular Express | ||
|
|
||
| To connect to Enclaved Express from the regular Express server: | ||
|
|
||
| ```bash | ||
| yarn start --port 4000 \ | ||
| --enclavedExpressUrl='https://localhost:3080' \ | ||
| --enclavedExpressSSLCert='./test-ssl-cert.pem' \ | ||
| --disableproxy \ | ||
| --debug | ||
| ``` | ||
|
|
||
| ## Understanding mTLS Configuration | ||
|
|
||
| ### Server Side (Enclaved Express) | ||
| - Uses both certificate and key files | ||
| - The key file (`test-ssl-key.pem`) is used to prove the server's identity | ||
| - The certificate file (`test-ssl-cert.pem`) is what the server presents to clients | ||
|
|
||
| ### Client Side (Regular Express) | ||
| - For testing, only needs the server's certificate | ||
| - `rejectUnauthorized: false` allows testing without strict certificate verification | ||
| - In production, proper client certificates should be used | ||
|
|
||
| ## Security Considerations | ||
|
|
||
| - The testing configuration (`MTLS_REJECT_UNAUTHORIZED=false`) should only be used in development | ||
| - In production: | ||
| - Use proper CA-signed certificates | ||
| - Enable strict certificate verification | ||
| - Use client certificate allowlisting | ||
| - Keep private keys secure | ||
| - Regularly rotate certificates | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### Common Issues | ||
|
|
||
| 1. **Certificate Errors** | ||
| - Ensure paths to certificate files are correct | ||
| - Check file permissions on certificate files | ||
| - Verify certificate format is correct | ||
|
|
||
| 2. **Connection Issues** | ||
| - Verify ports are not in use | ||
| - Check firewall settings | ||
| - Ensure URLs are correct (including https:// prefix) | ||
|
|
||
| 3. **mTLS Errors** | ||
| - Verify mTLS is enabled on both sides | ||
| - Check certificate configuration | ||
| - Ensure client certificate is trusted by server | ||
|
|
||
| ## License | ||
|
|
||
| MIT | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| #!/usr/bin/env node | ||
|
|
||
| // TODO: Remove this unhandledRejection hook once BG-49996 is implemented. | ||
| process.on('unhandledRejection', (reason, promise) => { | ||
| console.error('----- Unhandled Rejection at -----'); | ||
| console.error(promise); | ||
| console.error('----- Reason -----'); | ||
| console.error(reason); | ||
| }); | ||
|
|
||
| const { init } = require('../dist/src/enclavedApp'); | ||
|
|
||
| if (require.main === module) { | ||
| init().catch((err) => { | ||
| console.log(`Fatal error: ${err.message}`); | ||
| console.log(err.stack); | ||
| }); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| module.exports = { | ||
| preset: 'ts-jest', | ||
| testEnvironment: 'node', | ||
| roots: ['<rootDir>/src'], | ||
| testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'], | ||
| transform: { | ||
| '^.+\\.ts$': 'ts-jest', | ||
| }, | ||
| moduleFileExtensions: ['ts', 'js', 'json', 'node'], | ||
| collectCoverage: true, | ||
| coverageDirectory: 'coverage', | ||
| coverageReporters: ['text', 'lcov'], | ||
| verbose: true, | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| { | ||
| "name": "@bitgo/enclaved-bitgo-express", | ||
| "version": "1.0.0", | ||
| "description": "BitGo Enclaved Express - Secure enclave for BitGo signing operations with mTLS", | ||
| "main": "./dist/src/index.js", | ||
| "types": "./dist/src/index.d.ts", | ||
| "bin": { | ||
| "enclaved-bitgo-express": "./bin/enclaved-bitgo-express" | ||
| }, | ||
| "scripts": { | ||
| "start": "node bin/enclaved-bitgo-express", | ||
| "build": "yarn tsc --build --incremental --verbose . && cp package.json dist/", | ||
| "test": "jest", | ||
| "test:watch": "jest --watch", | ||
| "test:coverage": "jest --coverage", | ||
| "lint": "eslint --quiet .", | ||
| "generate-test-ssl": "openssl req -x509 -newkey rsa:2048 -keyout test-ssl-key.pem -out test-ssl-cert.pem -days 365 -nodes -subj '/CN=localhost'" | ||
| }, | ||
| "dependencies": { | ||
| "body-parser": "^1.20.3", | ||
| "connect-timeout": "^1.9.0", | ||
| "debug": "^3.1.0", | ||
| "express": "4.17.3", | ||
| "lodash": "^4.17.20", | ||
| "morgan": "^1.9.1" | ||
| }, | ||
| "devDependencies": { | ||
| "@types/body-parser": "^1.17.0", | ||
| "@types/connect-timeout": "^1.9.0", | ||
| "@types/debug": "^4.1.12", | ||
| "@types/express": "4.17.13", | ||
| "@types/jest": "^29.5.12", | ||
| "@types/lodash": "^4.14.121", | ||
| "@types/morgan": "^1.7.35", | ||
| "@types/node": "^16.18.46", | ||
| "@types/sinon": "^10.0.11", | ||
| "@types/supertest": "^2.0.11", | ||
| "@typescript-eslint/eslint-plugin": "^5.0.0", | ||
| "@typescript-eslint/parser": "^5.0.0", | ||
| "eslint": "^8.0.0", | ||
| "eslint-config-prettier": "^8.0.0", | ||
| "eslint-plugin-prettier": "^4.0.0", | ||
| "jest": "^29.7.0", | ||
| "nock": "^13.3.1", | ||
| "nyc": "^15.0.0", | ||
| "prettier": "^2.0.0", | ||
| "should": "^13.2.3", | ||
| "should-http": "^0.1.1", | ||
| "should-sinon": "^0.0.6", | ||
| "sinon": "^13.0.1", | ||
| "supertest": "^4.0.2", | ||
| "ts-jest": "^29.1.2", | ||
| "typescript": "^4.2.4" | ||
| }, | ||
| "engines": { | ||
| "node": ">=14" | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we have guidance/approval to use mit licesense ?