Skip to content

Commit

Permalink
Add pub key getter to authenticator
Browse files Browse the repository at this point in the history
  • Loading branch information
4of9 committed Oct 29, 2024
1 parent 236bb67 commit eacec32
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 7 deletions.
18 changes: 13 additions & 5 deletions pkg/beholder/authenticator.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import (
)

type Authenticator struct {
headers map[string]string
headers map[string]string
publicKey []byte
}

func NewAuthenticator(config Config) (*Authenticator, error) {
Expand All @@ -23,20 +24,27 @@ func NewAuthenticator(config Config) (*Authenticator, error) {
headers = config.AuthenticatorHeaders
}

return &Authenticator{headers}, nil
pubKey := config.AuthenticatorPublicKey
return &Authenticator{headers, pubKey}, nil
}

func (a *Authenticator) GetHeaders() map[string]string {
return maps.Clone(a.headers)
}

func (a *Authenticator) GetPubKey() []byte {
return a.publicKey
}

func validateAuthConfig(c Config) error {
if c.AuthenticatorSigner != nil && len(c.AuthenticatorHeaders) > 0 {
return errors.New("cannot configure both authenticator signer and authenticator header value")
}

if c.AuthenticatorSigner != nil && len(c.AuthenticatorPublicKey) == 0 {
return errors.New("authenticator public key must be configured when authenticator signer is configured")
if c.AuthenticatorSigner != nil || len(c.AuthenticatorHeaders) > 0 {
if len(c.AuthenticatorPublicKey) == 0 {
return errors.New("authenticator public key must be set when signer or headers are configured")
}
}

return nil
Expand All @@ -51,7 +59,7 @@ var authHeaderVersion = "1"
// deriveAuthHeaders creates the auth header value to be included on requests.
// The current format for the header is:
//
// <version>:<public_key_hex>:<signature_hex>
// <version>:<authenticator_public_key_hex>:<signature_hex>
//
// where the byte value of <public_key_hex> is what's being signed
func deriveAuthHeaders(config Config) map[string]string {
Expand Down
18 changes: 16 additions & 2 deletions pkg/beholder/authenticator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,21 @@ func TestAuthenticator_SignerAuth(t *testing.T) {
"X-Beholder-Node-Auth-Token": "1:746573742d7075626c69632d6b6579:746573742d7369676e6174757265",
}
assert.Equal(t, expectedHeaders, a.GetHeaders())
assert.Equal(t, c.AuthenticatorPublicKey, a.GetPubKey())
}

func TestAuthenticator_HeadersAuth(t *testing.T) {
// Authenticator should use the headers if they are set
expectedHeaders := map[string]string{"test-header-key": "test-header-value"}
c := beholder.Config{
AuthenticatorHeaders: expectedHeaders,
AuthenticatorHeaders: expectedHeaders,
AuthenticatorPublicKey: []byte("test-public-key"),
}

a, err := beholder.NewAuthenticator(c)
assert.NoError(t, err)
assert.Equal(t, expectedHeaders, a.GetHeaders())
assert.Equal(t, c.AuthenticatorPublicKey, a.GetPubKey())
}

func TestAuthenticator_NoAuth(t *testing.T) {
Expand All @@ -47,6 +50,7 @@ func TestAuthenticator_NoAuth(t *testing.T) {
assert.NoError(t, err)
expectedHeaders := map[string]string{}
assert.Equal(t, expectedHeaders, a.GetHeaders())
assert.Equal(t, []byte(nil), a.GetPubKey())
}

func TestAuthenticator_Config(t *testing.T) {
Expand All @@ -62,9 +66,19 @@ func TestAuthenticator_Config(t *testing.T) {
_, err = beholder.NewAuthenticator(c)
assert.Error(t, err)

// Configuring neither auth signer nor auth header should not error
// Configuring headers with no public key should error
c = defaultTestingConfig()
c.AuthenticatorSigner = nil
c.AuthenticatorHeaders = map[string]string{"test-header-key": "test-header-value"}
c.AuthenticatorPublicKey = nil
_, err = beholder.NewAuthenticator(c)
assert.Error(t, err)

// Configuring neither auth signer, nor auth heade, nor pub key should not error
c = defaultTestingConfig()
c.AuthenticatorSigner = nil
c.AuthenticatorPublicKey = nil
c.AuthenticatorHeaders = nil
_, err = beholder.NewAuthenticator(c)
assert.NoError(t, err)
}
4 changes: 4 additions & 0 deletions pkg/loop/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const (
envTelemetryAttribute = "CL_TELEMETRY_ATTRIBUTE_"
envTelemetryTraceSampleRatio = "CL_TELEMETRY_TRACE_SAMPLE_RATIO"
envTelemetryAuthHeader = "CL_TELEMETRY_AUTH_HEADER"
envTelemetryAuthPubKeyHex = "CL_TELEMETRY_AUTH_PUB_KEY_HEX"
)

// EnvConfig is the configuration between the application and the LOOP executable. The values
Expand All @@ -49,6 +50,7 @@ type EnvConfig struct {
TelemetryAttributes OtelAttributes
TelemetryTraceSampleRatio float64
TelemetryAuthHeaders map[string]string
TelemetryAuthPubKeyHex string
}

// AsCmdEnv returns a slice of environment variable key/value pairs for an exec.Cmd.
Expand Down Expand Up @@ -83,6 +85,7 @@ func (e *EnvConfig) AsCmdEnv() (env []string) {
for k, v := range e.TelemetryAuthHeaders {
add(envTelemetryAuthHeader+k, v)
}
add(envTelemetryAuthPubKeyHex, e.TelemetryAuthPubKeyHex)

return
}
Expand Down Expand Up @@ -131,6 +134,7 @@ func (e *EnvConfig) parse() error {
e.TelemetryAttributes = getMap(envTelemetryAttribute)
e.TelemetryTraceSampleRatio = getFloat64OrZero(envTelemetryTraceSampleRatio)
e.TelemetryAuthHeaders = getMap(envTelemetryAuthHeader)
e.TelemetryAuthPubKeyHex = os.Getenv(envTelemetryAuthPubKeyHex)
}
return nil
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/loop/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ func TestEnvConfig_AsCmdEnv(t *testing.T) {
TelemetryAttributes: OtelAttributes{"foo": "bar", "baz": "42"},
TelemetryTraceSampleRatio: 0.42,
TelemetryAuthHeaders: map[string]string{"header-key": "header-value"},
TelemetryAuthPubKeyHex: "pub-key-hex",
}
got := map[string]string{}
for _, kv := range envCfg.AsCmdEnv() {
Expand All @@ -153,6 +154,7 @@ func TestEnvConfig_AsCmdEnv(t *testing.T) {
assert.Equal(t, "bar", got[envTelemetryAttribute+"foo"])
assert.Equal(t, "42", got[envTelemetryAttribute+"baz"])
assert.Equal(t, "header-value", got[envTelemetryAuthHeader+"header-key"])
assert.Equal(t, "pub-key-hex", got[envTelemetryAuthPubKeyHex])
}

func TestManagedGRPCClientConfig(t *testing.T) {
Expand Down
7 changes: 7 additions & 0 deletions pkg/loop/server.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package loop

import (
"encoding/hex"
"fmt"
"os"

Expand Down Expand Up @@ -90,13 +91,19 @@ func (s *Server) start() error {
if tracingConfig.Enabled {
attributes = tracingConfig.Attributes()
}

authPubKey, err := hex.DecodeString(envCfg.TelemetryAuthPubKeyHex)
if err != nil {
return fmt.Errorf("failed to decode telemetry auth public key hex: %w", err)
}
beholderCfg := beholder.Config{
InsecureConnection: envCfg.TelemetryInsecureConnection,
CACertFile: envCfg.TelemetryCACertFile,
OtelExporterGRPCEndpoint: envCfg.TelemetryEndpoint,
ResourceAttributes: append(attributes, envCfg.TelemetryAttributes.AsStringAttributes()...),
TraceSampleRatio: envCfg.TelemetryTraceSampleRatio,
AuthenticatorHeaders: envCfg.TelemetryAuthHeaders,
AuthenticatorPublicKey: authPubKey,
}

if tracingConfig.Enabled {
Expand Down

0 comments on commit eacec32

Please sign in to comment.