oidc: allow reading the client secret from a file

Currently the most "secret" way to specify the oidc client secret is via
an environment variable `OIDC_CLIENT_SECRET`, which is problematic[1].
Lets allow reading oidc client secret from a file. For extra convenience
the path to the secret will resolve the environment variables.

[1]: https://systemd.io/CREDENTIALS/
This commit is contained in:
Motiejus Jakštys 2023-01-10 13:46:42 +02:00 committed by Kristoffer Dalby
parent 6edac4863a
commit bafb6791d3
6 changed files with 59 additions and 8 deletions

View file

@ -60,7 +60,8 @@ func TestOIDCAuthenticationPingAll(t *testing.T) {
oidcMap := map[string]string{
"HEADSCALE_OIDC_ISSUER": oidcConfig.Issuer,
"HEADSCALE_OIDC_CLIENT_ID": oidcConfig.ClientID,
"HEADSCALE_OIDC_CLIENT_SECRET": oidcConfig.ClientSecret,
"CREDENTIALS_DIRECTORY_TEST": "/tmp",
"HEADSCALE_OIDC_CLIENT_SECRET_PATH": "${CREDENTIALS_DIRECTORY_TEST}/hs_client_oidc_secret",
"HEADSCALE_OIDC_STRIP_EMAIL_DOMAIN": fmt.Sprintf("%t", oidcConfig.StripEmaildomain),
}
@ -69,6 +70,7 @@ func TestOIDCAuthenticationPingAll(t *testing.T) {
hsic.WithTestName("oidcauthping"),
hsic.WithConfigEnv(oidcMap),
hsic.WithHostnameAsServerURL(),
hsic.WithFileInContainer("/tmp/hs_client_oidc_secret", []byte(oidcConfig.ClientSecret)),
)
if err != nil {
t.Errorf("failed to create headscale environment: %s", err)

View file

@ -36,6 +36,11 @@ const (
var errHeadscaleStatusCodeNotOk = errors.New("headscale status code not ok")
type fileInContainer struct {
path string
contents []byte
}
type HeadscaleInContainer struct {
hostname string
@ -44,11 +49,12 @@ type HeadscaleInContainer struct {
network *dockertest.Network
// optional config
port int
aclPolicy *headscale.ACLPolicy
env map[string]string
tlsCert []byte
tlsKey []byte
port int
aclPolicy *headscale.ACLPolicy
env map[string]string
tlsCert []byte
tlsKey []byte
filesInContainer []fileInContainer
}
type Option = func(c *HeadscaleInContainer)
@ -110,6 +116,16 @@ func WithHostnameAsServerURL() Option {
}
}
func WithFileInContainer(path string, contents []byte) Option {
return func(hsic *HeadscaleInContainer) {
hsic.filesInContainer = append(hsic.filesInContainer,
fileInContainer{
path: path,
contents: contents,
})
}
}
func New(
pool *dockertest.Pool,
network *dockertest.Network,
@ -129,7 +145,8 @@ func New(
pool: pool,
network: network,
env: DefaultConfigEnv(),
env: DefaultConfigEnv(),
filesInContainer: []fileInContainer{},
}
for _, opt := range opts {
@ -214,6 +231,12 @@ func New(
}
}
for _, f := range hsic.filesInContainer {
if err := hsic.WriteFile(f.path, f.contents); err != nil {
return nil, fmt.Errorf("failed to write %q: %w", f.path, err)
}
}
return hsic, nil
}