Skip to content

Commit 465a8b5

Browse files
ribarakaAssem-Uber
andauthored
Add TLS Support for gRPC Connection (#885)
* TLS GRPC connection * docs: add TLS usage instructions for Docker * adding cache --------- Co-authored-by: Assem Hafez <[email protected]> Co-authored-by: Assem Hafez <[email protected]>
1 parent 9cf6009 commit 465a8b5

File tree

2 files changed

+64
-11
lines changed

2 files changed

+64
-11
lines changed

README.md

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@ This web UI is used to view workflows from [Cadence][cadence], see what's runnin
1313

1414
Set these environment variables if you need to change their defaults
1515

16-
| Variable | Description | Default |
17-
| ---------------------------- | --------------------------------------------- | ---------------- |
18-
| CADENCE_GRPC_PEERS | Comma-delimited list of gRPC peers | 127.0.0.1:7833 |
19-
| CADENCE_GRPC_SERVICES_NAMES | Comma-delimited list of gRPC services to call | cadence-frontend |
20-
| CADENCE_CLUSTERS_NAMES | Comma-delimited list of cluster names | cluster0 |
21-
| CADENCE_WEB_PORT | HTTP port to serve on | 8088 |
22-
| CADENCE_WEB_HOSTNAME | Host name to serve on | 0.0.0.0 |
23-
| CADENCE_ADMIN_SECURITY_TOKEN | Admin token for accessing admin methods | '' |
16+
| Variable | Description | Default |
17+
| ---------------------------- | ----------------------------------------------------------------------------- | ---------------- |
18+
| CADENCE_GRPC_PEERS | Comma-delimited list of gRPC peers | 127.0.0.1:7833 |
19+
| CADENCE_GRPC_SERVICES_NAMES | Comma-delimited list of gRPC services to call | cadence-frontend |
20+
| CADENCE_CLUSTERS_NAMES | Comma-delimited list of cluster names | cluster0 |
21+
| CADENCE_WEB_PORT | HTTP port to serve on | 8088 |
22+
| CADENCE_WEB_HOSTNAME | Host name to serve on | 0.0.0.0 |
23+
| CADENCE_ADMIN_SECURITY_TOKEN | Admin token for accessing admin methods | '' |
24+
| CADENCE_GRPC_TLS_CA_FILE | Path to root CA certificate file for enabling one-way TLS on gRPC connections | '' |
2425

2526
Note: To connect `cadence-web` to multiple clusters, you will need to add comma-delimted entries for `CADENCE_GRPC_PEERS`, `CADENCE_GRPC_SERVICES_NAMES` & `CADENCE_CLUSTERS_NAMES` for each cluster (each cluster values are grouped by their index within the Comma-delimited lists).
2627

@@ -39,6 +40,33 @@ The latest version of `cadence-web` is included in the `cadence` composed docker
3940
docker-compose -f docker/docker-compose.yml up
4041
```
4142

43+
### Using TLS for gRPC
44+
45+
You can run cadence-web with secure gRPC TLS communication by passing your CA certificate file to the container and configure the environment variable accordingly.
46+
47+
#### Steps to Pass the Certificate File in Docker
48+
49+
1. **Prepare your CA certificate file:**
50+
Ensure you have the root CA file (e.g., `ca.pem`) accessible on your host machine.
51+
52+
2. **Mount the certificate file into the container:**
53+
Use Docker volume mounting (`-v` or `--volume`) to make the certificate file available inside the container at a known path.
54+
55+
3. **Set the `CADENCE_GRPC_TLS_CA_FILE` environment variable to the mounted certificate path:**
56+
57+
Example command (for Linux):
58+
59+
```bash
60+
docker run -it --rm \
61+
-p 8088:8088 \
62+
-v /path/on/host/ca.pem:/etc/certs/ca.pem:ro \
63+
-e CADENCE_GRPC_TLS_CA_FILE=/etc/certs/ca.pem \
64+
ubercadence/server:master-auto-setup
65+
```
66+
67+
- Replace `/path/on/host/ca.pem` with the actual location of your CA certificate on the host system.
68+
- `CADENCE_GRPC_TLS_CA_FILE` must point to the path inside the container where the certificate is mounted.
69+
4270
### Building & developing cadence-web
4371

4472
`cadence-web` requires node `v18` or greater to be able to run correctly.
@@ -98,12 +126,13 @@ You can customize the YAML file or reuse configurations from the [cadence reposi
98126
After running `cadence`, start `cadence-web` for development using one of the previous methods ([Running development environment](#running-development-environment), [VSCode Dev Containers](#using-vscode-dev-containers))
99127

100128

129+
101130
#### NPM scripts
102131

103132

104133
| script | Description |
105134
| ----------------- | ----------------------------------------------------------------------------------------------- |
106-
| build | Generate a production build |
135+
| build | Generate a production build |
107136
| start | Start server for existing production build |
108137
| dev | Run a development server |
109138
| install-idl | Download idl files required for building/running the project |
@@ -122,4 +151,4 @@ After running `cadence`, start `cadence-web` for development using one of the pr
122151

123152
MIT License, please see [LICENSE](https://github.com/cadence-workflow/cadence-web/blob/master/LICENSE) for details.
124153

125-
[cadence]: https://github.com/cadence-workflow/cadence
154+
[cadence]: https://github.com/cadence-workflow/cadence

src/utils/grpc/grpc-service.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ import type { ServiceClient } from '@grpc/grpc-js/build/src/make-client';
33
import * as protoLoader from '@grpc/proto-loader';
44
import get from 'lodash/get';
55
import merge from 'lodash/merge';
6+
import * as fs from 'node:fs';
67

78
import GRPC_PROTO_DIR_BASE_PATH from '@/config/grpc/grpc-proto-dir-base-path';
9+
import logger from '@/utils/logger';
810

911
import { GRPCError, type GRPCInputError } from './grpc-error';
1012

@@ -51,7 +53,7 @@ class GRPCService {
5153
);
5254
this.service = new ServiceDefinition(
5355
peer,
54-
grpc.credentials.createInsecure(),
56+
getChannelCredentials(),
5557
GRPC_OPTIONS
5658
);
5759
this.requestConfig = requestConfig;
@@ -136,4 +138,26 @@ class GRPCService {
136138
}
137139
}
138140

141+
let cachedCredentials: grpc.ChannelCredentials | null = null;
142+
export function getChannelCredentials() {
143+
if (cachedCredentials) {
144+
return cachedCredentials;
145+
}
146+
const caRootPath = process.env.CADENCE_GRPC_TLS_CA_FILE?.trim();
147+
if (caRootPath) {
148+
try {
149+
const rootCert = fs.readFileSync(caRootPath);
150+
cachedCredentials = grpc.credentials.createSsl(rootCert);
151+
} catch (e) {
152+
logger.error({
153+
message: `Failed to read GRPC TLS CA file`,
154+
error: e,
155+
});
156+
}
157+
} else {
158+
cachedCredentials = grpc.credentials.createInsecure();
159+
}
160+
return cachedCredentials;
161+
}
162+
139163
export default GRPCService;

0 commit comments

Comments
 (0)