From 69c4c02d03fb4fab591be2d3282fc3fd25d2f981 Mon Sep 17 00:00:00 2001 From: James Elliott Date: Sat, 22 Oct 2022 19:27:59 +1100 Subject: [PATCH] feat(storage): tls connection support (#4233) This adds support to PostgreSQL and MySQL to connect via TLS via the standard TLS configuration options. --- config.template.yml | 235 ++++++++++++++++-- .../content/en/configuration/storage/mysql.md | 90 ++++++- .../en/configuration/storage/postgres.md | 116 ++++++--- docs/data/configkeys.json | 2 +- internal/configuration/config.template.yml | 235 ++++++++++++++++-- internal/configuration/schema/keys.go | 12 + internal/configuration/schema/storage.go | 23 +- internal/configuration/validator/const.go | 15 +- internal/configuration/validator/storage.go | 44 +++- .../configuration/validator/storage_test.go | 209 +++++++++++++++- .../storage/sql_provider_backend_mysql.go | 11 +- .../storage/sql_provider_backend_postgres.go | 78 +++--- internal/utils/crypto.go | 4 +- 13 files changed, 934 insertions(+), 140 deletions(-) diff --git a/config.template.yml b/config.template.yml index 4531e0138..89c45d675 100644 --- a/config.template.yml +++ b/config.template.yml @@ -304,18 +304,22 @@ authentication_backend: # start_tls: false # tls: - ## Server Name for certificate validation (in case it's not set correctly in the URL). + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host portion of the url option. # server_name: ldap.example.com - ## Skip verifying the server certificate (to allow a self-signed certificate). - ## In preference to setting this we strongly recommend you add the public portion of the certificate to the - ## certificates directory which is defined by the `certificates_directory` option at the top of the config. + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. # skip_verify: false - ## Minimum TLS version for either Secure LDAP or LDAP StartTLS. + ## Minimum TLS version for the connection. # minimum_version: TLS1.2 - ## Maximum TLS version for either Secure LDAP or LDAP StartTLS. + ## Maximum TLS version for the connection. # maximum_version: TLS1.3 ## The certificate chain used with the private_key if the server requests TLS Client Authentication @@ -717,12 +721,16 @@ session: ## The Redis TLS configuration. If defined will require a TLS connection to the Redis instance(s). # tls: - ## Server Name for certificate validation (in case you are using the IP or non-FQDN in the host option). + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host option. # server_name: myredis.example.com - ## Skip verifying the server certificate (to allow a self-signed certificate). - ## In preference to setting this we strongly recommend you add the public portion of the certificate to the - ## certificates directory which is defined by the `certificates_directory` option at the top of the config. + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. # skip_verify: false ## Minimum TLS version for the connection. @@ -882,6 +890,99 @@ regulation: # password: mypassword # timeout: 5s + ## MySQL TLS settings. Configuring this requires TLS. + # tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host option. + # server_name: mysql.example.com + + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. + # skip_verify: false + + ## Minimum TLS version for the connection. + # minimum_version: TLS1.2 + + ## Maximum TLS version for the connection. + # maximum_version: TLS1.3 + + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + # qocikt3WAdU^invalid DO NOT USE= + # -----END CERTIFICATE----- + + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + # DO NOT USE== + # -----END RSA PRIVATE KEY----- + ## ## PostgreSQL (Storage Provider) ## @@ -894,11 +995,99 @@ regulation: ## Password can also be set using a secret: https://www.authelia.com/c/secrets # password: mypassword # timeout: 5s - # ssl: - # mode: disable - # root_certificate: disable - # certificate: disable - # key: disable + + ## PostgreSQL TLS settings. Configuring this requires TLS. + # tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host option. + # server_name: postgres.example.com + + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. + # skip_verify: false + + ## Minimum TLS version for the connection. + # minimum_version: TLS1.2 + + ## Maximum TLS version for the connection. + # maximum_version: TLS1.3 + + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + # qocikt3WAdU^invalid DO NOT USE= + # -----END CERTIFICATE----- + + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + # DO NOT USE== + # -----END RSA PRIVATE KEY----- ## ## Notification Provider @@ -966,18 +1155,22 @@ notifier: # disable_html_emails: false # tls: - ## Server Name for certificate validation (in case you are using the IP or non-FQDN in the host option). + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host option. # server_name: smtp.example.com - ## Skip verifying the server certificate (to allow a self-signed certificate). - ## In preference to setting this we strongly recommend you add the public portion of the certificate to the - ## certificates directory which is defined by the `certificates_directory` option at the top of the config. + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. # skip_verify: false - ## Minimum TLS version for either StartTLS or SMTPS. + ## Minimum TLS version for the connection. # minimum_version: TLS1.2 - ## Maximum TLS version for either StartTLS or SMTPS. + ## Maximum TLS version for the connection. # maximum_version: TLS1.3 ## The certificate chain used with the private_key if the server requests TLS Client Authentication diff --git a/docs/content/en/configuration/storage/mysql.md b/docs/content/en/configuration/storage/mysql.md index 00fd9d1d8..f9ef749c1 100644 --- a/docs/content/en/configuration/storage/mysql.md +++ b/docs/content/en/configuration/storage/mysql.md @@ -17,12 +17,12 @@ aliases: ## Version support -When using MySQL or MariaDB we recommend using the latest version that is officially supported by the MySQL or MariaDB -developers. We also suggest checking out [PostgreSQL](postgres.md) as an alternative. +When using [MySQL] or [MariaDB] we recommend using the latest version that is officially supported by the [MySQL] or +[MariaDB] developers. We also suggest checking out [PostgreSQL](postgres.md) as an alternative. -The oldest versions that have been tested are MySQL 5.7 and MariaDB 10.6. +The oldest versions that have been tested are [MySQL] 5.7 and [MariaDB] 10.6. -If using MySQL 5.7 or MariaDB 10.6 you may be required to adjust the `explicit_defaults_for_timestamp` setting. This +If using [MySQL] 5.7 or [MariaDB] 10.6 you may be required to adjust the `explicit_defaults_for_timestamp` setting. This will be evident when the container starts with an error similar to `Error 1067: Invalid default value for 'exp'`. You can adjust this setting in the mysql.cnf file like so: @@ -43,6 +43,78 @@ storage: username: authelia password: mypassword timeout: 5s + tls: + server_name: mysql.example.com + skip_verify: false + minimum_version: TLS1.2 + maximum_version: TLS1.3 + certificate_chain: | + -----BEGIN CERTIFICATE----- + MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + qocikt3WAdU^invalid DO NOT USE= + -----END CERTIFICATE----- + private_key: | + -----BEGIN RSA PRIVATE KEY----- + MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + DO NOT USE== + -----END RSA PRIVATE KEY----- ``` ## Options @@ -65,7 +137,7 @@ storage: host: "[fd00:1111:2222:3333::1]" ``` -If utilizing a unix socket it must have the `unix:` prefix: +If utilizing a unix socket it must have the `/` prefix: ```yaml storage: @@ -110,3 +182,11 @@ characters and the user password is changed to this value. {{< confkey type="duration" default="5s" required="no" >}} The SQL connection timeout. + +### tls + +If defined enables connecting to [MySQL] or [MariaDB] over a TLS socket, and additionally controls the TLS connection +validation process. You can see how to configure the tls section [here](../prologue/common.md#tls-configuration). + +[MySQL]: https://www.mysql.com/ +[MariaDB]: https://mariadb.org/ diff --git a/docs/content/en/configuration/storage/postgres.md b/docs/content/en/configuration/storage/postgres.md index 97aa701ef..d888640d5 100644 --- a/docs/content/en/configuration/storage/postgres.md +++ b/docs/content/en/configuration/storage/postgres.md @@ -16,10 +16,10 @@ aliases: ## Version support -See [PostgreSQL support](https://www.postgresql.org/support/versioning/) for the versions supported by PostgreSQL. We -recommend the *current minor* version of one of the versions supported by PostgreSQL. +See [PostgreSQL support](https://www.postgresql.org/support/versioning/) for the versions supported by [PostgreSQL]. We +recommend the *current minor* version of one of the versions supported by [PostgreSQL]. -The versions of PostgreSQL that should be supported by Authelia are: +The versions of [PostgreSQL] that should be supported by Authelia are: * 14 * 13 @@ -40,11 +40,78 @@ storage: schema: public username: authelia password: mypassword - ssl: - mode: disable - root_certificate: /path/to/root_cert.pem - certificate: /path/to/cert.pem - key: /path/to/key.pem + tls: + server_name: psotgres.example.com + skip_verify: false + minimum_version: TLS1.2 + maximum_version: TLS1.3 + certificate_chain: | + -----BEGIN CERTIFICATE----- + MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + qocikt3WAdU^invalid DO NOT USE= + -----END CERTIFICATE----- + private_key: | + -----BEGIN RSA PRIVATE KEY----- + MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + DO NOT USE== + -----END RSA PRIVATE KEY----- ``` ## Options @@ -67,7 +134,7 @@ storage: host: "[fd00:1111:2222:3333::1]" ``` -If utilizing a unix socket it must have the `unix:` prefix: +If utilizing a unix socket it must have the `/` prefix: ```yaml storage: @@ -120,32 +187,9 @@ characters and the user password is changed to this value. The SQL connection timeout. -### ssl +### tls -#### mode +If defined enables connecting to [PostgreSQL] over a TLS socket, and additionally controls the TLS connection +validation process. You can see how to configure the tls section [here](../prologue/common.md#tls-configuration). -{{< confkey type="string" default="disable" required="no" >}} - -SSL mode configures how to handle SSL connections with Postgres. -Valid options are 'disable', 'require', 'verify-ca', or 'verify-full'. -See the [PostgreSQL Documentation](https://www.postgresql.org/docs/12/libpq-ssl.html) -or [pgx - PostgreSQL Driver and Toolkit Documentation](https://pkg.go.dev/github.com/jackc/pgx?tab=doc) -for more information. - -#### root_certificate - -{{< confkey type="string" required="no" >}} - -The optional location of the root certificate file encoded in the PEM format for validation purposes. - -#### certificate - -{{< confkey type="string" required="no" >}} - -The optional location of the certificate file encoded in the PEM format for validation purposes. - -#### key - -{{< confkey type="string" required="no" >}} - -The optional location of the key file encoded in the PEM format for authentication purposes. +[PostgreSQL]: https://www.postgresql.org/ diff --git a/docs/data/configkeys.json b/docs/data/configkeys.json index 3f0938209..ea96acbf1 100644 --- a/docs/data/configkeys.json +++ b/docs/data/configkeys.json @@ -1 +1 @@ -[{"path":"theme","secret":false,"env":"AUTHELIA_THEME"},{"path":"certificates_directory","secret":false,"env":"AUTHELIA_CERTIFICATES_DIRECTORY"},{"path":"jwt_secret","secret":true,"env":"AUTHELIA_JWT_SECRET_FILE"},{"path":"default_redirection_url","secret":false,"env":"AUTHELIA_DEFAULT_REDIRECTION_URL"},{"path":"default_2fa_method","secret":false,"env":"AUTHELIA_DEFAULT_2FA_METHOD"},{"path":"log.level","secret":false,"env":"AUTHELIA_LOG_LEVEL"},{"path":"log.format","secret":false,"env":"AUTHELIA_LOG_FORMAT"},{"path":"log.file_path","secret":false,"env":"AUTHELIA_LOG_FILE_PATH"},{"path":"log.keep_stdout","secret":false,"env":"AUTHELIA_LOG_KEEP_STDOUT"},{"path":"identity_providers.oidc.hmac_secret","secret":true,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_HMAC_SECRET_FILE"},{"path":"identity_providers.oidc.issuer_certificate_chain","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_CERTIFICATE_CHAIN"},{"path":"identity_providers.oidc.issuer_private_key","secret":true,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_PRIVATE_KEY_FILE"},{"path":"identity_providers.oidc.access_token_lifespan","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ACCESS_TOKEN_LIFESPAN"},{"path":"identity_providers.oidc.authorize_code_lifespan","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_AUTHORIZE_CODE_LIFESPAN"},{"path":"identity_providers.oidc.id_token_lifespan","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ID_TOKEN_LIFESPAN"},{"path":"identity_providers.oidc.refresh_token_lifespan","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_REFRESH_TOKEN_LIFESPAN"},{"path":"identity_providers.oidc.enable_client_debug_messages","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ENABLE_CLIENT_DEBUG_MESSAGES"},{"path":"identity_providers.oidc.minimum_parameter_entropy","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_MINIMUM_PARAMETER_ENTROPY"},{"path":"identity_providers.oidc.enforce_pkce","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ENFORCE_PKCE"},{"path":"identity_providers.oidc.enable_pkce_plain_challenge","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ENABLE_PKCE_PLAIN_CHALLENGE"},{"path":"identity_providers.oidc.cors.endpoints","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_CORS_ENDPOINTS"},{"path":"identity_providers.oidc.cors.allowed_origins","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_CORS_ALLOWED_ORIGINS"},{"path":"identity_providers.oidc.cors.allowed_origins_from_client_redirect_uris","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_CORS_ALLOWED_ORIGINS_FROM_CLIENT_REDIRECT_URIS"},{"path":"identity_providers.oidc.clients","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_CLIENTS"},{"path":"authentication_backend.password_reset.disable","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_PASSWORD_RESET_DISABLE"},{"path":"authentication_backend.password_reset.custom_url","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_PASSWORD_RESET_CUSTOM_URL"},{"path":"authentication_backend.refresh_interval","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_REFRESH_INTERVAL"},{"path":"authentication_backend.file.path","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PATH"},{"path":"authentication_backend.file.watch","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_WATCH"},{"path":"authentication_backend.file.password.algorithm","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ALGORITHM"},{"path":"authentication_backend.file.password.argon2.variant","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_VARIANT"},{"path":"authentication_backend.file.password.argon2.iterations","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_ITERATIONS"},{"path":"authentication_backend.file.password.argon2.memory","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_MEMORY"},{"path":"authentication_backend.file.password.argon2.parallelism","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_PARALLELISM"},{"path":"authentication_backend.file.password.argon2.key_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_KEY_LENGTH"},{"path":"authentication_backend.file.password.argon2.salt_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_SALT_LENGTH"},{"path":"authentication_backend.file.password.sha2crypt.variant","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SHA2CRYPT_VARIANT"},{"path":"authentication_backend.file.password.sha2crypt.iterations","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SHA2CRYPT_ITERATIONS"},{"path":"authentication_backend.file.password.sha2crypt.salt_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SHA2CRYPT_SALT_LENGTH"},{"path":"authentication_backend.file.password.pbkdf2.variant","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_PBKDF2_VARIANT"},{"path":"authentication_backend.file.password.pbkdf2.iterations","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_PBKDF2_ITERATIONS"},{"path":"authentication_backend.file.password.pbkdf2.salt_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_PBKDF2_SALT_LENGTH"},{"path":"authentication_backend.file.password.bcrypt.variant","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_BCRYPT_VARIANT"},{"path":"authentication_backend.file.password.bcrypt.cost","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_BCRYPT_COST"},{"path":"authentication_backend.file.password.scrypt.iterations","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_ITERATIONS"},{"path":"authentication_backend.file.password.scrypt.block_size","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_BLOCK_SIZE"},{"path":"authentication_backend.file.password.scrypt.parallelism","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_PARALLELISM"},{"path":"authentication_backend.file.password.scrypt.key_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_KEY_LENGTH"},{"path":"authentication_backend.file.password.scrypt.salt_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_SALT_LENGTH"},{"path":"authentication_backend.file.password.iterations","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ITERATIONS"},{"path":"authentication_backend.file.password.memory","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_MEMORY"},{"path":"authentication_backend.file.password.parallelism","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_PARALLELISM"},{"path":"authentication_backend.file.password.key_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_KEY_LENGTH"},{"path":"authentication_backend.file.password.salt_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SALT_LENGTH"},{"path":"authentication_backend.file.search.email","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_SEARCH_EMAIL"},{"path":"authentication_backend.file.search.case_insensitive","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_SEARCH_CASE_INSENSITIVE"},{"path":"authentication_backend.ldap.implementation","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_IMPLEMENTATION"},{"path":"authentication_backend.ldap.url","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_URL"},{"path":"authentication_backend.ldap.timeout","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TIMEOUT"},{"path":"authentication_backend.ldap.start_tls","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_START_TLS"},{"path":"authentication_backend.ldap.tls.minimum_version","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_MINIMUM_VERSION"},{"path":"authentication_backend.ldap.tls.maximum_version","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_MAXIMUM_VERSION"},{"path":"authentication_backend.ldap.tls.skip_verify","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_SKIP_VERIFY"},{"path":"authentication_backend.ldap.tls.server_name","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_SERVER_NAME"},{"path":"authentication_backend.ldap.tls.private_key","secret":true,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_PRIVATE_KEY_FILE"},{"path":"authentication_backend.ldap.tls.certificate_chain","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_CERTIFICATE_CHAIN"},{"path":"authentication_backend.ldap.base_dn","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_BASE_DN"},{"path":"authentication_backend.ldap.additional_users_dn","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ADDITIONAL_USERS_DN"},{"path":"authentication_backend.ldap.users_filter","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_USERS_FILTER"},{"path":"authentication_backend.ldap.additional_groups_dn","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ADDITIONAL_GROUPS_DN"},{"path":"authentication_backend.ldap.groups_filter","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_GROUPS_FILTER"},{"path":"authentication_backend.ldap.group_name_attribute","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_GROUP_NAME_ATTRIBUTE"},{"path":"authentication_backend.ldap.username_attribute","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_USERNAME_ATTRIBUTE"},{"path":"authentication_backend.ldap.mail_attribute","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_MAIL_ATTRIBUTE"},{"path":"authentication_backend.ldap.display_name_attribute","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_DISPLAY_NAME_ATTRIBUTE"},{"path":"authentication_backend.ldap.permit_referrals","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PERMIT_REFERRALS"},{"path":"authentication_backend.ldap.permit_unauthenticated_bind","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PERMIT_UNAUTHENTICATED_BIND"},{"path":"authentication_backend.ldap.permit_feature_detection_failure","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PERMIT_FEATURE_DETECTION_FAILURE"},{"path":"authentication_backend.ldap.user","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_USER"},{"path":"authentication_backend.ldap.password","secret":true,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE"},{"path":"session.name","secret":false,"env":"AUTHELIA_SESSION_NAME"},{"path":"session.domain","secret":false,"env":"AUTHELIA_SESSION_DOMAIN"},{"path":"session.same_site","secret":false,"env":"AUTHELIA_SESSION_SAME_SITE"},{"path":"session.secret","secret":true,"env":"AUTHELIA_SESSION_SECRET_FILE"},{"path":"session.expiration","secret":false,"env":"AUTHELIA_SESSION_EXPIRATION"},{"path":"session.inactivity","secret":false,"env":"AUTHELIA_SESSION_INACTIVITY"},{"path":"session.remember_me_duration","secret":false,"env":"AUTHELIA_SESSION_REMEMBER_ME_DURATION"},{"path":"session.redis.host","secret":false,"env":"AUTHELIA_SESSION_REDIS_HOST"},{"path":"session.redis.port","secret":false,"env":"AUTHELIA_SESSION_REDIS_PORT"},{"path":"session.redis.username","secret":false,"env":"AUTHELIA_SESSION_REDIS_USERNAME"},{"path":"session.redis.password","secret":true,"env":"AUTHELIA_SESSION_REDIS_PASSWORD_FILE"},{"path":"session.redis.database_index","secret":false,"env":"AUTHELIA_SESSION_REDIS_DATABASE_INDEX"},{"path":"session.redis.maximum_active_connections","secret":false,"env":"AUTHELIA_SESSION_REDIS_MAXIMUM_ACTIVE_CONNECTIONS"},{"path":"session.redis.minimum_idle_connections","secret":false,"env":"AUTHELIA_SESSION_REDIS_MINIMUM_IDLE_CONNECTIONS"},{"path":"session.redis.tls.minimum_version","secret":false,"env":"AUTHELIA_SESSION_REDIS_TLS_MINIMUM_VERSION"},{"path":"session.redis.tls.maximum_version","secret":false,"env":"AUTHELIA_SESSION_REDIS_TLS_MAXIMUM_VERSION"},{"path":"session.redis.tls.skip_verify","secret":false,"env":"AUTHELIA_SESSION_REDIS_TLS_SKIP_VERIFY"},{"path":"session.redis.tls.server_name","secret":false,"env":"AUTHELIA_SESSION_REDIS_TLS_SERVER_NAME"},{"path":"session.redis.tls.private_key","secret":true,"env":"AUTHELIA_SESSION_REDIS_TLS_PRIVATE_KEY_FILE"},{"path":"session.redis.tls.certificate_chain","secret":false,"env":"AUTHELIA_SESSION_REDIS_TLS_CERTIFICATE_CHAIN"},{"path":"session.redis.high_availability.sentinel_name","secret":false,"env":"AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_SENTINEL_NAME"},{"path":"session.redis.high_availability.sentinel_username","secret":false,"env":"AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_SENTINEL_USERNAME"},{"path":"session.redis.high_availability.sentinel_password","secret":true,"env":"AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_SENTINEL_PASSWORD_FILE"},{"path":"session.redis.high_availability.nodes","secret":false,"env":"AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_NODES"},{"path":"session.redis.high_availability.route_by_latency","secret":false,"env":"AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_ROUTE_BY_LATENCY"},{"path":"session.redis.high_availability.route_randomly","secret":false,"env":"AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_ROUTE_RANDOMLY"},{"path":"totp.disable","secret":false,"env":"AUTHELIA_TOTP_DISABLE"},{"path":"totp.issuer","secret":false,"env":"AUTHELIA_TOTP_ISSUER"},{"path":"totp.algorithm","secret":false,"env":"AUTHELIA_TOTP_ALGORITHM"},{"path":"totp.digits","secret":false,"env":"AUTHELIA_TOTP_DIGITS"},{"path":"totp.period","secret":false,"env":"AUTHELIA_TOTP_PERIOD"},{"path":"totp.skew","secret":false,"env":"AUTHELIA_TOTP_SKEW"},{"path":"totp.secret_size","secret":false,"env":"AUTHELIA_TOTP_SECRET_SIZE"},{"path":"duo_api.disable","secret":false,"env":"AUTHELIA_DUO_API_DISABLE"},{"path":"duo_api.hostname","secret":false,"env":"AUTHELIA_DUO_API_HOSTNAME"},{"path":"duo_api.integration_key","secret":true,"env":"AUTHELIA_DUO_API_INTEGRATION_KEY_FILE"},{"path":"duo_api.secret_key","secret":true,"env":"AUTHELIA_DUO_API_SECRET_KEY_FILE"},{"path":"duo_api.enable_self_enrollment","secret":false,"env":"AUTHELIA_DUO_API_ENABLE_SELF_ENROLLMENT"},{"path":"access_control.default_policy","secret":false,"env":"AUTHELIA_ACCESS_CONTROL_DEFAULT_POLICY"},{"path":"access_control.networks","secret":false,"env":"AUTHELIA_ACCESS_CONTROL_NETWORKS"},{"path":"access_control.rules","secret":false,"env":"AUTHELIA_ACCESS_CONTROL_RULES"},{"path":"ntp.address","secret":false,"env":"AUTHELIA_NTP_ADDRESS"},{"path":"ntp.version","secret":false,"env":"AUTHELIA_NTP_VERSION"},{"path":"ntp.max_desync","secret":false,"env":"AUTHELIA_NTP_MAX_DESYNC"},{"path":"ntp.disable_startup_check","secret":false,"env":"AUTHELIA_NTP_DISABLE_STARTUP_CHECK"},{"path":"ntp.disable_failure","secret":false,"env":"AUTHELIA_NTP_DISABLE_FAILURE"},{"path":"regulation.max_retries","secret":false,"env":"AUTHELIA_REGULATION_MAX_RETRIES"},{"path":"regulation.find_time","secret":false,"env":"AUTHELIA_REGULATION_FIND_TIME"},{"path":"regulation.ban_time","secret":false,"env":"AUTHELIA_REGULATION_BAN_TIME"},{"path":"storage.local.path","secret":false,"env":"AUTHELIA_STORAGE_LOCAL_PATH"},{"path":"storage.mysql.host","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_HOST"},{"path":"storage.mysql.port","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_PORT"},{"path":"storage.mysql.database","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_DATABASE"},{"path":"storage.mysql.username","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_USERNAME"},{"path":"storage.mysql.password","secret":true,"env":"AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE"},{"path":"storage.mysql.timeout","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_TIMEOUT"},{"path":"storage.postgres.host","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_HOST"},{"path":"storage.postgres.port","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_PORT"},{"path":"storage.postgres.database","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_DATABASE"},{"path":"storage.postgres.username","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_USERNAME"},{"path":"storage.postgres.password","secret":true,"env":"AUTHELIA_STORAGE_POSTGRES_PASSWORD_FILE"},{"path":"storage.postgres.timeout","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_TIMEOUT"},{"path":"storage.postgres.schema","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_SCHEMA"},{"path":"storage.postgres.ssl.mode","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_SSL_MODE"},{"path":"storage.postgres.ssl.root_certificate","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_SSL_ROOT_CERTIFICATE"},{"path":"storage.postgres.ssl.certificate","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_SSL_CERTIFICATE"},{"path":"storage.postgres.ssl.key","secret":true,"env":"AUTHELIA_STORAGE_POSTGRES_SSL_KEY_FILE"},{"path":"storage.encryption_key","secret":true,"env":"AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE"},{"path":"notifier.disable_startup_check","secret":false,"env":"AUTHELIA_NOTIFIER_DISABLE_STARTUP_CHECK"},{"path":"notifier.filesystem.filename","secret":false,"env":"AUTHELIA_NOTIFIER_FILESYSTEM_FILENAME"},{"path":"notifier.smtp.host","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_HOST"},{"path":"notifier.smtp.port","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_PORT"},{"path":"notifier.smtp.timeout","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_TIMEOUT"},{"path":"notifier.smtp.username","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_USERNAME"},{"path":"notifier.smtp.password","secret":true,"env":"AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE"},{"path":"notifier.smtp.identifier","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_IDENTIFIER"},{"path":"notifier.smtp.sender","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_SENDER"},{"path":"notifier.smtp.subject","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_SUBJECT"},{"path":"notifier.smtp.startup_check_address","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_STARTUP_CHECK_ADDRESS"},{"path":"notifier.smtp.disable_require_tls","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_DISABLE_REQUIRE_TLS"},{"path":"notifier.smtp.disable_html_emails","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_DISABLE_HTML_EMAILS"},{"path":"notifier.smtp.disable_starttls","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_DISABLE_STARTTLS"},{"path":"notifier.smtp.tls.minimum_version","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_MINIMUM_VERSION"},{"path":"notifier.smtp.tls.maximum_version","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_MAXIMUM_VERSION"},{"path":"notifier.smtp.tls.skip_verify","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_SKIP_VERIFY"},{"path":"notifier.smtp.tls.server_name","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_SERVER_NAME"},{"path":"notifier.smtp.tls.private_key","secret":true,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_PRIVATE_KEY_FILE"},{"path":"notifier.smtp.tls.certificate_chain","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_CERTIFICATE_CHAIN"},{"path":"notifier.template_path","secret":false,"env":"AUTHELIA_NOTIFIER_TEMPLATE_PATH"},{"path":"server.host","secret":false,"env":"AUTHELIA_SERVER_HOST"},{"path":"server.port","secret":false,"env":"AUTHELIA_SERVER_PORT"},{"path":"server.path","secret":false,"env":"AUTHELIA_SERVER_PATH"},{"path":"server.asset_path","secret":false,"env":"AUTHELIA_SERVER_ASSET_PATH"},{"path":"server.enable_pprof","secret":false,"env":"AUTHELIA_SERVER_ENABLE_PPROF"},{"path":"server.enable_expvars","secret":false,"env":"AUTHELIA_SERVER_ENABLE_EXPVARS"},{"path":"server.disable_healthcheck","secret":false,"env":"AUTHELIA_SERVER_DISABLE_HEALTHCHECK"},{"path":"server.tls.certificate","secret":false,"env":"AUTHELIA_SERVER_TLS_CERTIFICATE"},{"path":"server.tls.key","secret":true,"env":"AUTHELIA_SERVER_TLS_KEY_FILE"},{"path":"server.tls.client_certificates","secret":false,"env":"AUTHELIA_SERVER_TLS_CLIENT_CERTIFICATES"},{"path":"server.headers.csp_template","secret":false,"env":"AUTHELIA_SERVER_HEADERS_CSP_TEMPLATE"},{"path":"server.buffers.read","secret":false,"env":"AUTHELIA_SERVER_BUFFERS_READ"},{"path":"server.buffers.write","secret":false,"env":"AUTHELIA_SERVER_BUFFERS_WRITE"},{"path":"server.timeouts.read","secret":false,"env":"AUTHELIA_SERVER_TIMEOUTS_READ"},{"path":"server.timeouts.write","secret":false,"env":"AUTHELIA_SERVER_TIMEOUTS_WRITE"},{"path":"server.timeouts.idle","secret":false,"env":"AUTHELIA_SERVER_TIMEOUTS_IDLE"},{"path":"telemetry.metrics.enabled","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_ENABLED"},{"path":"telemetry.metrics.address","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_ADDRESS"},{"path":"telemetry.metrics.buffers.read","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_BUFFERS_READ"},{"path":"telemetry.metrics.buffers.write","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_BUFFERS_WRITE"},{"path":"telemetry.metrics.timeouts.read","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_TIMEOUTS_READ"},{"path":"telemetry.metrics.timeouts.write","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_TIMEOUTS_WRITE"},{"path":"telemetry.metrics.timeouts.idle","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_TIMEOUTS_IDLE"},{"path":"webauthn.disable","secret":false,"env":"AUTHELIA_WEBAUTHN_DISABLE"},{"path":"webauthn.display_name","secret":false,"env":"AUTHELIA_WEBAUTHN_DISPLAY_NAME"},{"path":"webauthn.attestation_conveyance_preference","secret":false,"env":"AUTHELIA_WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE"},{"path":"webauthn.user_verification","secret":false,"env":"AUTHELIA_WEBAUTHN_USER_VERIFICATION"},{"path":"webauthn.timeout","secret":false,"env":"AUTHELIA_WEBAUTHN_TIMEOUT"},{"path":"password_policy.standard.enabled","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_ENABLED"},{"path":"password_policy.standard.min_length","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_MIN_LENGTH"},{"path":"password_policy.standard.max_length","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_MAX_LENGTH"},{"path":"password_policy.standard.require_uppercase","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_REQUIRE_UPPERCASE"},{"path":"password_policy.standard.require_lowercase","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_REQUIRE_LOWERCASE"},{"path":"password_policy.standard.require_number","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_REQUIRE_NUMBER"},{"path":"password_policy.standard.require_special","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_REQUIRE_SPECIAL"},{"path":"password_policy.zxcvbn.enabled","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_ZXCVBN_ENABLED"},{"path":"password_policy.zxcvbn.min_score","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_ZXCVBN_MIN_SCORE"}] \ No newline at end of file +[{"path":"theme","secret":false,"env":"AUTHELIA_THEME"},{"path":"certificates_directory","secret":false,"env":"AUTHELIA_CERTIFICATES_DIRECTORY"},{"path":"jwt_secret","secret":true,"env":"AUTHELIA_JWT_SECRET_FILE"},{"path":"default_redirection_url","secret":false,"env":"AUTHELIA_DEFAULT_REDIRECTION_URL"},{"path":"default_2fa_method","secret":false,"env":"AUTHELIA_DEFAULT_2FA_METHOD"},{"path":"log.level","secret":false,"env":"AUTHELIA_LOG_LEVEL"},{"path":"log.format","secret":false,"env":"AUTHELIA_LOG_FORMAT"},{"path":"log.file_path","secret":false,"env":"AUTHELIA_LOG_FILE_PATH"},{"path":"log.keep_stdout","secret":false,"env":"AUTHELIA_LOG_KEEP_STDOUT"},{"path":"identity_providers.oidc.hmac_secret","secret":true,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_HMAC_SECRET_FILE"},{"path":"identity_providers.oidc.issuer_certificate_chain","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_CERTIFICATE_CHAIN"},{"path":"identity_providers.oidc.issuer_private_key","secret":true,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_PRIVATE_KEY_FILE"},{"path":"identity_providers.oidc.access_token_lifespan","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ACCESS_TOKEN_LIFESPAN"},{"path":"identity_providers.oidc.authorize_code_lifespan","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_AUTHORIZE_CODE_LIFESPAN"},{"path":"identity_providers.oidc.id_token_lifespan","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ID_TOKEN_LIFESPAN"},{"path":"identity_providers.oidc.refresh_token_lifespan","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_REFRESH_TOKEN_LIFESPAN"},{"path":"identity_providers.oidc.enable_client_debug_messages","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ENABLE_CLIENT_DEBUG_MESSAGES"},{"path":"identity_providers.oidc.minimum_parameter_entropy","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_MINIMUM_PARAMETER_ENTROPY"},{"path":"identity_providers.oidc.enforce_pkce","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ENFORCE_PKCE"},{"path":"identity_providers.oidc.enable_pkce_plain_challenge","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ENABLE_PKCE_PLAIN_CHALLENGE"},{"path":"identity_providers.oidc.cors.endpoints","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_CORS_ENDPOINTS"},{"path":"identity_providers.oidc.cors.allowed_origins","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_CORS_ALLOWED_ORIGINS"},{"path":"identity_providers.oidc.cors.allowed_origins_from_client_redirect_uris","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_CORS_ALLOWED_ORIGINS_FROM_CLIENT_REDIRECT_URIS"},{"path":"identity_providers.oidc.clients","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_CLIENTS"},{"path":"authentication_backend.password_reset.disable","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_PASSWORD_RESET_DISABLE"},{"path":"authentication_backend.password_reset.custom_url","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_PASSWORD_RESET_CUSTOM_URL"},{"path":"authentication_backend.refresh_interval","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_REFRESH_INTERVAL"},{"path":"authentication_backend.file.path","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PATH"},{"path":"authentication_backend.file.watch","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_WATCH"},{"path":"authentication_backend.file.password.algorithm","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ALGORITHM"},{"path":"authentication_backend.file.password.argon2.variant","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_VARIANT"},{"path":"authentication_backend.file.password.argon2.iterations","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_ITERATIONS"},{"path":"authentication_backend.file.password.argon2.memory","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_MEMORY"},{"path":"authentication_backend.file.password.argon2.parallelism","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_PARALLELISM"},{"path":"authentication_backend.file.password.argon2.key_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_KEY_LENGTH"},{"path":"authentication_backend.file.password.argon2.salt_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_SALT_LENGTH"},{"path":"authentication_backend.file.password.sha2crypt.variant","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SHA2CRYPT_VARIANT"},{"path":"authentication_backend.file.password.sha2crypt.iterations","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SHA2CRYPT_ITERATIONS"},{"path":"authentication_backend.file.password.sha2crypt.salt_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SHA2CRYPT_SALT_LENGTH"},{"path":"authentication_backend.file.password.pbkdf2.variant","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_PBKDF2_VARIANT"},{"path":"authentication_backend.file.password.pbkdf2.iterations","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_PBKDF2_ITERATIONS"},{"path":"authentication_backend.file.password.pbkdf2.salt_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_PBKDF2_SALT_LENGTH"},{"path":"authentication_backend.file.password.bcrypt.variant","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_BCRYPT_VARIANT"},{"path":"authentication_backend.file.password.bcrypt.cost","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_BCRYPT_COST"},{"path":"authentication_backend.file.password.scrypt.iterations","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_ITERATIONS"},{"path":"authentication_backend.file.password.scrypt.block_size","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_BLOCK_SIZE"},{"path":"authentication_backend.file.password.scrypt.parallelism","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_PARALLELISM"},{"path":"authentication_backend.file.password.scrypt.key_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_KEY_LENGTH"},{"path":"authentication_backend.file.password.scrypt.salt_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_SALT_LENGTH"},{"path":"authentication_backend.file.password.iterations","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ITERATIONS"},{"path":"authentication_backend.file.password.memory","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_MEMORY"},{"path":"authentication_backend.file.password.parallelism","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_PARALLELISM"},{"path":"authentication_backend.file.password.key_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_KEY_LENGTH"},{"path":"authentication_backend.file.password.salt_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SALT_LENGTH"},{"path":"authentication_backend.file.search.email","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_SEARCH_EMAIL"},{"path":"authentication_backend.file.search.case_insensitive","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_SEARCH_CASE_INSENSITIVE"},{"path":"authentication_backend.ldap.implementation","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_IMPLEMENTATION"},{"path":"authentication_backend.ldap.url","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_URL"},{"path":"authentication_backend.ldap.timeout","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TIMEOUT"},{"path":"authentication_backend.ldap.start_tls","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_START_TLS"},{"path":"authentication_backend.ldap.tls.minimum_version","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_MINIMUM_VERSION"},{"path":"authentication_backend.ldap.tls.maximum_version","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_MAXIMUM_VERSION"},{"path":"authentication_backend.ldap.tls.skip_verify","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_SKIP_VERIFY"},{"path":"authentication_backend.ldap.tls.server_name","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_SERVER_NAME"},{"path":"authentication_backend.ldap.tls.private_key","secret":true,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_PRIVATE_KEY_FILE"},{"path":"authentication_backend.ldap.tls.certificate_chain","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_CERTIFICATE_CHAIN"},{"path":"authentication_backend.ldap.base_dn","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_BASE_DN"},{"path":"authentication_backend.ldap.additional_users_dn","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ADDITIONAL_USERS_DN"},{"path":"authentication_backend.ldap.users_filter","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_USERS_FILTER"},{"path":"authentication_backend.ldap.additional_groups_dn","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ADDITIONAL_GROUPS_DN"},{"path":"authentication_backend.ldap.groups_filter","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_GROUPS_FILTER"},{"path":"authentication_backend.ldap.group_name_attribute","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_GROUP_NAME_ATTRIBUTE"},{"path":"authentication_backend.ldap.username_attribute","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_USERNAME_ATTRIBUTE"},{"path":"authentication_backend.ldap.mail_attribute","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_MAIL_ATTRIBUTE"},{"path":"authentication_backend.ldap.display_name_attribute","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_DISPLAY_NAME_ATTRIBUTE"},{"path":"authentication_backend.ldap.permit_referrals","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PERMIT_REFERRALS"},{"path":"authentication_backend.ldap.permit_unauthenticated_bind","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PERMIT_UNAUTHENTICATED_BIND"},{"path":"authentication_backend.ldap.permit_feature_detection_failure","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PERMIT_FEATURE_DETECTION_FAILURE"},{"path":"authentication_backend.ldap.user","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_USER"},{"path":"authentication_backend.ldap.password","secret":true,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE"},{"path":"session.name","secret":false,"env":"AUTHELIA_SESSION_NAME"},{"path":"session.domain","secret":false,"env":"AUTHELIA_SESSION_DOMAIN"},{"path":"session.same_site","secret":false,"env":"AUTHELIA_SESSION_SAME_SITE"},{"path":"session.secret","secret":true,"env":"AUTHELIA_SESSION_SECRET_FILE"},{"path":"session.expiration","secret":false,"env":"AUTHELIA_SESSION_EXPIRATION"},{"path":"session.inactivity","secret":false,"env":"AUTHELIA_SESSION_INACTIVITY"},{"path":"session.remember_me_duration","secret":false,"env":"AUTHELIA_SESSION_REMEMBER_ME_DURATION"},{"path":"session.redis.host","secret":false,"env":"AUTHELIA_SESSION_REDIS_HOST"},{"path":"session.redis.port","secret":false,"env":"AUTHELIA_SESSION_REDIS_PORT"},{"path":"session.redis.username","secret":false,"env":"AUTHELIA_SESSION_REDIS_USERNAME"},{"path":"session.redis.password","secret":true,"env":"AUTHELIA_SESSION_REDIS_PASSWORD_FILE"},{"path":"session.redis.database_index","secret":false,"env":"AUTHELIA_SESSION_REDIS_DATABASE_INDEX"},{"path":"session.redis.maximum_active_connections","secret":false,"env":"AUTHELIA_SESSION_REDIS_MAXIMUM_ACTIVE_CONNECTIONS"},{"path":"session.redis.minimum_idle_connections","secret":false,"env":"AUTHELIA_SESSION_REDIS_MINIMUM_IDLE_CONNECTIONS"},{"path":"session.redis.tls.minimum_version","secret":false,"env":"AUTHELIA_SESSION_REDIS_TLS_MINIMUM_VERSION"},{"path":"session.redis.tls.maximum_version","secret":false,"env":"AUTHELIA_SESSION_REDIS_TLS_MAXIMUM_VERSION"},{"path":"session.redis.tls.skip_verify","secret":false,"env":"AUTHELIA_SESSION_REDIS_TLS_SKIP_VERIFY"},{"path":"session.redis.tls.server_name","secret":false,"env":"AUTHELIA_SESSION_REDIS_TLS_SERVER_NAME"},{"path":"session.redis.tls.private_key","secret":true,"env":"AUTHELIA_SESSION_REDIS_TLS_PRIVATE_KEY_FILE"},{"path":"session.redis.tls.certificate_chain","secret":false,"env":"AUTHELIA_SESSION_REDIS_TLS_CERTIFICATE_CHAIN"},{"path":"session.redis.high_availability.sentinel_name","secret":false,"env":"AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_SENTINEL_NAME"},{"path":"session.redis.high_availability.sentinel_username","secret":false,"env":"AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_SENTINEL_USERNAME"},{"path":"session.redis.high_availability.sentinel_password","secret":true,"env":"AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_SENTINEL_PASSWORD_FILE"},{"path":"session.redis.high_availability.nodes","secret":false,"env":"AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_NODES"},{"path":"session.redis.high_availability.route_by_latency","secret":false,"env":"AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_ROUTE_BY_LATENCY"},{"path":"session.redis.high_availability.route_randomly","secret":false,"env":"AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_ROUTE_RANDOMLY"},{"path":"totp.disable","secret":false,"env":"AUTHELIA_TOTP_DISABLE"},{"path":"totp.issuer","secret":false,"env":"AUTHELIA_TOTP_ISSUER"},{"path":"totp.algorithm","secret":false,"env":"AUTHELIA_TOTP_ALGORITHM"},{"path":"totp.digits","secret":false,"env":"AUTHELIA_TOTP_DIGITS"},{"path":"totp.period","secret":false,"env":"AUTHELIA_TOTP_PERIOD"},{"path":"totp.skew","secret":false,"env":"AUTHELIA_TOTP_SKEW"},{"path":"totp.secret_size","secret":false,"env":"AUTHELIA_TOTP_SECRET_SIZE"},{"path":"duo_api.disable","secret":false,"env":"AUTHELIA_DUO_API_DISABLE"},{"path":"duo_api.hostname","secret":false,"env":"AUTHELIA_DUO_API_HOSTNAME"},{"path":"duo_api.integration_key","secret":true,"env":"AUTHELIA_DUO_API_INTEGRATION_KEY_FILE"},{"path":"duo_api.secret_key","secret":true,"env":"AUTHELIA_DUO_API_SECRET_KEY_FILE"},{"path":"duo_api.enable_self_enrollment","secret":false,"env":"AUTHELIA_DUO_API_ENABLE_SELF_ENROLLMENT"},{"path":"access_control.default_policy","secret":false,"env":"AUTHELIA_ACCESS_CONTROL_DEFAULT_POLICY"},{"path":"access_control.networks","secret":false,"env":"AUTHELIA_ACCESS_CONTROL_NETWORKS"},{"path":"access_control.rules","secret":false,"env":"AUTHELIA_ACCESS_CONTROL_RULES"},{"path":"ntp.address","secret":false,"env":"AUTHELIA_NTP_ADDRESS"},{"path":"ntp.version","secret":false,"env":"AUTHELIA_NTP_VERSION"},{"path":"ntp.max_desync","secret":false,"env":"AUTHELIA_NTP_MAX_DESYNC"},{"path":"ntp.disable_startup_check","secret":false,"env":"AUTHELIA_NTP_DISABLE_STARTUP_CHECK"},{"path":"ntp.disable_failure","secret":false,"env":"AUTHELIA_NTP_DISABLE_FAILURE"},{"path":"regulation.max_retries","secret":false,"env":"AUTHELIA_REGULATION_MAX_RETRIES"},{"path":"regulation.find_time","secret":false,"env":"AUTHELIA_REGULATION_FIND_TIME"},{"path":"regulation.ban_time","secret":false,"env":"AUTHELIA_REGULATION_BAN_TIME"},{"path":"storage.local.path","secret":false,"env":"AUTHELIA_STORAGE_LOCAL_PATH"},{"path":"storage.mysql.host","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_HOST"},{"path":"storage.mysql.port","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_PORT"},{"path":"storage.mysql.database","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_DATABASE"},{"path":"storage.mysql.username","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_USERNAME"},{"path":"storage.mysql.password","secret":true,"env":"AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE"},{"path":"storage.mysql.timeout","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_TIMEOUT"},{"path":"storage.mysql.tls.minimum_version","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_TLS_MINIMUM_VERSION"},{"path":"storage.mysql.tls.maximum_version","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_TLS_MAXIMUM_VERSION"},{"path":"storage.mysql.tls.skip_verify","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_TLS_SKIP_VERIFY"},{"path":"storage.mysql.tls.server_name","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_TLS_SERVER_NAME"},{"path":"storage.mysql.tls.private_key","secret":true,"env":"AUTHELIA_STORAGE_MYSQL_TLS_PRIVATE_KEY_FILE"},{"path":"storage.mysql.tls.certificate_chain","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_TLS_CERTIFICATE_CHAIN"},{"path":"storage.postgres.host","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_HOST"},{"path":"storage.postgres.port","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_PORT"},{"path":"storage.postgres.database","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_DATABASE"},{"path":"storage.postgres.username","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_USERNAME"},{"path":"storage.postgres.password","secret":true,"env":"AUTHELIA_STORAGE_POSTGRES_PASSWORD_FILE"},{"path":"storage.postgres.timeout","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_TIMEOUT"},{"path":"storage.postgres.schema","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_SCHEMA"},{"path":"storage.postgres.tls.minimum_version","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_TLS_MINIMUM_VERSION"},{"path":"storage.postgres.tls.maximum_version","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_TLS_MAXIMUM_VERSION"},{"path":"storage.postgres.tls.skip_verify","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_TLS_SKIP_VERIFY"},{"path":"storage.postgres.tls.server_name","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_TLS_SERVER_NAME"},{"path":"storage.postgres.tls.private_key","secret":true,"env":"AUTHELIA_STORAGE_POSTGRES_TLS_PRIVATE_KEY_FILE"},{"path":"storage.postgres.tls.certificate_chain","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_TLS_CERTIFICATE_CHAIN"},{"path":"storage.postgres.ssl.mode","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_SSL_MODE"},{"path":"storage.postgres.ssl.root_certificate","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_SSL_ROOT_CERTIFICATE"},{"path":"storage.postgres.ssl.certificate","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_SSL_CERTIFICATE"},{"path":"storage.postgres.ssl.key","secret":true,"env":"AUTHELIA_STORAGE_POSTGRES_SSL_KEY_FILE"},{"path":"storage.encryption_key","secret":true,"env":"AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE"},{"path":"notifier.disable_startup_check","secret":false,"env":"AUTHELIA_NOTIFIER_DISABLE_STARTUP_CHECK"},{"path":"notifier.filesystem.filename","secret":false,"env":"AUTHELIA_NOTIFIER_FILESYSTEM_FILENAME"},{"path":"notifier.smtp.host","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_HOST"},{"path":"notifier.smtp.port","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_PORT"},{"path":"notifier.smtp.timeout","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_TIMEOUT"},{"path":"notifier.smtp.username","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_USERNAME"},{"path":"notifier.smtp.password","secret":true,"env":"AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE"},{"path":"notifier.smtp.identifier","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_IDENTIFIER"},{"path":"notifier.smtp.sender","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_SENDER"},{"path":"notifier.smtp.subject","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_SUBJECT"},{"path":"notifier.smtp.startup_check_address","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_STARTUP_CHECK_ADDRESS"},{"path":"notifier.smtp.disable_require_tls","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_DISABLE_REQUIRE_TLS"},{"path":"notifier.smtp.disable_html_emails","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_DISABLE_HTML_EMAILS"},{"path":"notifier.smtp.disable_starttls","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_DISABLE_STARTTLS"},{"path":"notifier.smtp.tls.minimum_version","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_MINIMUM_VERSION"},{"path":"notifier.smtp.tls.maximum_version","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_MAXIMUM_VERSION"},{"path":"notifier.smtp.tls.skip_verify","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_SKIP_VERIFY"},{"path":"notifier.smtp.tls.server_name","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_SERVER_NAME"},{"path":"notifier.smtp.tls.private_key","secret":true,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_PRIVATE_KEY_FILE"},{"path":"notifier.smtp.tls.certificate_chain","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_CERTIFICATE_CHAIN"},{"path":"notifier.template_path","secret":false,"env":"AUTHELIA_NOTIFIER_TEMPLATE_PATH"},{"path":"server.host","secret":false,"env":"AUTHELIA_SERVER_HOST"},{"path":"server.port","secret":false,"env":"AUTHELIA_SERVER_PORT"},{"path":"server.path","secret":false,"env":"AUTHELIA_SERVER_PATH"},{"path":"server.asset_path","secret":false,"env":"AUTHELIA_SERVER_ASSET_PATH"},{"path":"server.enable_pprof","secret":false,"env":"AUTHELIA_SERVER_ENABLE_PPROF"},{"path":"server.enable_expvars","secret":false,"env":"AUTHELIA_SERVER_ENABLE_EXPVARS"},{"path":"server.disable_healthcheck","secret":false,"env":"AUTHELIA_SERVER_DISABLE_HEALTHCHECK"},{"path":"server.tls.certificate","secret":false,"env":"AUTHELIA_SERVER_TLS_CERTIFICATE"},{"path":"server.tls.key","secret":true,"env":"AUTHELIA_SERVER_TLS_KEY_FILE"},{"path":"server.tls.client_certificates","secret":false,"env":"AUTHELIA_SERVER_TLS_CLIENT_CERTIFICATES"},{"path":"server.headers.csp_template","secret":false,"env":"AUTHELIA_SERVER_HEADERS_CSP_TEMPLATE"},{"path":"server.buffers.read","secret":false,"env":"AUTHELIA_SERVER_BUFFERS_READ"},{"path":"server.buffers.write","secret":false,"env":"AUTHELIA_SERVER_BUFFERS_WRITE"},{"path":"server.timeouts.read","secret":false,"env":"AUTHELIA_SERVER_TIMEOUTS_READ"},{"path":"server.timeouts.write","secret":false,"env":"AUTHELIA_SERVER_TIMEOUTS_WRITE"},{"path":"server.timeouts.idle","secret":false,"env":"AUTHELIA_SERVER_TIMEOUTS_IDLE"},{"path":"telemetry.metrics.enabled","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_ENABLED"},{"path":"telemetry.metrics.address","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_ADDRESS"},{"path":"telemetry.metrics.buffers.read","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_BUFFERS_READ"},{"path":"telemetry.metrics.buffers.write","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_BUFFERS_WRITE"},{"path":"telemetry.metrics.timeouts.read","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_TIMEOUTS_READ"},{"path":"telemetry.metrics.timeouts.write","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_TIMEOUTS_WRITE"},{"path":"telemetry.metrics.timeouts.idle","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_TIMEOUTS_IDLE"},{"path":"webauthn.disable","secret":false,"env":"AUTHELIA_WEBAUTHN_DISABLE"},{"path":"webauthn.display_name","secret":false,"env":"AUTHELIA_WEBAUTHN_DISPLAY_NAME"},{"path":"webauthn.attestation_conveyance_preference","secret":false,"env":"AUTHELIA_WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE"},{"path":"webauthn.user_verification","secret":false,"env":"AUTHELIA_WEBAUTHN_USER_VERIFICATION"},{"path":"webauthn.timeout","secret":false,"env":"AUTHELIA_WEBAUTHN_TIMEOUT"},{"path":"password_policy.standard.enabled","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_ENABLED"},{"path":"password_policy.standard.min_length","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_MIN_LENGTH"},{"path":"password_policy.standard.max_length","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_MAX_LENGTH"},{"path":"password_policy.standard.require_uppercase","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_REQUIRE_UPPERCASE"},{"path":"password_policy.standard.require_lowercase","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_REQUIRE_LOWERCASE"},{"path":"password_policy.standard.require_number","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_REQUIRE_NUMBER"},{"path":"password_policy.standard.require_special","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_REQUIRE_SPECIAL"},{"path":"password_policy.zxcvbn.enabled","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_ZXCVBN_ENABLED"},{"path":"password_policy.zxcvbn.min_score","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_ZXCVBN_MIN_SCORE"}] \ No newline at end of file diff --git a/internal/configuration/config.template.yml b/internal/configuration/config.template.yml index 4531e0138..89c45d675 100644 --- a/internal/configuration/config.template.yml +++ b/internal/configuration/config.template.yml @@ -304,18 +304,22 @@ authentication_backend: # start_tls: false # tls: - ## Server Name for certificate validation (in case it's not set correctly in the URL). + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host portion of the url option. # server_name: ldap.example.com - ## Skip verifying the server certificate (to allow a self-signed certificate). - ## In preference to setting this we strongly recommend you add the public portion of the certificate to the - ## certificates directory which is defined by the `certificates_directory` option at the top of the config. + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. # skip_verify: false - ## Minimum TLS version for either Secure LDAP or LDAP StartTLS. + ## Minimum TLS version for the connection. # minimum_version: TLS1.2 - ## Maximum TLS version for either Secure LDAP or LDAP StartTLS. + ## Maximum TLS version for the connection. # maximum_version: TLS1.3 ## The certificate chain used with the private_key if the server requests TLS Client Authentication @@ -717,12 +721,16 @@ session: ## The Redis TLS configuration. If defined will require a TLS connection to the Redis instance(s). # tls: - ## Server Name for certificate validation (in case you are using the IP or non-FQDN in the host option). + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host option. # server_name: myredis.example.com - ## Skip verifying the server certificate (to allow a self-signed certificate). - ## In preference to setting this we strongly recommend you add the public portion of the certificate to the - ## certificates directory which is defined by the `certificates_directory` option at the top of the config. + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. # skip_verify: false ## Minimum TLS version for the connection. @@ -882,6 +890,99 @@ regulation: # password: mypassword # timeout: 5s + ## MySQL TLS settings. Configuring this requires TLS. + # tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host option. + # server_name: mysql.example.com + + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. + # skip_verify: false + + ## Minimum TLS version for the connection. + # minimum_version: TLS1.2 + + ## Maximum TLS version for the connection. + # maximum_version: TLS1.3 + + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + # qocikt3WAdU^invalid DO NOT USE= + # -----END CERTIFICATE----- + + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + # DO NOT USE== + # -----END RSA PRIVATE KEY----- + ## ## PostgreSQL (Storage Provider) ## @@ -894,11 +995,99 @@ regulation: ## Password can also be set using a secret: https://www.authelia.com/c/secrets # password: mypassword # timeout: 5s - # ssl: - # mode: disable - # root_certificate: disable - # certificate: disable - # key: disable + + ## PostgreSQL TLS settings. Configuring this requires TLS. + # tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host option. + # server_name: postgres.example.com + + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. + # skip_verify: false + + ## Minimum TLS version for the connection. + # minimum_version: TLS1.2 + + ## Maximum TLS version for the connection. + # maximum_version: TLS1.3 + + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + # qocikt3WAdU^invalid DO NOT USE= + # -----END CERTIFICATE----- + + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + # DO NOT USE== + # -----END RSA PRIVATE KEY----- ## ## Notification Provider @@ -966,18 +1155,22 @@ notifier: # disable_html_emails: false # tls: - ## Server Name for certificate validation (in case you are using the IP or non-FQDN in the host option). + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host option. # server_name: smtp.example.com - ## Skip verifying the server certificate (to allow a self-signed certificate). - ## In preference to setting this we strongly recommend you add the public portion of the certificate to the - ## certificates directory which is defined by the `certificates_directory` option at the top of the config. + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. # skip_verify: false - ## Minimum TLS version for either StartTLS or SMTPS. + ## Minimum TLS version for the connection. # minimum_version: TLS1.2 - ## Maximum TLS version for either StartTLS or SMTPS. + ## Maximum TLS version for the connection. # maximum_version: TLS1.3 ## The certificate chain used with the private_key if the server requests TLS Client Authentication diff --git a/internal/configuration/schema/keys.go b/internal/configuration/schema/keys.go index 283d4e692..bcd577f39 100644 --- a/internal/configuration/schema/keys.go +++ b/internal/configuration/schema/keys.go @@ -174,6 +174,12 @@ var Keys = []string{ "storage.mysql.username", "storage.mysql.password", "storage.mysql.timeout", + "storage.mysql.tls.minimum_version", + "storage.mysql.tls.maximum_version", + "storage.mysql.tls.skip_verify", + "storage.mysql.tls.server_name", + "storage.mysql.tls.private_key", + "storage.mysql.tls.certificate_chain", "storage.postgres.host", "storage.postgres.port", "storage.postgres.database", @@ -181,6 +187,12 @@ var Keys = []string{ "storage.postgres.password", "storage.postgres.timeout", "storage.postgres.schema", + "storage.postgres.tls.minimum_version", + "storage.postgres.tls.maximum_version", + "storage.postgres.tls.skip_verify", + "storage.postgres.tls.server_name", + "storage.postgres.tls.private_key", + "storage.postgres.tls.certificate_chain", "storage.postgres.ssl.mode", "storage.postgres.ssl.root_certificate", "storage.postgres.ssl.certificate", diff --git a/internal/configuration/schema/storage.go b/internal/configuration/schema/storage.go index de4eae7bb..d8eb93808 100644 --- a/internal/configuration/schema/storage.go +++ b/internal/configuration/schema/storage.go @@ -1,6 +1,9 @@ package schema -import "time" +import ( + "crypto/tls" + "time" +) // LocalStorageConfiguration represents the configuration when using local storage. type LocalStorageConfiguration struct { @@ -20,6 +23,8 @@ type SQLStorageConfiguration struct { // MySQLStorageConfiguration represents the configuration of a MySQL database. type MySQLStorageConfiguration struct { SQLStorageConfiguration `koanf:",squash"` + + TLS *TLSConfig `koanf:"tls"` } // PostgreSQLStorageConfiguration represents the configuration of a PostgreSQL database. @@ -27,7 +32,9 @@ type PostgreSQLStorageConfiguration struct { SQLStorageConfiguration `koanf:",squash"` Schema string `koanf:"schema"` - SSL PostgreSQLSSLStorageConfiguration `koanf:"ssl"` + TLS *TLSConfig `koanf:"tls"` + + SSL *PostgreSQLSSLStorageConfiguration `koanf:"ssl"` } // PostgreSQLSSLStorageConfiguration represents the SSL configuration of a PostgreSQL database. @@ -52,10 +59,20 @@ var DefaultSQLStorageConfiguration = SQLStorageConfiguration{ Timeout: 5 * time.Second, } +// DefaultMySQLStorageConfiguration represents the default MySQL configuration. +var DefaultMySQLStorageConfiguration = MySQLStorageConfiguration{ + TLS: &TLSConfig{ + MinimumVersion: TLSVersion{tls.VersionTLS12}, + }, +} + // DefaultPostgreSQLStorageConfiguration represents the default PostgreSQL configuration. var DefaultPostgreSQLStorageConfiguration = PostgreSQLStorageConfiguration{ Schema: "public", - SSL: PostgreSQLSSLStorageConfiguration{ + TLS: &TLSConfig{ + MinimumVersion: TLSVersion{tls.VersionTLS12}, + }, + SSL: &PostgreSQLSSLStorageConfiguration{ Mode: "disable", }, } diff --git a/internal/configuration/validator/const.go b/internal/configuration/validator/const.go index 24c8810f5..a8b102ac7 100644 --- a/internal/configuration/validator/const.go +++ b/internal/configuration/validator/const.go @@ -121,12 +121,15 @@ const ( // Storage Error constants. const ( - errStrStorage = "storage: configuration for a 'local', 'mysql' or 'postgres' database must be provided" - errStrStorageEncryptionKeyMustBeProvided = "storage: option 'encryption_key' is required" - errStrStorageEncryptionKeyTooShort = "storage: option 'encryption_key' must be 20 characters or longer" - errFmtStorageUserPassMustBeProvided = "storage: %s: option 'username' and 'password' are required" //nolint:gosec - errFmtStorageOptionMustBeProvided = "storage: %s: option '%s' is required" - errFmtStoragePostgreSQLInvalidSSLMode = "storage: postgres: ssl: option 'mode' must be one of '%s' but it is configured as '%s'" + errStrStorage = "storage: configuration for a 'local', 'mysql' or 'postgres' database must be provided" + errStrStorageEncryptionKeyMustBeProvided = "storage: option 'encryption_key' is required" + errStrStorageEncryptionKeyTooShort = "storage: option 'encryption_key' must be 20 characters or longer" + errFmtStorageUserPassMustBeProvided = "storage: %s: option 'username' and 'password' are required" //nolint:gosec + errFmtStorageOptionMustBeProvided = "storage: %s: option '%s' is required" + errFmtStorageTLSConfigInvalid = "storage: %s: tls: %w" + errFmtStoragePostgreSQLInvalidSSLMode = "storage: postgres: ssl: option 'mode' must be one of '%s' but it is configured as '%s'" + errFmtStoragePostgreSQLInvalidSSLAndTLSConfig = "storage: postgres: can't define both 'tls' and 'ssl' configuration options" + warnFmtStoragePostgreSQLInvalidSSLDeprecated = "storage: postgres: ssl: the ssl configuration options are deprecated and we recommend the tls options instead" ) // Telemetry Error constants. diff --git a/internal/configuration/validator/storage.go b/internal/configuration/validator/storage.go index a545113bf..7172383a7 100644 --- a/internal/configuration/validator/storage.go +++ b/internal/configuration/validator/storage.go @@ -17,7 +17,7 @@ func ValidateStorage(config schema.StorageConfiguration, validator *schema.Struc switch { case config.MySQL != nil: - validateSQLConfiguration(&config.MySQL.SQLStorageConfiguration, validator, "mysql") + validateMySQLConfiguration(config.MySQL, validator) case config.PostgreSQL != nil: validatePostgreSQLConfiguration(config.PostgreSQL, validator) case config.Local != nil: @@ -49,6 +49,22 @@ func validateSQLConfiguration(config *schema.SQLStorageConfiguration, validator } } +func validateMySQLConfiguration(config *schema.MySQLStorageConfiguration, validator *schema.StructValidator) { + validateSQLConfiguration(&config.SQLStorageConfiguration, validator, "mysql") + + if config.TLS != nil { + configDefaultTLS := &schema.TLSConfig{ + ServerName: config.Host, + MinimumVersion: schema.DefaultMySQLStorageConfiguration.TLS.MinimumVersion, + MaximumVersion: schema.DefaultMySQLStorageConfiguration.TLS.MaximumVersion, + } + + if err := ValidateTLSConfig(config.TLS, configDefaultTLS); err != nil { + validator.Push(fmt.Errorf(errFmtStorageTLSConfigInvalid, "mysql", err)) + } + } +} + func validatePostgreSQLConfiguration(config *schema.PostgreSQLStorageConfiguration, validator *schema.StructValidator) { validateSQLConfiguration(&config.SQLStorageConfiguration, validator, "postgres") @@ -56,10 +72,28 @@ func validatePostgreSQLConfiguration(config *schema.PostgreSQLStorageConfigurati config.Schema = schema.DefaultPostgreSQLStorageConfiguration.Schema } - if config.SSL.Mode == "" { - config.SSL.Mode = schema.DefaultPostgreSQLStorageConfiguration.SSL.Mode - } else if !utils.IsStringInSlice(config.SSL.Mode, validStoragePostgreSQLSSLModes) { - validator.Push(fmt.Errorf(errFmtStoragePostgreSQLInvalidSSLMode, strings.Join(validStoragePostgreSQLSSLModes, "', '"), config.SSL.Mode)) + switch { + case config.TLS != nil && config.SSL != nil: + validator.Push(fmt.Errorf(errFmtStoragePostgreSQLInvalidSSLAndTLSConfig)) + case config.TLS != nil: + configDefaultTLS := &schema.TLSConfig{ + ServerName: config.Host, + MinimumVersion: schema.DefaultPostgreSQLStorageConfiguration.TLS.MinimumVersion, + MaximumVersion: schema.DefaultPostgreSQLStorageConfiguration.TLS.MaximumVersion, + } + + if err := ValidateTLSConfig(config.TLS, configDefaultTLS); err != nil { + validator.Push(fmt.Errorf(errFmtStorageTLSConfigInvalid, "postgres", err)) + } + case config.SSL != nil: + validator.PushWarning(fmt.Errorf(warnFmtStoragePostgreSQLInvalidSSLDeprecated)) + + switch { + case config.SSL.Mode == "": + config.SSL.Mode = schema.DefaultPostgreSQLStorageConfiguration.SSL.Mode + case !utils.IsStringInSlice(config.SSL.Mode, validStoragePostgreSQLSSLModes): + validator.Push(fmt.Errorf(errFmtStoragePostgreSQLInvalidSSLMode, strings.Join(validStoragePostgreSQLSSLModes, "', '"), config.SSL.Mode)) + } } } diff --git a/internal/configuration/validator/storage_test.go b/internal/configuration/validator/storage_test.go index bf0d0a67c..8ac7d9dbb 100644 --- a/internal/configuration/validator/storage_test.go +++ b/internal/configuration/validator/storage_test.go @@ -1,6 +1,7 @@ package validator import ( + "crypto/tls" "testing" "github.com/stretchr/testify/suite" @@ -79,6 +80,70 @@ func (suite *StorageSuite) TestShouldValidateMySQLHostUsernamePasswordAndDatabas suite.Require().Len(suite.validator.Errors(), 0) } +func (suite *StorageSuite) TestShouldSetDefaultMySQLTLSServerName() { + suite.config.MySQL = &schema.MySQLStorageConfiguration{ + SQLStorageConfiguration: schema.SQLStorageConfiguration{ + Host: "mysql1", + Username: "myuser", + Password: "pass", + Database: "database", + }, + TLS: &schema.TLSConfig{ + MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS12}, + }, + } + + ValidateStorage(suite.config, suite.validator) + + suite.Assert().Len(suite.validator.Warnings(), 0) + suite.Assert().Len(suite.validator.Errors(), 0) + + suite.Assert().Equal(suite.config.MySQL.Host, suite.config.MySQL.TLS.ServerName) +} + +func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidMySQLTLSVersion() { + suite.config.MySQL = &schema.MySQLStorageConfiguration{ + SQLStorageConfiguration: schema.SQLStorageConfiguration{ + Host: "db1", + Username: "myuser", + Password: "pass", + Database: "database", + }, + TLS: &schema.TLSConfig{ + MinimumVersion: schema.TLSVersion{Value: tls.VersionSSL30}, //nolint:staticcheck + }, + } + + ValidateStorage(suite.config, suite.validator) + + suite.Assert().Len(suite.validator.Warnings(), 0) + suite.Require().Len(suite.validator.Errors(), 1) + + suite.Assert().EqualError(suite.validator.Errors()[0], "storage: mysql: tls: option 'minimum_version' is invalid: minimum version is TLS1.0 but SSL3.0 was configured") +} + +func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidMySQLTLSMinVersionGreaterThanMaximum() { + suite.config.MySQL = &schema.MySQLStorageConfiguration{ + SQLStorageConfiguration: schema.SQLStorageConfiguration{ + Host: "db1", + Username: "myuser", + Password: "pass", + Database: "database", + }, + TLS: &schema.TLSConfig{ + MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS13}, + MaximumVersion: schema.TLSVersion{Value: tls.VersionTLS11}, + }, + } + + ValidateStorage(suite.config, suite.validator) + + suite.Assert().Len(suite.validator.Warnings(), 0) + suite.Require().Len(suite.validator.Errors(), 1) + + suite.Assert().EqualError(suite.validator.Errors()[0], "storage: mysql: tls: option combination of 'minimum_version' and 'maximum_version' is invalid: minimum version TLS1.3 is greater than the maximum version TLS1.1") +} + func (suite *StorageSuite) TestShouldValidatePostgreSQLHostUsernamePasswordAndDatabaseAreProvided() { suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{} suite.config.MySQL = nil @@ -104,7 +169,7 @@ func (suite *StorageSuite) TestShouldValidatePostgreSQLHostUsernamePasswordAndDa suite.Assert().Len(suite.validator.Errors(), 0) } -func (suite *StorageSuite) TestShouldValidatePostgresSSLModeAndSchemaDefaults() { +func (suite *StorageSuite) TestShouldValidatePostgresSchemaDefault() { suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ SQLStorageConfiguration: schema.SQLStorageConfiguration{ Host: "db1", @@ -119,10 +184,140 @@ func (suite *StorageSuite) TestShouldValidatePostgresSSLModeAndSchemaDefaults() suite.Assert().Len(suite.validator.Warnings(), 0) suite.Assert().Len(suite.validator.Errors(), 0) - suite.Assert().Equal("disable", suite.config.PostgreSQL.SSL.Mode) + suite.Assert().Nil(suite.config.PostgreSQL.SSL) + suite.Assert().Nil(suite.config.PostgreSQL.TLS) + suite.Assert().Equal("public", suite.config.PostgreSQL.Schema) } +func (suite *StorageSuite) TestShouldValidatePostgresTLSDefaults() { + suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ + SQLStorageConfiguration: schema.SQLStorageConfiguration{ + Host: "db1", + Username: "myuser", + Password: "pass", + Database: "database", + }, + TLS: &schema.TLSConfig{}, + } + + ValidateStorage(suite.config, suite.validator) + + suite.Assert().Len(suite.validator.Warnings(), 0) + suite.Assert().Len(suite.validator.Errors(), 0) + + suite.Assert().Nil(suite.config.PostgreSQL.SSL) + suite.Require().NotNil(suite.config.PostgreSQL.TLS) + + suite.Assert().Equal(uint16(tls.VersionTLS12), suite.config.PostgreSQL.TLS.MinimumVersion.Value) +} + +func (suite *StorageSuite) TestShouldSetDefaultPostgreSQLTLSServerName() { + suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ + SQLStorageConfiguration: schema.SQLStorageConfiguration{ + Host: "mysql1", + Username: "myuser", + Password: "pass", + Database: "database", + }, + TLS: &schema.TLSConfig{ + MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS12}, + }, + } + + ValidateStorage(suite.config, suite.validator) + + suite.Assert().Len(suite.validator.Warnings(), 0) + suite.Assert().Len(suite.validator.Errors(), 0) + + suite.Assert().Equal(suite.config.PostgreSQL.Host, suite.config.PostgreSQL.TLS.ServerName) +} + +func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidPostgreSQLTLSVersion() { + suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ + SQLStorageConfiguration: schema.SQLStorageConfiguration{ + Host: "db1", + Username: "myuser", + Password: "pass", + Database: "database", + }, + TLS: &schema.TLSConfig{ + MinimumVersion: schema.TLSVersion{Value: tls.VersionSSL30}, //nolint:staticcheck + }, + } + + ValidateStorage(suite.config, suite.validator) + + suite.Assert().Len(suite.validator.Warnings(), 0) + suite.Require().Len(suite.validator.Errors(), 1) + + suite.Assert().EqualError(suite.validator.Errors()[0], "storage: postgres: tls: option 'minimum_version' is invalid: minimum version is TLS1.0 but SSL3.0 was configured") +} + +func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidPostgreSQLMinVersionGreaterThanMaximum() { + suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ + SQLStorageConfiguration: schema.SQLStorageConfiguration{ + Host: "db1", + Username: "myuser", + Password: "pass", + Database: "database", + }, + TLS: &schema.TLSConfig{ + MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS13}, + MaximumVersion: schema.TLSVersion{Value: tls.VersionTLS11}, + }, + } + + ValidateStorage(suite.config, suite.validator) + + suite.Assert().Len(suite.validator.Warnings(), 0) + suite.Require().Len(suite.validator.Errors(), 1) + + suite.Assert().EqualError(suite.validator.Errors()[0], "storage: postgres: tls: option combination of 'minimum_version' and 'maximum_version' is invalid: minimum version TLS1.3 is greater than the maximum version TLS1.1") +} + +func (suite *StorageSuite) TestShouldValidatePostgresSSLDefaults() { + suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ + SQLStorageConfiguration: schema.SQLStorageConfiguration{ + Host: "db1", + Username: "myuser", + Password: "pass", + Database: "database", + }, + SSL: &schema.PostgreSQLSSLStorageConfiguration{}, + } + + ValidateStorage(suite.config, suite.validator) + + suite.Assert().Len(suite.validator.Warnings(), 1) + suite.Assert().Len(suite.validator.Errors(), 0) + + suite.Assert().NotNil(suite.config.PostgreSQL.SSL) + suite.Require().Nil(suite.config.PostgreSQL.TLS) + + suite.Assert().Equal(schema.DefaultPostgreSQLStorageConfiguration.SSL.Mode, suite.config.PostgreSQL.SSL.Mode) +} + +func (suite *StorageSuite) TestShouldRaiseErrorOnTLSAndLegacySSL() { + suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ + SQLStorageConfiguration: schema.SQLStorageConfiguration{ + Host: "db1", + Username: "myuser", + Password: "pass", + Database: "database", + }, + SSL: &schema.PostgreSQLSSLStorageConfiguration{}, + TLS: &schema.TLSConfig{}, + } + + ValidateStorage(suite.config, suite.validator) + + suite.Assert().Len(suite.validator.Warnings(), 0) + suite.Require().Len(suite.validator.Errors(), 1) + + suite.Assert().EqualError(suite.validator.Errors()[0], "storage: postgres: can't define both 'tls' and 'ssl' configuration options") +} + func (suite *StorageSuite) TestShouldValidatePostgresDefaultsDontOverrideConfiguration() { suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ SQLStorageConfiguration: schema.SQLStorageConfiguration{ @@ -132,18 +327,20 @@ func (suite *StorageSuite) TestShouldValidatePostgresDefaultsDontOverrideConfigu Database: "database", }, Schema: "authelia", - SSL: schema.PostgreSQLSSLStorageConfiguration{ + SSL: &schema.PostgreSQLSSLStorageConfiguration{ Mode: "require", }, } ValidateStorage(suite.config, suite.validator) - suite.Assert().Len(suite.validator.Warnings(), 0) + suite.Require().Len(suite.validator.Warnings(), 1) suite.Assert().Len(suite.validator.Errors(), 0) suite.Assert().Equal("require", suite.config.PostgreSQL.SSL.Mode) suite.Assert().Equal("authelia", suite.config.PostgreSQL.Schema) + + suite.Assert().EqualError(suite.validator.Warnings()[0], "storage: postgres: ssl: the ssl configuration options are deprecated and we recommend the tls options instead") } func (suite *StorageSuite) TestShouldValidatePostgresSSLModeMustBeValid() { @@ -154,14 +351,14 @@ func (suite *StorageSuite) TestShouldValidatePostgresSSLModeMustBeValid() { Password: "pass", Database: "database", }, - SSL: schema.PostgreSQLSSLStorageConfiguration{ + SSL: &schema.PostgreSQLSSLStorageConfiguration{ Mode: "unknown", }, } ValidateStorage(suite.config, suite.validator) - suite.Assert().Len(suite.validator.Warnings(), 0) + suite.Assert().Len(suite.validator.Warnings(), 1) suite.Require().Len(suite.validator.Errors(), 1) suite.Assert().EqualError(suite.validator.Errors()[0], "storage: postgres: ssl: option 'mode' must be one of 'disable', 'require', 'verify-ca', 'verify-full' but it is configured as 'unknown'") } diff --git a/internal/storage/sql_provider_backend_mysql.go b/internal/storage/sql_provider_backend_mysql.go index b0382ed7d..32cc7de16 100644 --- a/internal/storage/sql_provider_backend_mysql.go +++ b/internal/storage/sql_provider_backend_mysql.go @@ -9,6 +9,7 @@ import ( "github.com/go-sql-driver/mysql" "github.com/authelia/authelia/v4/internal/configuration/schema" + "github.com/authelia/authelia/v4/internal/utils" ) // MySQLProvider is a MySQL provider. @@ -19,7 +20,7 @@ type MySQLProvider struct { // NewMySQLProvider a MySQL provider. func NewMySQLProvider(config *schema.Configuration, caCertPool *x509.CertPool) (provider *MySQLProvider) { provider = &MySQLProvider{ - SQLProvider: NewSQLProvider(config, providerMySQL, providerMySQL, dsnMySQL(config.Storage.MySQL)), + SQLProvider: NewSQLProvider(config, providerMySQL, providerMySQL, dsnMySQL(config.Storage.MySQL, caCertPool)), } // All providers have differing SELECT existing table statements. @@ -31,7 +32,7 @@ func NewMySQLProvider(config *schema.Configuration, caCertPool *x509.CertPool) ( return provider } -func dsnMySQL(config *schema.MySQLStorageConfiguration) (dataSourceName string) { +func dsnMySQL(config *schema.MySQLStorageConfiguration, caCertPool *x509.CertPool) (dataSourceName string) { dsnConfig := mysql.NewConfig() switch { @@ -46,6 +47,12 @@ func dsnMySQL(config *schema.MySQLStorageConfiguration) (dataSourceName string) dsnConfig.Addr = fmt.Sprintf("%s:%d", config.Host, config.Port) } + if config.TLS != nil { + _ = mysql.RegisterTLSConfig("storage", utils.NewTLSConfig(config.TLS, caCertPool)) + + dsnConfig.TLSConfig = "storage" + } + switch config.Port { case 0: dsnConfig.Addr = config.Host diff --git a/internal/storage/sql_provider_backend_postgres.go b/internal/storage/sql_provider_backend_postgres.go index 80f9929aa..19a14f351 100644 --- a/internal/storage/sql_provider_backend_postgres.go +++ b/internal/storage/sql_provider_backend_postgres.go @@ -12,6 +12,7 @@ import ( "github.com/jackc/pgx/v5/stdlib" "github.com/authelia/authelia/v4/internal/configuration/schema" + "github.com/authelia/authelia/v4/internal/utils" ) // PostgreSQLProvider is a PostgreSQL provider. @@ -135,42 +136,12 @@ func NewPostgreSQLProvider(config *schema.Configuration, caCertPool *x509.CertPo func dsnPostgreSQL(config *schema.PostgreSQLStorageConfiguration, globalCACertPool *x509.CertPool) (dsn string) { dsnConfig, _ := pgx.ParseConfig("") - ca, certs := loadPostgreSQLLegacyTLS(config) - - switch config.SSL.Mode { - case "disable": - break - default: - var caCertPool *x509.CertPool - - switch ca { - case nil: - caCertPool = globalCACertPool - default: - caCertPool = globalCACertPool.Clone() - caCertPool.AddCert(ca) - } - - dsnConfig.TLSConfig = &tls.Config{ - Certificates: certs, - RootCAs: caCertPool, - InsecureSkipVerify: true, //nolint:gosec - } - - switch { - case config.SSL.Mode == "require" && config.SSL.RootCertificate != "" || config.SSL.Mode == "verify-ca": - dsnConfig.TLSConfig.VerifyPeerCertificate = newPostgreSQLVerifyCAFunc(dsnConfig.TLSConfig) - case config.SSL.Mode == "verify-full": - dsnConfig.TLSConfig.InsecureSkipVerify = false - dsnConfig.TLSConfig.ServerName = config.Host - } - } - dsnConfig.Host = config.Host dsnConfig.Port = uint16(config.Port) dsnConfig.Database = config.Database dsnConfig.User = config.Username dsnConfig.Password = config.Password + dsnConfig.TLSConfig = loadPostgreSQLTLSConfig(config, globalCACertPool) dsnConfig.ConnectTimeout = config.Timeout dsnConfig.RuntimeParams = map[string]string{ "search_path": config.Schema, @@ -183,7 +154,50 @@ func dsnPostgreSQL(config *schema.PostgreSQLStorageConfiguration, globalCACertPo return stdlib.RegisterConnConfig(dsnConfig) } -func loadPostgreSQLLegacyTLS(config *schema.PostgreSQLStorageConfiguration) (ca *x509.Certificate, certs []tls.Certificate) { +func loadPostgreSQLTLSConfig(config *schema.PostgreSQLStorageConfiguration, globalCACertPool *x509.CertPool) (tlsConfig *tls.Config) { + if config.TLS == nil && config.SSL == nil { + return nil + } + + if config.TLS != nil { + return utils.NewTLSConfig(config.TLS, globalCACertPool) + } + + ca, certs := loadPostgreSQLLegacyTLSConfig(config) + + switch config.SSL.Mode { + case "disable": + return nil + default: + var caCertPool *x509.CertPool + + switch ca { + case nil: + caCertPool = globalCACertPool + default: + caCertPool = globalCACertPool.Clone() + caCertPool.AddCert(ca) + } + + tlsConfig = &tls.Config{ + Certificates: certs, + RootCAs: caCertPool, + InsecureSkipVerify: true, //nolint:gosec + } + + switch { + case config.SSL.Mode == "require" && config.SSL.RootCertificate != "" || config.SSL.Mode == "verify-ca": + tlsConfig.VerifyPeerCertificate = newPostgreSQLVerifyCAFunc(tlsConfig) + case config.SSL.Mode == "verify-full": + tlsConfig.InsecureSkipVerify = false + tlsConfig.ServerName = config.Host + } + } + + return tlsConfig +} + +func loadPostgreSQLLegacyTLSConfig(config *schema.PostgreSQLStorageConfiguration) (ca *x509.Certificate, certs []tls.Certificate) { var ( err error ) diff --git a/internal/utils/crypto.go b/internal/utils/crypto.go index e8408cee6..2e2dbab2d 100644 --- a/internal/utils/crypto.go +++ b/internal/utils/crypto.go @@ -235,7 +235,7 @@ func IsX509PrivateKey(i any) bool { } // NewTLSConfig generates a tls.Config from a schema.TLSConfig and a x509.CertPool. -func NewTLSConfig(config *schema.TLSConfig, certPool *x509.CertPool) (tlsConfig *tls.Config) { +func NewTLSConfig(config *schema.TLSConfig, caCertPool *x509.CertPool) (tlsConfig *tls.Config) { var certificates []tls.Certificate if config.CertificateChain.HasCertificates() && config.PrivateKey != nil { @@ -253,7 +253,7 @@ func NewTLSConfig(config *schema.TLSConfig, certPool *x509.CertPool) (tlsConfig InsecureSkipVerify: config.SkipVerify, //nolint:gosec // Informed choice by user. Off by default. MinVersion: config.MinimumVersion.MinVersion(), MaxVersion: config.MinimumVersion.MaxVersion(), - RootCAs: certPool, + RootCAs: caCertPool, Certificates: certificates, } }