Skip to content

Commit

Permalink
WLT-135 After CR
Browse files Browse the repository at this point in the history
  • Loading branch information
nirfireblocks committed Jul 14, 2024
1 parent 079498f commit e89e38a
Show file tree
Hide file tree
Showing 22 changed files with 104 additions and 9,171 deletions.
20 changes: 12 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,20 @@ Fireblocks Agent is an open-source on-prem service written in Typescript which i
- `cd examples/server`
- `npm run build:docker`
- `npm run start:docker`
- Copy `.env.prod` and name it `.env.{env}` for example `.env.dev9`
- Edit your newly created `.env.{env}` file with the right config
- Start fireblocks agent with your desired env i.e `npm run start --env=prod`

- Configure and run Fireblocks agent:
- Copy `.env.prod` and name it `.env.{env-name}` (e.g. `.env.test`)
- Edit your newly created `.env.{env-name}` file with the right configuration
- Start the Fireblocks agent with your desired environment:
- `npm run start --env=env-name`

### Fireblocks Agent Environment Variables
The fireblocks agent expect a configuration file (for production it's called `.env.prod`) with several parameters:
The Fireblocks agent expect a configuration file (for production it's called `.env.prod`) with several parameters:
* `MOBILE_GATEWAY_URL` - In production this value should be `https://mobile-api.fireblocks.io`
* `CUSTOMER_SERVER_URL` - The client's custom server url
* `CUSTOMER_SERVER_PULL_CADENCE_MS` - Cadence of pulling messages status
* `CUSTOMER_SERVER_AUTHORIZATION` - If exists, the fireblocks agent will send its value on the `Authorization` header for each request. The client can use it for authorizing the fireblocks agent or keep track on which agent is calling it
* `CUSTOMER_SERVER_AUTHORIZATION` - If exists, the Fireblocks agent will send its value on the `Authorization` header for each request. The client can use it for authorizing the fireblocks agent or keep track on which agent is calling it
* `SSL_CERT_PATH` - If exists, a path to a self-signed SSL certificate which will be used to validate the server certificate


# About the Fireblocks Key Link Workspace
Expand All @@ -49,10 +53,10 @@ The Fireblocks Key Link workspace consists of several components (aka actors). E

* Console - Fireblocks web console. [Link](https://console.fireblocks.io/v2/)
* Mobile App - Fireblocks mobile app.
* Mobile API Gateway - Fireblocks REST API Server. The firblocks agent communicates with this server in the registration flow and for receiving new messages.
* Mobile API Gateway - Fireblocks REST API Server. The Fireblocks agent communicates with this server in the registration flow and for receiving new messages.
* Developer API - Fireblocks back office server for workspace setup and configuration.
* Fireblocks Agent - An on-prem service written in Typescript which is responsible for receiving new messages to sign from Fireblocks, relay these messages to the client's HSM and return the signed result back to Fireblocks.
* Customer Server - The client's own server which receives messages to sign from the fireblocks agent. Sign them via the client's HSM and provide the fireblocks agent with the signed messages.
* Customer Server - The client's own server which receives messages to sign from the Fireblocks agent. Sign them via the client's HSM and provide the Fireblocks agent with the signed messages.
* HSM component - The actual HSM implementation. Can be on prem or a cloud based HSM, or a different Key Management System.

## About the Customer Server
Expand All @@ -75,7 +79,7 @@ The entry point for the server can be found [here](examples/server/src/server.ts
![Pair the Fireblocks Agent Device flow](docs/flows/pair_device_sd.png)

### Add a Validator Key
This procedure should happen once. Fireblocks will need a validator key to approve new signing keys. This flow is done via the fireblocks sdk and not via this program.
This procedure should happen once. Fireblocks will need a validator key to approve new signing keys. This flow is done via the Fireblocks sdk and not via this program.

![Add validator key flow](docs/flows/add_validator_key.png)

Expand Down
22 changes: 21 additions & 1 deletion examples/server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,24 @@
This server implement an example integration with HSM module assuming SoftHSM.
- Hardcoded PIN used in the example is "1234"
- The example uses first available slot which is usually slot 0
- Current example supports only ECDSA secp256k1 curve.
- Current example supports ECDSA secp256k1 and EdDSA Ed25519 curves

# Support for self signed certificate
The server can support self signed certificate when accepting SSL connections from the Agent.
In order to run the server with self signed certificate, follow the following steps:
1. Make sure to have an openssl Subject Alternative Name (SAN) certificates configuration file
- You can find an example file at examples/server/env/san.cnf
2. Create a private key using openssl
- `openssl genrsa -out priv-key.txt 2048`
3. Create a Certificate certificate signing requests (CSR) file
- `openssl req -new -key priv-key.txt -out csr.txt -config san.cnf`
4. Create a self signed certificate
- `openssl x509 -req -days 3650 -in csr.txt -signkey priv-key.txt -out self-signed-cert.txt -extfile san.cnf -extensions v3_req`
5. Validate the self signed certificate has all the information required
- `openssl x509 -in self-signed-cert.txt -noout -text`
6. Add two parameters to your server environment file (e.g. /example/server/env/dev.env)
- `SELF_SIGNED_SSL_PRIV_KEY_PATH="./env/priv-key.txt"
SELF_SIGNED_SSL_CERT_PATH="./env/self-signed-cert.txt"`
7. Start the server, it will automatically run in SSL if the defined files are found
8. In order for the Agent to accept the self signed certificate, add the following to the Agent env file (e.g. .env.prod)
- `SSL_CERT_PATH="./examples/server/env/self-signed-cert.txt"`
4 changes: 1 addition & 3 deletions examples/server/env/dev.env
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
KNOWN_API_KEYS=""
SELF_SIGNED_SSL_PRIV_KEY_PATH="./env/example-private.key"
SELF_SIGNED_SSL_CERT_PATH="./env/example-self-signed-cert.crt"
KNOWN_API_KEYS=""
18 changes: 0 additions & 18 deletions examples/server/env/example-csr.csr

This file was deleted.

28 changes: 0 additions & 28 deletions examples/server/env/example-private.key

This file was deleted.

22 changes: 0 additions & 22 deletions examples/server/env/example-self-signed-cert.crt

This file was deleted.

2 changes: 1 addition & 1 deletion examples/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"start:dev": "NODE_ENV=dev nodemon ./src/server.ts",
"dev": "NODE_ENV=dev ts-node ./src/server.ts",
"build:docker": "npm run build:api && docker build -t softhsm2:2.6.1 .",
"start:docker": "npm run docker:volumes && docker compose up -d",
"start:docker": "npm run docker:volumes && docker compose up",
"initToken": "softhsm2-util --init-token --slot 0 --label test-token --pin 1234 --so-pin 4321",
"exportDER": "pkcs11-tool --module /usr/local/lib/softhsm/libsofthsm2.so --read-object --type pubkey --id 49b8e635db29a67cd7ea64ee2ec01d2d --output-file public_key.der",
"exportPEM": "openssl ec -inform DER -in public_key.der -pubin -outform PEM -out public_key.pem"
Expand Down
8 changes: 4 additions & 4 deletions examples/server/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,17 @@ app.use(helmet());
app.use(`/api`, apiRouter);

// Use HTTPS if private key and certificate are provided
logger.info(process.env.SELF_SIGNED_SSL_PRIV_KEY_PATH);
logger.info(process.env.SELF_SIGNED_SSL_CERT_PATH);
const ssl_priv_key_path = process.env.SELF_SIGNED_SSL_PRIV_KEY_PATH ?? '';
const ssl_cert_path = process.env.SELF_SIGNED_SSL_CERT_PATH ?? '';
if (fs.existsSync(process.env.SELF_SIGNED_SSL_PRIV_KEY_PATH) && fs.existsSync(process.env.SELF_SIGNED_SSL_CERT_PATH)) {
logger.info('Found private key and SSL certificate - Using HTTPS');
logger.info(`Found private key and SSL certificate - Using HTTPS`);
const sslOptions = {
key: fs.readFileSync(process.env.SELF_SIGNED_SSL_PRIV_KEY_PATH),
cert: fs.readFileSync(process.env.SELF_SIGNED_SSL_CERT_PATH),
};
https.createServer(sslOptions, app).listen(PORT, () => logger.info(SERVER_START_MSG));
}
else {
logger.info('Using HTTP');
logger.info(`Could not find private key ${ssl_priv_key_path} or SSL certificate ${ssl_cert_path} - Using HTTP`);
app.listen(PORT, () => logger.info(SERVER_START_MSG));
}
Loading

0 comments on commit e89e38a

Please sign in to comment.