authentik.outposts.docker_tls
Create Docker TLSConfig from CertificateKeyPair
1"""Create Docker TLSConfig from CertificateKeyPair""" 2 3from os import unlink 4from pathlib import Path 5from tempfile import gettempdir 6 7from docker.tls import TLSConfig 8 9from authentik.crypto.models import CertificateKeyPair 10from authentik.outposts.docker_ssh import opener 11 12 13class DockerInlineTLS: 14 """Create Docker TLSConfig from CertificateKeyPair""" 15 16 verification_kp: CertificateKeyPair | None 17 authentication_kp: CertificateKeyPair | None 18 19 _paths: list[str] 20 21 def __init__( 22 self, 23 verification_kp: CertificateKeyPair | None, 24 authentication_kp: CertificateKeyPair | None, 25 ) -> None: 26 self.verification_kp = verification_kp 27 self.authentication_kp = authentication_kp 28 self._paths = [] 29 30 def __enter__(self): 31 return self.write() 32 33 def __exit__(self, exc_type, exc, tb): 34 self.cleanup() 35 36 def write_file(self, name: str, contents: str) -> str: 37 """Wrapper for mkstemp that uses fdopen""" 38 path = Path(gettempdir(), name) 39 with open(path, "w", encoding="utf8", opener=opener) as _file: 40 _file.write(contents) 41 self._paths.append(str(path)) 42 return str(path) 43 44 def cleanup(self): 45 """Clean up certificates when we're done""" 46 for path in self._paths: 47 unlink(path) 48 49 def write(self) -> TLSConfig: 50 """Create TLSConfig with Certificate Key pairs""" 51 # So yes, this is quite ugly. But sadly, there is no clean way to pass 52 # docker-py (which is using requests (which is using urllib3)) a certificate 53 # for verification or authentication as string. 54 # Because we run in docker, and our tmpfs is isolated to us, we can just 55 # write out the certificates and keys to files and use their paths 56 config_args = {} 57 if self.verification_kp: 58 ca_cert_path = self.write_file( 59 f"{self.verification_kp.pk.hex}-cert.pem", 60 self.verification_kp.certificate_data, 61 ) 62 config_args["ca_cert"] = ca_cert_path 63 if self.authentication_kp: 64 auth_cert_path = self.write_file( 65 f"{self.authentication_kp.pk.hex}-cert.pem", 66 self.authentication_kp.certificate_data, 67 ) 68 auth_key_path = self.write_file( 69 f"{self.authentication_kp.pk.hex}-key.pem", 70 self.authentication_kp.key_data, 71 ) 72 config_args["client_cert"] = (auth_cert_path, auth_key_path) 73 return TLSConfig(**config_args)
class
DockerInlineTLS:
14class DockerInlineTLS: 15 """Create Docker TLSConfig from CertificateKeyPair""" 16 17 verification_kp: CertificateKeyPair | None 18 authentication_kp: CertificateKeyPair | None 19 20 _paths: list[str] 21 22 def __init__( 23 self, 24 verification_kp: CertificateKeyPair | None, 25 authentication_kp: CertificateKeyPair | None, 26 ) -> None: 27 self.verification_kp = verification_kp 28 self.authentication_kp = authentication_kp 29 self._paths = [] 30 31 def __enter__(self): 32 return self.write() 33 34 def __exit__(self, exc_type, exc, tb): 35 self.cleanup() 36 37 def write_file(self, name: str, contents: str) -> str: 38 """Wrapper for mkstemp that uses fdopen""" 39 path = Path(gettempdir(), name) 40 with open(path, "w", encoding="utf8", opener=opener) as _file: 41 _file.write(contents) 42 self._paths.append(str(path)) 43 return str(path) 44 45 def cleanup(self): 46 """Clean up certificates when we're done""" 47 for path in self._paths: 48 unlink(path) 49 50 def write(self) -> TLSConfig: 51 """Create TLSConfig with Certificate Key pairs""" 52 # So yes, this is quite ugly. But sadly, there is no clean way to pass 53 # docker-py (which is using requests (which is using urllib3)) a certificate 54 # for verification or authentication as string. 55 # Because we run in docker, and our tmpfs is isolated to us, we can just 56 # write out the certificates and keys to files and use their paths 57 config_args = {} 58 if self.verification_kp: 59 ca_cert_path = self.write_file( 60 f"{self.verification_kp.pk.hex}-cert.pem", 61 self.verification_kp.certificate_data, 62 ) 63 config_args["ca_cert"] = ca_cert_path 64 if self.authentication_kp: 65 auth_cert_path = self.write_file( 66 f"{self.authentication_kp.pk.hex}-cert.pem", 67 self.authentication_kp.certificate_data, 68 ) 69 auth_key_path = self.write_file( 70 f"{self.authentication_kp.pk.hex}-key.pem", 71 self.authentication_kp.key_data, 72 ) 73 config_args["client_cert"] = (auth_cert_path, auth_key_path) 74 return TLSConfig(**config_args)
Create Docker TLSConfig from CertificateKeyPair
DockerInlineTLS( verification_kp: authentik.crypto.models.CertificateKeyPair | None, authentication_kp: authentik.crypto.models.CertificateKeyPair | None)
verification_kp: authentik.crypto.models.CertificateKeyPair | None
authentication_kp: authentik.crypto.models.CertificateKeyPair | None
def
write_file(self, name: str, contents: str) -> str:
37 def write_file(self, name: str, contents: str) -> str: 38 """Wrapper for mkstemp that uses fdopen""" 39 path = Path(gettempdir(), name) 40 with open(path, "w", encoding="utf8", opener=opener) as _file: 41 _file.write(contents) 42 self._paths.append(str(path)) 43 return str(path)
Wrapper for mkstemp that uses fdopen
def
cleanup(self):
45 def cleanup(self): 46 """Clean up certificates when we're done""" 47 for path in self._paths: 48 unlink(path)
Clean up certificates when we're done
def
write(self) -> docker.tls.TLSConfig:
50 def write(self) -> TLSConfig: 51 """Create TLSConfig with Certificate Key pairs""" 52 # So yes, this is quite ugly. But sadly, there is no clean way to pass 53 # docker-py (which is using requests (which is using urllib3)) a certificate 54 # for verification or authentication as string. 55 # Because we run in docker, and our tmpfs is isolated to us, we can just 56 # write out the certificates and keys to files and use their paths 57 config_args = {} 58 if self.verification_kp: 59 ca_cert_path = self.write_file( 60 f"{self.verification_kp.pk.hex}-cert.pem", 61 self.verification_kp.certificate_data, 62 ) 63 config_args["ca_cert"] = ca_cert_path 64 if self.authentication_kp: 65 auth_cert_path = self.write_file( 66 f"{self.authentication_kp.pk.hex}-cert.pem", 67 self.authentication_kp.certificate_data, 68 ) 69 auth_key_path = self.write_file( 70 f"{self.authentication_kp.pk.hex}-key.pem", 71 self.authentication_kp.key_data, 72 ) 73 config_args["client_cert"] = (auth_cert_path, auth_key_path) 74 return TLSConfig(**config_args)
Create TLSConfig with Certificate Key pairs