Skip to content

Commit

Permalink
feat: Adding SSL support for the React UI server and feast UI command. (
Browse files Browse the repository at this point in the history
#4736)

Adding SSL support for the React UI server and feast UI command.
Adding the separate documentation for all the feast servers to start in TLS mode except the offline server. We will add once the SSL support is added to offline server.

Signed-off-by: lrangine <[email protected]>
  • Loading branch information
lokeshrangineni authored Nov 6, 2024
1 parent d4d94f8 commit 4a89252
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 1 deletion.
131 changes: 131 additions & 0 deletions docs/reference/starting-feast-servers-tls-mode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# Starting feast servers in TLS (SSL) mode.
TLS (Transport Layer Security) and SSL (Secure Sockets Layer) are both protocols encrypts communications between a client and server to provide enhanced security.TLS or SSL words used interchangeably.
This article is going to show the sample code to start all the feast servers such as online server, offline server, registry server and UI server in TLS mode.
Also show examples related to feast clients to communicate with the feast servers started in TLS mode.

## Obtaining a self-signed TLS certificate and key
In development mode we can generate a self-signed certificate for testing. In an actual production environment it is always recommended to get it from a trusted TLS certificate provider.

```shell
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes
```

The above command will generate two files
* `key.pem` : certificate private key
* `cert.pem`: certificate public key

You can use the public or private keys generated from above command in the rest of the sections in this tutorial.

## Create the feast demo repo for the rest of the sections.
create a feast repo using `feast init` command and use this repo as a demo for subsequent sections.

```shell
feast init feast_repo_ssl_demo
```

Output is
```
Creating a new Feast repository in /Documents/Src/feast/feast_repo_ssl_demo.
```

You need to execute the feast cli commands from `feast_repo_ssl_demo/feature_repo` directory created from the above `feast init` command.

## Starting feast online server (feature server) in TLS mode
To start the feature server in TLS mode, you need to provide the private and public keys using the `--key` and `--cert` arguments with the `feast serve` command.

```shell
feast serve --key /path/to/key.pem --cert /path/to/cert.pem
```
You will see the output something similar to as below. Note the server url starts in the `https` mode.

```shell
[2024-11-04 15:03:57 -0500] [77989] [INFO] Starting gunicorn 23.0.0
[2024-11-04 15:03:57 -0500] [77989] [INFO] Listening at: https://127.0.0.1:6566 (77989)
[2024-11-04 15:03:57 -0500] [77989] [INFO] Using worker: uvicorn_worker.UvicornWorker
[2024-11-04 15:03:57 -0500] [77992] [INFO] Booting worker with pid: 77992
[2024-11-04 15:03:57 -0500] [77992] [INFO] Started server process [77992]
[2024-11-04 15:03:57 -0500] [77992] [INFO] Waiting for application startup.
[2024-11-04 15:03:57 -0500] [77992] [INFO] Application startup complete.
```


### Feast client connecting to remote online sever started in TLS mode.

Sometimes you may need to pass the self-signed public key to connect to the remote online server started in SSL mode if you have not added the public key to the certificate store.

feast client example:
The registry is pointing to registry of remote feature store. If it is not accessible then should be configured to use remote registry.

```yaml
project: feast-project
registry: /remote/data/registry.db
provider: local
online_store:
path: http://localhost:6566
type: remote
cert: /path/to/cert.pem
entity_key_serialization_version: 2
auth:
type: no_auth
```
{% endcode %}
`cert` is an optional configuration to the public certificate path when the online server starts in TLS(SSL) mode. Typically, this file ends with `*.crt`, `*.cer`, or `*.pem`.

## Starting feast Registry server in TLS mode
To start the feature server in TLS mode, you need to provide the private and public keys using the `--key` and `--cert` arguments with the `feast serve_registry` command.

```shell
feast serve_registry --key /path/to/key.pem --cert /path/to/cert.pem
```
You will see the output something similar to as below. Note the server url starts in the `https` mode.

```shell
11/04/2024 03:10:27 PM feast.registry_server INFO: Starting grpc registry server in TLS(SSL) mode
11/04/2024 03:10:27 PM feast.registry_server INFO: Grpc server started at https://localhost:6570
```

### Feast client connecting to remote registry sever started in TLS mode.

Sometimes you may need to pass the self-signed public key to connect to the remote registry server started in SSL mode if you have not added the public key to the certificate store.

feast client example:

```yaml
project: feast-project
registry:
registry_type: remote
path: https://localhost:6570
cert: /path/to/cert.pem
provider: local
online_store:
path: http://localhost:6566
type: remote
cert: /path/to/cert.pem
entity_key_serialization_version: 2
auth:
type: no_auth
```
{% endcode %}

`cert` is an optional configuration to the public certificate path when the registry server starts in TLS(SSL) mode. Typically, this file ends with `*.crt`, `*.cer`, or `*.pem`.

## Starting feast offline server in TLS mode

TBD


## Starting feast UI server (react app) in TLS mode
To start the feast UI server in TLS mode, you need to provide the private and public keys using the `--key` and `--cert` arguments with the `feast ui` command.

```shell
feast ui --key /path/to/key.pem --cert /path/to/cert.pem
```
You will see the output something similar to as below. Note the server url starts in the `https` mode.

```shell
INFO: Started server process [78872]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on https://0.0.0.0:8888 (Press CTRL+C to quit)
```
26 changes: 26 additions & 0 deletions sdk/python/feast/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,17 +168,41 @@ def version():
type=click.STRING,
default="",
)
@click.option(
"--key",
"-k",
"tls_key_path",
type=click.STRING,
default="",
show_default=False,
help="path to TLS(SSL) certificate private key. You need to pass --cert arg as well to start server in TLS mode",
)
@click.option(
"--cert",
"-c",
"tls_cert_path",
type=click.STRING,
default="",
show_default=False,
help="path to TLS(SSL) certificate public key. You need to pass --key arg as well to start server in TLS mode",
)
@click.pass_context
def ui(
ctx: click.Context,
host: str,
port: int,
registry_ttl_sec: int,
root_path: str = "",
tls_key_path: str = "",
tls_cert_path: str = "",
):
"""
Shows the Feast UI over the current directory
"""
if (tls_key_path and not tls_cert_path) or (not tls_key_path and tls_cert_path):
raise click.BadParameter(
"Please configure --key and --cert args to start the feature server in SSL mode."
)
store = create_feature_store(ctx)
# Pass in the registry_dump method to get around a circular dependency
store.serve_ui(
Expand All @@ -187,6 +211,8 @@ def ui(
get_registry_dump=registry_dump,
registry_ttl_sec=registry_ttl_sec,
root_path=root_path,
tls_key_path=tls_key_path,
tls_cert_path=tls_cert_path,
)


Expand Down
4 changes: 4 additions & 0 deletions sdk/python/feast/feature_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -1931,6 +1931,8 @@ def serve_ui(
get_registry_dump: Callable,
registry_ttl_sec: int,
root_path: str = "",
tls_key_path: str = "",
tls_cert_path: str = "",
) -> None:
"""Start the UI server locally"""
if flags_helper.is_test():
Expand All @@ -1947,6 +1949,8 @@ def serve_ui(
project_id=self.config.project,
registry_ttl_sec=registry_ttl_sec,
root_path=root_path,
tls_key_path=tls_key_path,
tls_cert_path=tls_cert_path,
)

def serve_registry(
Expand Down
13 changes: 12 additions & 1 deletion sdk/python/feast/ui_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,22 @@ def start_server(
project_id: str,
registry_ttl_sec: int,
root_path: str = "",
tls_key_path: str = "",
tls_cert_path: str = "",
):
app = get_app(
store,
project_id,
registry_ttl_sec,
root_path,
)
uvicorn.run(app, host=host, port=port)
if tls_key_path and tls_cert_path:
uvicorn.run(
app,
host=host,
port=port,
ssl_keyfile=tls_key_path,
ssl_certfile=tls_cert_path,
)
else:
uvicorn.run(app, host=host, port=port)

0 comments on commit 4a89252

Please sign in to comment.