Skip to content

Commit

Permalink
Remove nats auth 🍫 [minting] (#386)
Browse files Browse the repository at this point in the history
* Removed nats-only auth

Replaces: #380

* Found one more reference in the docs to remove
  • Loading branch information
dylanratcliffe authored Dec 2, 2024
1 parent 04c0b4e commit 019d405
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 104 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ sequenceDiagram
Login to the Overmind app, eg [local dev](https://localhost.df.overmind-demo.com:3000/settings/api-keys) and create a new overmind API key. Use the scope of 'request:receive'. To use the API key with a source add the CLI option

```shell
go run main.go start --aws-regions eu-west-2 --aws-access-strategy sso-profile --aws-profile sso-dogfood --nats-jwt=... --api-key=ovm...
go run main.go start --aws-regions eu-west-2 --aws-access-strategy sso-profile --aws-profile sso-dogfood --api-key=ovm...
```

### Static Access Token Auth
Expand All @@ -110,7 +110,7 @@ sequenceDiagram
To generate a static access token go to `https://manage.auth0.com/dashboard/eu/om-dogfood/applications` and select your application. Go to quick start and grab the curl command. You will need to add the account_name to the curl request. eg `,"account_name":"6351cbb7-cb45-481a-99cd-909d04a58512"`. This will return a JWT token that you can use to authenticate with the engine. You can now start your source.

```shell
go run main.go start --aws-regions eu-west-2 --aws-access-strategy sso-profile --aws-profile sso-dogfood --nats-jwt=... --overmind-managed-source true --source-access-token-type Bearer --source-access-token ey....
go run main.go start --aws-regions eu-west-2 --aws-access-strategy sso-profile --aws-profile sso-dogfood --overmind-managed-source true --source-access-token-type Bearer --source-access-token ey....
```

## Default Adapters
Expand Down
86 changes: 10 additions & 76 deletions cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ import (

"github.com/getsentry/sentry-go"
"github.com/google/uuid"
"github.com/nats-io/jwt/v2"
"github.com/nats-io/nkeys"
"github.com/overmindtech/sdp-go"
"github.com/overmindtech/sdp-go/auth"
"github.com/overmindtech/sdp-go/sdpconnect"
Expand Down Expand Up @@ -54,10 +52,6 @@ func AddEngineFlags(command *cobra.Command) {
command.PersistentFlags().String("api-key", "", "The API key to use to authenticate to the Overmind API")
cobra.CheckErr(viper.BindEnv("api-key", "OVM_API_KEY", "API_KEY"))

command.PersistentFlags().String("nats-jwt", "", "The JWT token that should be used to authenticate to NATS, provided in raw format e.g. eyJ0eXAiOiJKV1Q...")
cobra.CheckErr(viper.BindEnv("nats-jwt", "NATS_JWT"))
command.PersistentFlags().String("nats-nkey-seed", "", "The NKey seed which corresponds to the NATS JWT e.g. SUAFK6QUC...")
cobra.CheckErr(viper.BindEnv("nats-nkey-seed", "NATS_NKEY_SEED"))
command.PersistentFlags().String("nats-connection-name", "", "The name that the source should use to connect to NATS")
cobra.CheckErr(viper.BindEnv("nats-connection-name", "NATS_CONNECTION_NAME"))
command.PersistentFlags().Int("nats-connection-timeout", 10, "The timeout for connecting to NATS")
Expand Down Expand Up @@ -151,33 +145,23 @@ func EngineConfigFromViper(engineType, version string) (*EngineConfig, error) {
ReconnectJitter: 1 * time.Second,
}

natsOnly := false
allow, exists := os.LookupEnv("ALLOW_UNAUTHENTICATED")
unauthenticated := exists && allow == "true"
allow := os.Getenv("ALLOW_UNAUTHENTICATED")
allowUnauthenticated := allow == "true"

// order of precedence is:
// unauthenticated overrides everything # used for local development
// if managed source, we expect a token
// if local source
// we expect an api key
// or
// nats jwt and nkey seed # old way
// if local source, we expect an api key

// this is a workaround until we can remove nats only authentication. Going forward all sources must send a heartbeat
if unauthenticated {
if allowUnauthenticated {
log.Warn("Using unauthenticated mode as ALLOW_UNAUTHENTICATED is set")
natsOnly = true
} else {
if viper.GetBool("overmind-managed-source") {
log.Info("Running source in managed mode")
// If managed source, we expect a token
if viper.GetString("source-access-token") == "" {
return nil, fmt.Errorf("source-access-token must be set for managed sources")
}
} else if viper.GetString("nats-jwt") != "" && viper.GetString("nats-nkey-seed") != "" {
// If not managed source, we expect nats jwt and nkey seed
log.Warn("Using nats jwt and nkey-seed for authentication")
natsOnly = true
} else if viper.GetString("api-key") == "" {
return nil, fmt.Errorf("api-key must be set for local sources")
}
Expand All @@ -200,10 +184,7 @@ func EngineConfigFromViper(engineType, version string) (*EngineConfig, error) {
APIServerURL: apiServerURL,
ApiKey: viper.GetString("api-key"),
NATSOptions: &natsOptions,
NATSJwt: viper.GetString("nats-jwt"),
NATSNkeySeed: viper.GetString("nats-nkey-seed"),
NATSOnly: natsOnly,
Unauthenticated: unauthenticated,
Unauthenticated: allowUnauthenticated,
MaxParallelExecutions: maxParallelExecutions,
}, nil
}
Expand All @@ -218,14 +199,6 @@ func MapFromEngineConfig(ec *EngineConfig) map[string]any {
if ec.SourceAccessToken != "" {
sourceAccessToken = "[REDACTED]"
}
var natsJWT string
if ec.NATSJwt != "" {
natsJWT = "[REDACTED]"
}
var natsNKeySeed string
if ec.NATSNkeySeed != "" {
natsNKeySeed = "[REDACTED]"
}

return map[string]interface{}{
"engine-type": ec.EngineType,
Expand All @@ -243,34 +216,19 @@ func MapFromEngineConfig(ec *EngineConfig) map[string]any {
"nats-connection-name": ec.NATSOptions.ConnectionName,
"nats-connection-timeout": ec.NATSConnectionTimeout,
"nats-queue-name": ec.NATSQueueName,
"nats-jwt": natsJWT,
"nats-nkey-seed": natsNKeySeed,
"nats-only": ec.NATSOnly,
"unauthenticated": ec.Unauthenticated,
}
}

// CreateClients we need to have some checks, as it is called by the cli tool
func (ec *EngineConfig) CreateClients() error {
// NATS authenticated and unauthenticated mode
if ec.NATSOnly {
if ec.Unauthenticated {
log.Warn("Using unauthenticated NATS as ALLOW_UNAUTHENTICATED is set")
log.WithFields(MapFromEngineConfig(ec)).Info("Engine config")
return nil
}
log.Info("Using NATS authentication, no heartbeat will be sent")
tokenClient, err := createNATSTokenClient(ec.NATSJwt, ec.NATSNkeySeed)
if err != nil {
err = fmt.Errorf("error validating NATS only authentication information: %w", err)
return err
}
ec.NATSOptions.TokenClient = tokenClient
// lets print out the config
// If we are running in unauthenticated mode then do nothing here
if ec.Unauthenticated {
log.Warn("Using unauthenticated NATS as ALLOW_UNAUTHENTICATED is set")
log.WithFields(MapFromEngineConfig(ec)).Info("Engine config")
return nil
}
// this is the normal case

if ec.OvermindManagedSource == sdp.SourceManaged_LOCAL {
log.Info("Using API Key for authentication, heartbeats will be sent")
tokenClient, err := auth.NewAPIKeyClient(ec.APIServerURL, ec.ApiKey)
Expand Down Expand Up @@ -330,31 +288,7 @@ func (ec *EngineConfig) CreateClients() error {
log.WithFields(MapFromEngineConfig(ec)).Info("Engine config")
return nil
}

err := fmt.Errorf("unable to setup authentication. Please check your configuration %v", ec)
return err
}

// createNATSTokenClient Creates a basic token client that will authenticate to NATS
// using the given values
func createNATSTokenClient(natsJWT string, natsNKeySeed string) (auth.TokenClient, error) {
var kp nkeys.KeyPair
var err error

if natsJWT == "" {
return nil, errors.New("nats-jwt was blank. This is required when using authentication")
}

if natsNKeySeed == "" {
return nil, errors.New("nats-nkey-seed was blank. This is required when using authentication")
}

if _, err = jwt.DecodeUserClaims(natsJWT); err != nil {
return nil, fmt.Errorf("could not parse nats-jwt: %w", err)
}

if kp, err = nkeys.FromSeed([]byte(natsNKeySeed)); err != nil {
return nil, fmt.Errorf("could not parse nats-nkey-seed: %w", err)
}

return auth.NewBasicTokenClient(natsJWT, kp), nil
}
23 changes: 0 additions & 23 deletions cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ func TestEngineConfigFromViper(t *testing.T) {
expectedApiKey string
expectedNATSUrl string
expectedMaxParallel int
expectedNATSOnly bool
expectUnauthenticated bool
expectError bool
}{
Expand Down Expand Up @@ -155,26 +154,6 @@ func TestEngineConfigFromViper(t *testing.T) {
version: "1.0",
expectError: true,
},
{
name: "nats authenticated",
setupViper: func() {
viper.Reset()
viper.Set("nats-jwt", "nats-jwt")
viper.Set("nats-nkey-seed", "nats-nkey-seed")
viper.Set("source-name", "custom-source")
viper.Set("app", "https://app.overmind.tech")
},
engineType: "test-engine",
version: "1.0",
expectError: false,
expectedMaxParallel: runtime.NumCPU(),
expectedSourceName: "custom-source",
expectedApp: "https://app.overmind.tech",
expectedApiServerURL: "https://api.app.overmind.tech",
expectedNATSUrl: "wss://messages.app.overmind.tech",
expectedNATSOnly: true,
expectUnauthenticated: false,
},
{
name: "fully unauthenticated",
setupViper: func() {
Expand All @@ -191,7 +170,6 @@ func TestEngineConfigFromViper(t *testing.T) {
expectedApp: "https://app.overmind.tech",
expectedApiServerURL: "https://api.app.overmind.tech",
expectedNATSUrl: "wss://messages.app.overmind.tech",
expectedNATSOnly: true,
expectUnauthenticated: true,
},
}
Expand Down Expand Up @@ -220,7 +198,6 @@ func TestEngineConfigFromViper(t *testing.T) {
assert.Equal(t, tt.expectedNATSUrl, engineConfig.NATSOptions.Servers[0])
assert.Equal(t, tt.expectedApiKey, engineConfig.ApiKey)
assert.Equal(t, tt.expectedMaxParallel, engineConfig.MaxParallelExecutions)
assert.Equal(t, tt.expectedNATSOnly, engineConfig.NATSOnly)
assert.Equal(t, tt.expectUnauthenticated, engineConfig.Unauthenticated)
}
})
Expand Down
3 changes: 0 additions & 3 deletions engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,6 @@ type EngineConfig struct {
NATSOptions *auth.NATSOptions // Options for connecting to NATS
NATSConnectionTimeout int // The timeout for connecting to NATS
NATSQueueName string // The name of the queue to use when subscribing
NATSJwt string // The JWT to use for NATS
NATSNkeySeed string // The seed to use for the NATS nkey
NATSOnly bool // ONLY used for testing
Unauthenticated bool // Whether the source is unauthenticated

// The options for the heartbeat. If this is nil the engine won't send
Expand Down

0 comments on commit 019d405

Please sign in to comment.