Unverified Commit 13164bf4 authored by Dave Cameron's avatar Dave Cameron Committed by GitHub

feat: Expose config for mTLS certificates. (#757)

A client certificate can be specified to present with requests to
metadata and search services for mTLS. The configuration is given
as a pair of paths to the PEM encoded cert and key files. This is
described in more detail in the requests documentation:
https://requests.readthedocs.io/en/master/user/advanced/#client-side-certificates

This assumes that the frontend should present the same client
cert to both the search and metadata services, which is consistent
with the idea that a client cert should uniquely identify the
service that is presenting it.

If the environment variables are not set, then the clients are
created as normal without any expectation of mTLS.
Signed-off-by: 's avatarDave Cameron <dcameron@digitalocean.com>
parent d27326fb
...@@ -105,7 +105,7 @@ def request_wrapper(method: str, url: str, client, headers, timeout_sec: int, da ...@@ -105,7 +105,7 @@ def request_wrapper(method: str, url: str, client, headers, timeout_sec: int, da
else: else:
raise Exception('Method not allowed: {}'.format(method)) raise Exception('Method not allowed: {}'.format(method))
else: else:
with requests.Session() as s: with build_session() as s:
if method == 'DELETE': if method == 'DELETE':
return s.delete(url, headers=headers, timeout=timeout_sec) return s.delete(url, headers=headers, timeout=timeout_sec)
elif method == 'GET': elif method == 'GET':
...@@ -116,3 +116,14 @@ def request_wrapper(method: str, url: str, client, headers, timeout_sec: int, da ...@@ -116,3 +116,14 @@ def request_wrapper(method: str, url: str, client, headers, timeout_sec: int, da
return s.put(url, headers=headers, timeout=timeout_sec, data=data) return s.put(url, headers=headers, timeout=timeout_sec, data=data)
else: else:
raise Exception('Method not allowed: {}'.format(method)) raise Exception('Method not allowed: {}'.format(method))
def build_session() -> requests.Session:
session = requests.Session()
cert = app.config.get('MTLS_CLIENT_CERT')
key = app.config.get('MTLS_CLIENT_KEY')
if cert is not None and key is not None:
session.cert = (cert, key)
return session
...@@ -100,6 +100,16 @@ class Config: ...@@ -100,6 +100,16 @@ class Config:
# e.g: ACL_ENABLED_DASHBOARD_PREVIEW = {'ModePreview'} # e.g: ACL_ENABLED_DASHBOARD_PREVIEW = {'ModePreview'}
ACL_ENABLED_DASHBOARD_PREVIEW = set() # type: Set[Optional[str]] ACL_ENABLED_DASHBOARD_PREVIEW = set() # type: Set[Optional[str]]
MTLS_CLIENT_CERT = os.getenv('MTLS_CLIENT_CERT')
"""
Optional.
The path to a PEM formatted certificate to present when calling the metadata and search services.
MTLS_CLIENT_KEY must also be set.
"""
MTLS_CLIENT_KEY = os.getenv('MTLS_CLIENT_KEY')
"""Optional. The path to a PEM formatted key to use with the MTLS_CLIENT_CERT. MTLS_CLIENT_CERT must also be set."""
class LocalConfig(Config): class LocalConfig(Config):
DEBUG = False DEBUG = False
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment