From 31a0cff88ba13b66e6edb60bcf13607697ed2db7 Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Thu, 5 Dec 2024 16:58:10 -0500 Subject: [PATCH 1/4] enhance: add functions for daemon tools to do mTLS Signed-off-by: Grant Linville --- gptscript/daemon.py | 47 +++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 1 + requirements.txt | 1 + 3 files changed, 49 insertions(+) create mode 100644 gptscript/daemon.py diff --git a/gptscript/daemon.py b/gptscript/daemon.py new file mode 100644 index 0000000..59da535 --- /dev/null +++ b/gptscript/daemon.py @@ -0,0 +1,47 @@ +import base64 +import ssl +import os +import tempfile + + +def start_fastapi(app): + cert, key, client_cert = save_certificates_from_env() + import uvicorn + uvicorn.run( + app, + host="127.0.0.1", + port=int(os.getenv("PORT")), + ssl_certfile=cert, + ssl_keyfile=key, + ssl_ca_certs=client_cert, + ssl_cert_reqs=ssl.CERT_REQUIRED, + ) + +def save_certificates_from_env(): + cert = base64.b64decode(os.getenv("CERT", "")) + key = base64.b64decode(os.getenv("PRIVATE_KEY", "")) + client_cert = base64.b64decode(os.getenv("GPTSCRIPT_CERT", "")) + + if cert == "": + print("error: CERT env var is empty") + exit(1) + elif key == "": + print("error: PRIVATE_KEY env var is empty") + exit(1) + elif client_cert == "": + print("error: GPTSCRIPT_CERT env var is empty") + exit(1) + + cert_file = tempfile.NamedTemporaryFile(delete=False, suffix=".pem") + key_file = tempfile.NamedTemporaryFile(delete=False, suffix=".pem") + client_cert_file = tempfile.NamedTemporaryFile(delete=False, suffix=".pem") + + cert_file.write(cert) + key_file.write(key) + client_cert_file.write(client_cert) + + cert_file.close() + key_file.close() + client_cert_file.close() + + return cert_file.name, key_file.name, client_cert_file.name diff --git a/pyproject.toml b/pyproject.toml index 70fb34c..75eae1f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,6 +19,7 @@ dependencies = [ "urllib3==2.2.1", "pydantic==2.9.2", "pywin32==306 ; sys_platform == 'win32'", + "uvicorn==0.32.1", ] [project.urls] diff --git a/requirements.txt b/requirements.txt index 4e5a79b..dbdbf7a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,3 +12,4 @@ build==1.1.1 httpx==0.27.0 pydantic==2.9.2 pywin32==306; sys_platform == 'win32' +uvicorn==0.32.1 \ No newline at end of file From 6daee5dfd231c278c2a62d0ff8b3913edc8b47e6 Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Thu, 5 Dec 2024 16:58:57 -0500 Subject: [PATCH 2/4] rename Signed-off-by: Grant Linville --- gptscript/daemon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gptscript/daemon.py b/gptscript/daemon.py index 59da535..4cf8006 100644 --- a/gptscript/daemon.py +++ b/gptscript/daemon.py @@ -4,7 +4,7 @@ import tempfile -def start_fastapi(app): +def start_uvicorn(app): cert, key, client_cert = save_certificates_from_env() import uvicorn uvicorn.run( From 52bf69827a2aa91ce19484ca66f141c478a79554 Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Thu, 5 Dec 2024 22:28:53 -0500 Subject: [PATCH 3/4] delete temp files Signed-off-by: Grant Linville --- gptscript/daemon.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gptscript/daemon.py b/gptscript/daemon.py index 4cf8006..4012082 100644 --- a/gptscript/daemon.py +++ b/gptscript/daemon.py @@ -6,6 +6,13 @@ def start_uvicorn(app): cert, key, client_cert = save_certificates_from_env() + + @app.on_event("shutdown") + def cleanup(): + os.remove(cert) + os.remove(key) + os.remove(client_cert) + import uvicorn uvicorn.run( app, From 24ff3de7edf828711e430647bc2bac0eeda4d5a7 Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Fri, 6 Dec 2024 11:25:33 -0500 Subject: [PATCH 4/4] set perms on cert files Signed-off-by: Grant Linville --- gptscript/daemon.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gptscript/daemon.py b/gptscript/daemon.py index 4012082..1ab3816 100644 --- a/gptscript/daemon.py +++ b/gptscript/daemon.py @@ -43,6 +43,10 @@ def save_certificates_from_env(): key_file = tempfile.NamedTemporaryFile(delete=False, suffix=".pem") client_cert_file = tempfile.NamedTemporaryFile(delete=False, suffix=".pem") + os.chmod(cert_file.name, 0o600) + os.chmod(key_file.name, 0o600) + os.chmod(client_cert_file.name, 0o600) + cert_file.write(cert) key_file.write(key) client_cert_file.write(client_cert)