mirror of
https://github.com/0rangebananaspy/authelia.git
synced 2024-09-14 22:47:21 +07:00
[DEPRECATE] Environment Variable Secrets (#905)
* remove ENV usages * fix reader unit tests * fix standalone suite * fix k8s suite * apply suggestions from code review Co-authored-by: Amir Zarrinkafsh <nightah@me.com>
This commit is contained in:
parent
a70e460ff4
commit
9e7947a193
|
@ -6,6 +6,11 @@ recommended not to use the 'latest' Docker image tag blindly but pick a version
|
||||||
and read this documentation before upgrading. This is where you will get information about
|
and read this documentation before upgrading. This is where you will get information about
|
||||||
breaking changes and about what you should do to overcome those changes.
|
breaking changes and about what you should do to overcome those changes.
|
||||||
|
|
||||||
|
## Breaking in v4.18.0
|
||||||
|
* Secrets stored directly in ENV are now removed from Authelia. They have been replaced with file
|
||||||
|
secrets. If you still have not moved feel free to contact the team for assistance, otherwise the
|
||||||
|
[documentation](https://docs.authelia.com/configuration/secrets.html) has instructions on how to utilize these.
|
||||||
|
|
||||||
## Breaking in v4.15.0
|
## Breaking in v4.15.0
|
||||||
* Previously if a configuration value did not exist we ignored it. Now we will error if someone has
|
* Previously if a configuration value did not exist we ignored it. Now we will error if someone has
|
||||||
specified either an unknown configuration key or one that has changed. In the instance of a changed
|
specified either an unknown configuration key or one that has changed. In the instance of a changed
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
host: 0.0.0.0
|
host: 0.0.0.0
|
||||||
port: 9091
|
port: 9091
|
||||||
log_level: debug
|
log_level: debug
|
||||||
# This secret can also be set using the env variables AUTHELIA_JWT_SECRET
|
# This secret can also be set using the env variables AUTHELIA_JWT_SECRET_FILE
|
||||||
jwt_secret: a_very_important_secret
|
jwt_secret: a_very_important_secret
|
||||||
default_redirection_url: https://public.example.com
|
default_redirection_url: https://public.example.com
|
||||||
totp:
|
totp:
|
||||||
|
@ -14,7 +14,7 @@ totp:
|
||||||
#duo_api:
|
#duo_api:
|
||||||
# hostname: api-123456789.example.com
|
# hostname: api-123456789.example.com
|
||||||
# integration_key: ABCDEF
|
# integration_key: ABCDEF
|
||||||
# # This secret can also be set using the env variables AUTHELIA_DUO_API_SECRET_KEY
|
# # This secret can also be set using the env variables AUTHELIA_DUO_API_SECRET_KEY_FILE
|
||||||
# secret_key: 1234567890abcdefghifjkl
|
# secret_key: 1234567890abcdefghifjkl
|
||||||
|
|
||||||
authentication_backend:
|
authentication_backend:
|
||||||
|
@ -34,7 +34,7 @@ access_control:
|
||||||
|
|
||||||
session:
|
session:
|
||||||
name: authelia_session
|
name: authelia_session
|
||||||
# This secret can also be set using the env variables AUTHELIA_SESSION_SECRET
|
# This secret can also be set using the env variables AUTHELIA_SESSION_SECRET_FILE
|
||||||
secret: unsecure_session_secret
|
secret: unsecure_session_secret
|
||||||
expiration: 3600 # 1 hour
|
expiration: 3600 # 1 hour
|
||||||
inactivity: 300 # 5 minutes
|
inactivity: 300 # 5 minutes
|
||||||
|
@ -43,7 +43,7 @@ session:
|
||||||
redis:
|
redis:
|
||||||
host: redis
|
host: redis
|
||||||
port: 6379
|
port: 6379
|
||||||
# This secret can also be set using the env variables AUTHELIA_SESSION_REDIS_PASSWORD
|
# This secret can also be set using the env variables AUTHELIA_SESSION_REDIS_PASSWORD_FILE
|
||||||
password: authelia
|
password: authelia
|
||||||
|
|
||||||
regulation:
|
regulation:
|
||||||
|
@ -58,7 +58,7 @@ storage:
|
||||||
notifier:
|
notifier:
|
||||||
smtp:
|
smtp:
|
||||||
username: test
|
username: test
|
||||||
# This secret can also be set using the env variables AUTHELIA_NOTIFIER_SMTP_PASSWORD
|
# This secret can also be set using the env variables AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE
|
||||||
password: password
|
password: password
|
||||||
host: mail.example.com
|
host: mail.example.com
|
||||||
port: 25
|
port: 25
|
||||||
|
|
|
@ -42,22 +42,6 @@ environment variable will not be replaced.
|
||||||
|notifier.smtp.password |AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE |
|
|notifier.smtp.password |AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE |
|
||||||
|authentication_backend.ldap.password|AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE|
|
|authentication_backend.ldap.password|AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE|
|
||||||
|
|
||||||
|
|
||||||
## Secrets exposed in an environment variable
|
|
||||||
|
|
||||||
Prior to implementing file secrets you were able to define the
|
|
||||||
values of secrets in the environment variables themselves
|
|
||||||
in plain text instead of referencing a file. This is still
|
|
||||||
supported but discouraged. If you still want to do this
|
|
||||||
just remove _FILE from the environment variable name
|
|
||||||
and define the value in insecure plain text. See
|
|
||||||
[this article](https://diogomonica.com/2017/03/27/why-you-shouldnt-use-env-variables-for-secret-data/)
|
|
||||||
for reasons why this is considered insecure and is discouraged.
|
|
||||||
|
|
||||||
**DEPRECATION NOTICE:** This backwards compatibility feature will be
|
|
||||||
**removed** in 4.18.0+.
|
|
||||||
|
|
||||||
|
|
||||||
## Secrets in configuration file
|
## Secrets in configuration file
|
||||||
|
|
||||||
If for some reason you prefer keeping the secrets in the configuration
|
If for some reason you prefer keeping the secrets in the configuration
|
||||||
|
@ -65,6 +49,16 @@ file, be sure to apply the right permissions to the file in order to
|
||||||
prevent secret leaks if an another application gets compromised on your
|
prevent secret leaks if an another application gets compromised on your
|
||||||
server. The UNIX permissions should probably be something like 600.
|
server. The UNIX permissions should probably be something like 600.
|
||||||
|
|
||||||
|
## Secrets exposed in an environment variable
|
||||||
|
|
||||||
|
**DEPRECATION NOTICE:** This backwards compatibility feature **has been removed** in 4.18.0+.
|
||||||
|
|
||||||
|
Prior to implementing file secrets you were able to define the
|
||||||
|
values of secrets in the environment variables themselves
|
||||||
|
in plain text instead of referencing a file. **This is no longer available
|
||||||
|
as an option**, please see the table above for the file based replacements. See
|
||||||
|
[this article](https://diogomonica.com/2017/03/27/why-you-shouldnt-use-env-variables-for-secret-data/)
|
||||||
|
for reasons why this was removed.
|
||||||
|
|
||||||
## Docker
|
## Docker
|
||||||
|
|
||||||
|
|
|
@ -14,17 +14,6 @@ import (
|
||||||
func Read(configPath string) (*schema.Configuration, []error) {
|
func Read(configPath string) (*schema.Configuration, []error) {
|
||||||
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||||
|
|
||||||
// we need to bind all env variables as long as https://github.com/spf13/viper/issues/761
|
|
||||||
// is not resolved.
|
|
||||||
viper.BindEnv("authelia.jwt_secret") //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
|
|
||||||
viper.BindEnv("authelia.duo_api.secret_key") //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
|
|
||||||
viper.BindEnv("authelia.session.secret") //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
|
|
||||||
viper.BindEnv("authelia.authentication_backend.ldap.password") //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
|
|
||||||
viper.BindEnv("authelia.notifier.smtp.password") //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
|
|
||||||
viper.BindEnv("authelia.session.redis.password") //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
|
|
||||||
viper.BindEnv("authelia.storage.mysql.password") //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
|
|
||||||
viper.BindEnv("authelia.storage.postgres.password") //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
|
|
||||||
|
|
||||||
viper.BindEnv("authelia.jwt_secret.file") //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
|
viper.BindEnv("authelia.jwt_secret.file") //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
|
||||||
viper.BindEnv("authelia.duo_api.secret_key.file") //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
|
viper.BindEnv("authelia.duo_api.secret_key.file") //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
|
||||||
viper.BindEnv("authelia.session.secret.file") //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
|
viper.BindEnv("authelia.session.secret.file") //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
|
||||||
|
|
|
@ -1,36 +1,73 @@
|
||||||
package configuration
|
package configuration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/authentication"
|
||||||
|
"github.com/authelia/authelia/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func createTestingTempFile(t *testing.T, dir, name, content string) {
|
||||||
|
err := ioutil.WriteFile(path.Join(dir, name), []byte(content), 0600)
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
func resetEnv() {
|
func resetEnv() {
|
||||||
_ = os.Unsetenv("AUTHELIA_JWT_SECRET")
|
_ = os.Unsetenv("AUTHELIA_JWT_SECRET_FILE")
|
||||||
_ = os.Unsetenv("AUTHELIA_DUO_API_SECRET_KEY")
|
_ = os.Unsetenv("AUTHELIA_DUO_API_SECRET_KEY_FILE")
|
||||||
_ = os.Unsetenv("AUTHELIA_SESSION_SECRET")
|
_ = os.Unsetenv("AUTHELIA_SESSION_SECRET_FILE")
|
||||||
_ = os.Unsetenv("AUTHELIA_SESSION_SECRET")
|
_ = os.Unsetenv("AUTHELIA_SESSION_SECRET_FILE")
|
||||||
_ = os.Unsetenv("AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD")
|
_ = os.Unsetenv("AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE")
|
||||||
_ = os.Unsetenv("AUTHELIA_NOTIFIER_SMTP_PASSWORD")
|
_ = os.Unsetenv("AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE")
|
||||||
_ = os.Unsetenv("AUTHELIA_SESSION_REDIS_PASSWORD")
|
_ = os.Unsetenv("AUTHELIA_SESSION_REDIS_PASSWORD_FILE")
|
||||||
_ = os.Unsetenv("AUTHELIA_STORAGE_MYSQL_PASSWORD")
|
_ = os.Unsetenv("AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE")
|
||||||
_ = os.Unsetenv("AUTHELIA_STORAGE_POSTGRES_PASSWORD")
|
_ = os.Unsetenv("AUTHELIA_STORAGE_POSTGRES_PASSWORD_FILE")
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupEnv(t *testing.T) string {
|
||||||
|
resetEnv()
|
||||||
|
|
||||||
|
dirEnv := os.Getenv("AUTHELIA_TESTING_DIR")
|
||||||
|
if dirEnv != "" {
|
||||||
|
return dirEnv
|
||||||
|
}
|
||||||
|
|
||||||
|
dir := "/tmp/authelia" + utils.RandomString(10, authentication.HashingPossibleSaltCharacters) + "/"
|
||||||
|
err := os.MkdirAll(dir, 0700)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
createTestingTempFile(t, dir, "jwt", "secret_from_env")
|
||||||
|
createTestingTempFile(t, dir, "duo", "duo_secret_from_env")
|
||||||
|
createTestingTempFile(t, dir, "session", "session_secret_from_env")
|
||||||
|
createTestingTempFile(t, dir, "authentication", "ldap_secret_from_env")
|
||||||
|
createTestingTempFile(t, dir, "notifier", "smtp_secret_from_env")
|
||||||
|
createTestingTempFile(t, dir, "redis", "redis_secret_from_env")
|
||||||
|
createTestingTempFile(t, dir, "mysql", "mysql_secret_from_env")
|
||||||
|
createTestingTempFile(t, dir, "postgres", "postgres_secret_from_env")
|
||||||
|
|
||||||
|
require.NoError(t, os.Setenv("AUTHELIA_TESTING_DIR", dir))
|
||||||
|
|
||||||
|
return dir
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShouldParseConfigFile(t *testing.T) {
|
func TestShouldParseConfigFile(t *testing.T) {
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_JWT_SECRET", "secret_from_env"))
|
dir := setupEnv(t)
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_DUO_API_SECRET_KEY", "duo_secret_from_env"))
|
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_SESSION_SECRET", "session_secret_from_env"))
|
require.NoError(t, os.Setenv("AUTHELIA_JWT_SECRET_FILE", dir+"jwt"))
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD", "ldap_secret_from_env"))
|
require.NoError(t, os.Setenv("AUTHELIA_DUO_API_SECRET_KEY_FILE", dir+"duo"))
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_NOTIFIER_SMTP_PASSWORD", "smtp_secret_from_env"))
|
require.NoError(t, os.Setenv("AUTHELIA_SESSION_SECRET_FILE", dir+"session"))
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_SESSION_REDIS_PASSWORD", "redis_secret_from_env"))
|
require.NoError(t, os.Setenv("AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE", dir+"authentication"))
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_STORAGE_MYSQL_PASSWORD", "mysql_secret_from_env"))
|
require.NoError(t, os.Setenv("AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE", dir+"notifier"))
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_STORAGE_POSTGRES_PASSWORD", "postgres_secret_from_env"))
|
require.NoError(t, os.Setenv("AUTHELIA_SESSION_REDIS_PASSWORD_FILE", dir+"redis"))
|
||||||
|
require.NoError(t, os.Setenv("AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE", dir+"mysql"))
|
||||||
|
require.NoError(t, os.Setenv("AUTHELIA_STORAGE_POSTGRES_PASSWORD_FILE", dir+"postgres"))
|
||||||
|
|
||||||
config, errors := Read("./test_resources/config.yml")
|
config, errors := Read("./test_resources/config.yml")
|
||||||
|
|
||||||
|
@ -57,7 +94,12 @@ func TestShouldParseConfigFile(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShouldParseAltConfigFile(t *testing.T) {
|
func TestShouldParseAltConfigFile(t *testing.T) {
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_STORAGE_POSTGRES_PASSWORD", "postgres_secret_from_env"))
|
dir := setupEnv(t)
|
||||||
|
|
||||||
|
require.NoError(t, os.Setenv("AUTHELIA_STORAGE_POSTGRES_PASSWORD_FILE", dir+"postgres"))
|
||||||
|
require.NoError(t, os.Setenv("AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE", dir+"authentication"))
|
||||||
|
require.NoError(t, os.Setenv("AUTHELIA_JWT_SECRET_FILE", dir+"jwt"))
|
||||||
|
require.NoError(t, os.Setenv("AUTHELIA_SESSION_SECRET_FILE", dir+"session"))
|
||||||
|
|
||||||
config, errors := Read("./test_resources/config_alt.yml")
|
config, errors := Read("./test_resources/config_alt.yml")
|
||||||
require.Len(t, errors, 0)
|
require.Len(t, errors, 0)
|
||||||
|
@ -77,14 +119,15 @@ func TestShouldParseAltConfigFile(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShouldNotParseConfigFileWithOldOrUnexpectedKeys(t *testing.T) {
|
func TestShouldNotParseConfigFileWithOldOrUnexpectedKeys(t *testing.T) {
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_JWT_SECRET", "secret_from_env"))
|
dir := setupEnv(t)
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_DUO_API_SECRET_KEY", "duo_secret_from_env"))
|
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_SESSION_SECRET", "session_secret_from_env"))
|
require.NoError(t, os.Setenv("AUTHELIA_JWT_SECRET_FILE", dir+"jwt"))
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD", "ldap_secret_from_env"))
|
require.NoError(t, os.Setenv("AUTHELIA_DUO_API_SECRET_KEY_FILE", dir+"duo"))
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_NOTIFIER_SMTP_PASSWORD", "smtp_secret_from_env"))
|
require.NoError(t, os.Setenv("AUTHELIA_SESSION_SECRET_FILE", dir+"session"))
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_SESSION_REDIS_PASSWORD", "redis_secret_from_env"))
|
require.NoError(t, os.Setenv("AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE", dir+"authentication"))
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_STORAGE_MYSQL_PASSWORD", "mysql_secret_from_env"))
|
require.NoError(t, os.Setenv("AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE", dir+"notifier"))
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_STORAGE_POSTGRES_PASSWORD", "postgres_secret_from_env"))
|
require.NoError(t, os.Setenv("AUTHELIA_SESSION_REDIS_PASSWORD_FILE", dir+"redis"))
|
||||||
|
require.NoError(t, os.Setenv("AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE", dir+"mysql"))
|
||||||
|
|
||||||
_, errors := Read("./test_resources/config_bad_keys.yml")
|
_, errors := Read("./test_resources/config_bad_keys.yml")
|
||||||
require.Len(t, errors, 2)
|
require.Len(t, errors, 2)
|
||||||
|
@ -104,33 +147,17 @@ func TestShouldValidateConfigurationTemplate(t *testing.T) {
|
||||||
assert.Len(t, errors, 0)
|
assert.Len(t, errors, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShouldOnlyAllowOneEnvType(t *testing.T) {
|
|
||||||
resetEnv()
|
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_STORAGE_POSTGRES_PASSWORD", "postgres_secret_from_env"))
|
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_STORAGE_POSTGRES_PASSWORD_FILE", "/tmp/postgres_secret"))
|
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_JWT_SECRET", "secret_from_env"))
|
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_DUO_API_SECRET_KEY", "duo_secret_from_env"))
|
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_SESSION_SECRET", "session_secret_from_env"))
|
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD", "ldap_secret_from_env"))
|
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_NOTIFIER_SMTP_PASSWORD", "smtp_secret_from_env"))
|
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_SESSION_REDIS_PASSWORD", "redis_secret_from_env"))
|
|
||||||
|
|
||||||
_, errors := Read("./test_resources/config_alt.yml")
|
|
||||||
|
|
||||||
require.Len(t, errors, 2)
|
|
||||||
assert.EqualError(t, errors[0], "secret is defined in multiple areas: storage.postgres.password")
|
|
||||||
assert.True(t, strings.HasPrefix(errors[1].Error(), "error loading secret file (storage.postgres.password): open /tmp/postgres_secret: "))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestShouldOnlyAllowEnvOrConfig(t *testing.T) {
|
func TestShouldOnlyAllowEnvOrConfig(t *testing.T) {
|
||||||
|
dir := setupEnv(t)
|
||||||
|
|
||||||
resetEnv()
|
resetEnv()
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_STORAGE_MYSQL_PASSWORD", "mysql_secret_from_env"))
|
require.NoError(t, os.Setenv("AUTHELIA_JWT_SECRET_FILE", dir+"jwt"))
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_JWT_SECRET", "secret_from_env"))
|
require.NoError(t, os.Setenv("AUTHELIA_DUO_API_SECRET_KEY_FILE", dir+"duo"))
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_DUO_API_SECRET_KEY", "duo_secret_from_env"))
|
require.NoError(t, os.Setenv("AUTHELIA_SESSION_SECRET_FILE", dir+"session"))
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_SESSION_SECRET", "session_secret_from_env"))
|
require.NoError(t, os.Setenv("AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE", dir+"authentication"))
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD", "ldap_secret_from_env"))
|
require.NoError(t, os.Setenv("AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE", dir+"notifier"))
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_NOTIFIER_SMTP_PASSWORD", "smtp_secret_from_env"))
|
require.NoError(t, os.Setenv("AUTHELIA_SESSION_REDIS_PASSWORD_FILE", dir+"redis"))
|
||||||
require.NoError(t, os.Setenv("AUTHELIA_SESSION_REDIS_PASSWORD", "redis_secret_from_env"))
|
require.NoError(t, os.Setenv("AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE", dir+"mysql"))
|
||||||
|
|
||||||
_, errors := Read("./test_resources/config_with_secret.yml")
|
_, errors := Read("./test_resources/config_with_secret.yml")
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
"github.com/authelia/authelia/internal/logging"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ValidateSecrets checks that secrets are either specified by config file/env or by file references.
|
// ValidateSecrets checks that secrets are either specified by config file/env or by file references.
|
||||||
|
@ -43,15 +42,10 @@ func ValidateSecrets(configuration *schema.Configuration, validator *schema.Stru
|
||||||
|
|
||||||
func getSecretValue(name string, validator *schema.StructValidator, viper *viper.Viper) string {
|
func getSecretValue(name string, validator *schema.StructValidator, viper *viper.Viper) string {
|
||||||
configValue := viper.GetString(name)
|
configValue := viper.GetString(name)
|
||||||
envValue := viper.GetString("authelia." + name)
|
|
||||||
fileEnvValue := viper.GetString("authelia." + name + ".file")
|
fileEnvValue := viper.GetString("authelia." + name + ".file")
|
||||||
|
|
||||||
// Error Checking.
|
// Error Checking.
|
||||||
if envValue != "" && fileEnvValue != "" {
|
if fileEnvValue != "" && configValue != "" {
|
||||||
validator.Push(fmt.Errorf("secret is defined in multiple areas: %s", name))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (envValue != "" || fileEnvValue != "") && configValue != "" {
|
|
||||||
validator.Push(fmt.Errorf("error loading secret (%s): it's already defined in the config file", name))
|
validator.Push(fmt.Errorf("error loading secret (%s): it's already defined in the config file", name))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,10 +59,5 @@ func getSecretValue(name string, validator *schema.StructValidator, viper *viper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if envValue != "" {
|
|
||||||
logging.Logger().Warnf("The following secret is defined as an environment variable, this is insecure and being removed in 4.18.0+, it's recommended to use the file secrets instead (https://docs.authelia.com/configuration/secrets.html): %s", name)
|
|
||||||
return envValue
|
|
||||||
}
|
|
||||||
|
|
||||||
return configValue
|
return configValue
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@ version: '3'
|
||||||
services:
|
services:
|
||||||
authelia-backend:
|
authelia-backend:
|
||||||
environment:
|
environment:
|
||||||
- AUTHELIA_JWT_SECRET=very_important_secret
|
- AUTHELIA_JWT_SECRET_FILE=/tmp/authelia/StandaloneSuite/jwt
|
||||||
- AUTHELIA_SESSION_SECRET=unsecure_session_secret
|
- AUTHELIA_SESSION_SECRET_FILE=/tmp/authelia/StandaloneSuite/session
|
||||||
volumes:
|
volumes:
|
||||||
- './Standalone/configuration.yml:/etc/authelia/configuration.yml:ro'
|
- './Standalone/configuration.yml:/etc/authelia/configuration.yml:ro'
|
||||||
- './Standalone/users.yml:/var/lib/authelia/users.yml'
|
- './Standalone/users.yml:/var/lib/authelia/users.yml'
|
||||||
|
|
|
@ -26,17 +26,20 @@ spec:
|
||||||
mountPath: /etc/authelia
|
mountPath: /etc/authelia
|
||||||
- name: ssl-volume
|
- name: ssl-volume
|
||||||
mountPath: /var/lib/authelia/ssl
|
mountPath: /var/lib/authelia/ssl
|
||||||
|
- name: secrets
|
||||||
|
mountPath: /usr/app/secrets
|
||||||
|
readOnly: true
|
||||||
env:
|
env:
|
||||||
# We set secrets directly here for ease of deployment but all secrets
|
# We set secrets directly here for ease of deployment but all secrets
|
||||||
# should be stored in the Kube Vault in production.
|
# should be stored in the Kube Vault in production.
|
||||||
- name: AUTHELIA_JWT_SECRET
|
- name: AUTHELIA_JWT_SECRET_FILE
|
||||||
value: an_unsecure_secret
|
value: /usr/app/secrets/jwt_secret
|
||||||
- name: AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD
|
- name: AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE
|
||||||
value: password
|
value: /usr/app/secrets/ldap_password
|
||||||
- name: AUTHELIA_SESSION_SECRET
|
- name: AUTHELIA_SESSION_SECRET_FILE
|
||||||
value: unsecure_password
|
value: /usr/app/secrets/session
|
||||||
- name: AUTHELIA_STORAGE_MYSQL_PASSWORD
|
- name: AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE
|
||||||
value: password
|
value: /usr/app/secrets/sql_password
|
||||||
volumes:
|
volumes:
|
||||||
- name: config-volume
|
- name: config-volume
|
||||||
configMap:
|
configMap:
|
||||||
|
@ -52,4 +55,15 @@ spec:
|
||||||
path: cert.pem
|
path: cert.pem
|
||||||
- key: key.pem
|
- key: key.pem
|
||||||
path: key.pem
|
path: key.pem
|
||||||
|
- name: secrets
|
||||||
|
secret:
|
||||||
|
secretName: authelia
|
||||||
|
items:
|
||||||
|
- key: jwt_secret
|
||||||
|
path: jwt_secret
|
||||||
|
- key: session
|
||||||
|
path: session
|
||||||
|
- key: sql_password
|
||||||
|
path: sql_password
|
||||||
|
- key: ldap_password
|
||||||
|
path: ldap_password
|
14
internal/suites/example/kube/authelia/secret.yml
Normal file
14
internal/suites/example/kube/authelia/secret.yml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
type: Opaque
|
||||||
|
metadata:
|
||||||
|
name: authelia
|
||||||
|
namespace: authelia
|
||||||
|
labels:
|
||||||
|
app: authelia
|
||||||
|
data:
|
||||||
|
jwt_secret: YW5fdW5zZWN1cmVfc2VjcmV0 #an_unsecure_secret
|
||||||
|
ldap_password: cGFzc3dvcmQ= #password
|
||||||
|
session: dW5zZWN1cmVfcGFzc3dvcmQ= #unsecure_password
|
||||||
|
sql_password: cGFzc3dvcmQ= #password
|
|
@ -2,12 +2,18 @@ package suites
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var standaloneSuiteName = "Standalone"
|
var standaloneSuiteName = "Standalone"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
_ = os.MkdirAll("/tmp/authelia/StandaloneSuite/", 0700)
|
||||||
|
_ = ioutil.WriteFile("/tmp/authelia/StandaloneSuite/jwt", []byte("very_important_secret"), 0600) //nolint:gosec
|
||||||
|
_ = ioutil.WriteFile("/tmp/authelia/StandaloneSuite/session", []byte("unsecure_session_secret"), 0600) //nolint:gosec
|
||||||
|
|
||||||
dockerEnvironment := NewDockerEnvironment([]string{
|
dockerEnvironment := NewDockerEnvironment([]string{
|
||||||
"internal/suites/docker-compose.yml",
|
"internal/suites/docker-compose.yml",
|
||||||
"internal/suites/Standalone/docker-compose.yml",
|
"internal/suites/Standalone/docker-compose.yml",
|
||||||
|
|
Loading…
Reference in New Issue
Block a user