Skip to content

Commit

Permalink
Switch to using the secondary key (#3427)
Browse files Browse the repository at this point in the history
* Switch to using the secondary key

* Documentation update

* Log the name of the key used

* Pass log arg through

* Fix import ordering

* Shorten line
  • Loading branch information
mociarain authored Mar 21, 2024
1 parent c9b7d81 commit 07672dd
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 11 deletions.
3 changes: 2 additions & 1 deletion cmd/aro/dbtoken.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ func dbtoken(ctx context.Context, log *logrus.Entry) error {
clientOptions := &policy.ClientOptions{
ClientOptions: _env.Environment().ManagedIdentityCredentialOptions().ClientOptions,
}
dbAuthorizer, err := database.NewMasterKeyAuthorizer(ctx, msiToken, clientOptions, _env.SubscriptionID(), _env.ResourceGroup(), dbAccountName)
logrusEntry := log.WithField("component", "database")
dbAuthorizer, err := database.NewMasterKeyAuthorizer(ctx, logrusEntry, msiToken, clientOptions, _env.SubscriptionID(), _env.ResourceGroup(), dbAccountName)
if err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion cmd/aro/monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ func monitor(ctx context.Context, log *logrus.Entry) error {
clientOptions := &policy.ClientOptions{
ClientOptions: _env.Environment().ManagedIdentityCredentialOptions().ClientOptions,
}
dbAuthorizer, err := database.NewMasterKeyAuthorizer(ctx, msiToken, clientOptions, _env.SubscriptionID(), _env.ResourceGroup(), dbAccountName)
logrusEntry := log.WithField("component", "database")
dbAuthorizer, err := database.NewMasterKeyAuthorizer(ctx, logrusEntry, msiToken, clientOptions, _env.SubscriptionID(), _env.ResourceGroup(), dbAccountName)
if err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion cmd/aro/portal.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ func portal(ctx context.Context, log *logrus.Entry, audit *logrus.Entry) error {
clientOptions := &policy.ClientOptions{
ClientOptions: _env.Environment().ManagedIdentityCredentialOptions().ClientOptions,
}
dbAuthorizer, err := database.NewMasterKeyAuthorizer(ctx, msiToken, clientOptions, _env.SubscriptionID(), _env.ResourceGroup(), dbAccountName)
logrusEntry := log.WithField("component", "database")
dbAuthorizer, err := database.NewMasterKeyAuthorizer(ctx, logrusEntry, msiToken, clientOptions, _env.SubscriptionID(), _env.ResourceGroup(), dbAccountName)
if err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion cmd/aro/rp.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ func rp(ctx context.Context, log, audit *logrus.Entry) error {
clientOptions := &policy.ClientOptions{
ClientOptions: _env.Environment().ManagedIdentityCredentialOptions().ClientOptions,
}
dbAuthorizer, err := database.NewMasterKeyAuthorizer(ctx, msiToken, clientOptions, _env.SubscriptionID(), _env.ResourceGroup(), dbAccountName)
logrusEntry := log.WithField("component", "database")
dbAuthorizer, err := database.NewMasterKeyAuthorizer(ctx, logrusEntry, msiToken, clientOptions, _env.SubscriptionID(), _env.ResourceGroup(), dbAccountName)
if err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion cmd/aro/update_ocp_versions.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ func getVersionsDatabase(ctx context.Context, log *logrus.Entry) (database.OpenS
clientOptions := &policy.ClientOptions{
ClientOptions: _env.Environment().ManagedIdentityCredentialOptions().ClientOptions,
}
dbAuthorizer, err := database.NewMasterKeyAuthorizer(ctx, msiToken, clientOptions, _env.SubscriptionID(), _env.ResourceGroup(), dbAccountName)
logrusEntry := log.WithField("component", "database")
dbAuthorizer, err := database.NewMasterKeyAuthorizer(ctx, logrusEntry, msiToken, clientOptions, _env.SubscriptionID(), _env.ResourceGroup(), dbAccountName)
if err != nil {
return nil, err
}
Expand Down
7 changes: 4 additions & 3 deletions docs/dbtoken-service.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ In brief, there are three options:

1. use r/w or r/o primary keys, which grant access to the whole database account
2. implement a service which transforms (1) into scoped resource tokens
3. a third AAD RBAC-based model is in preview.
3. a third AAD RBAC-based model with Entra Ids.

Currently, the RP, monitoring and portal service share the same security
boundary (the RP VM) and use option 1. The dbtoken service, which also runs on
the RP VM, is our implementation of option 2. As and when option 3 goes GA, it
may be possible to retire the dbtoken service.
the RP VM, is our implementation of option 2. Option 3 is now in GA and there are plans
[here](https://issues.redhat.com/browse/ARO-5512) to implement it and replace option 1
and 2.

The purpose of the dbtoken service at its implementation time is to enable the
gateway component (which handles end-user traffic) to access the service Cosmos
Expand Down
3 changes: 2 additions & 1 deletion hack/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ func run(ctx context.Context, log *logrus.Entry) error {
clientOptions := &policy.ClientOptions{
ClientOptions: _env.Environment().ManagedIdentityCredentialOptions().ClientOptions,
}
dbAuthorizer, err := database.NewMasterKeyAuthorizer(ctx, tokenCredential, clientOptions, _env.SubscriptionID(), _env.ResourceGroup(), dbAccountName)
logrusEntry := log.WithField("component", "database")
dbAuthorizer, err := database.NewMasterKeyAuthorizer(ctx, logrusEntry, tokenCredential, clientOptions, _env.SubscriptionID(), _env.ResourceGroup(), dbAccountName)
if err != nil {
return err
}
Expand Down
10 changes: 8 additions & 2 deletions pkg/database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func NewDatabaseClient(log *logrus.Entry, _env env.Core, authorizer cosmosdb.Aut
return cosmosdb.NewDatabaseClient(log, c, h, databaseAccountName+"."+_env.Environment().CosmosDBDNSSuffix, authorizer), nil
}

func NewMasterKeyAuthorizer(ctx context.Context, token azcore.TokenCredential, clientOptions *policy.ClientOptions, subscriptionID, resourceGroup, databaseAccountName string) (cosmosdb.Authorizer, error) {
func NewMasterKeyAuthorizer(ctx context.Context, log *logrus.Entry, token azcore.TokenCredential, clientOptions *policy.ClientOptions, subscriptionID, resourceGroup, databaseAccountName string) (cosmosdb.Authorizer, error) {
databaseaccounts, err := armcosmos.NewDatabaseAccountsClient(subscriptionID, token, clientOptions)
if err != nil {
return nil, err
Expand All @@ -68,7 +68,13 @@ func NewMasterKeyAuthorizer(ctx context.Context, token azcore.TokenCredential, c
return nil, err
}

return cosmosdb.NewMasterKeyAuthorizer(*keys.PrimaryMasterKey)
return cosmosdb.NewMasterKeyAuthorizer(getDatabaseKey(keys, log))
}

func getDatabaseKey(keys sdkcosmos.DatabaseAccountsClientListKeysResponse, log *logrus.Entry) string {
keyName := "SecondaryMasterKey"
log.Infof("Using %s to authenticate with CosmosDB", keyName)
return *keys.SecondaryMasterKey
}

func NewJSONHandle(aead encryption.AEAD) (*codec.JsonHandle, error) {
Expand Down
63 changes: 63 additions & 0 deletions pkg/database/database_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package database

// Copyright (c) Microsoft Corporation.
// Licensed under the Apache License 2.0.

import (
"testing"

sdkcosmos "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/cosmos/armcosmos/v2"
"github.com/onsi/gomega"
"github.com/onsi/gomega/types"
"github.com/sirupsen/logrus"

testlog "github.com/Azure/ARO-RP/test/util/log"
)

func TestGetDatabaseKey(t *testing.T) {
primaryMasterKeyName := "PrimaryMasterKey"
primaryReadOnlyMasterKeyName := "PrimaryReadonlyMasterKey"
secondaryMasterKeyName := "SecondaryMasterKey"
secondaryReadOnlyMasterKeyName := "SecondaryReadonlyMasterKey"
for _, tt := range []struct {
name string
wantData string
wantEntries []map[string]types.GomegaMatcher
}{
{
name: "Use correct CosmosDB Key",
wantData: secondaryMasterKeyName,
wantEntries: []map[string]types.GomegaMatcher{
{
"level": gomega.Equal(logrus.InfoLevel),
"msg": gomega.ContainSubstring(secondaryMasterKeyName),
},
},
},
} {
t.Run(tt.name, func(t *testing.T) {
h, log := testlog.New()

keys := sdkcosmos.DatabaseAccountsClientListKeysResponse{
DatabaseAccountListKeysResult: sdkcosmos.DatabaseAccountListKeysResult{
PrimaryMasterKey: &primaryMasterKeyName,
PrimaryReadonlyMasterKey: &primaryReadOnlyMasterKeyName,
SecondaryMasterKey: &secondaryMasterKeyName,
SecondaryReadonlyMasterKey: &secondaryReadOnlyMasterKeyName,
},
}

result := getDatabaseKey(keys, log)
t.Log(result)

if result != tt.wantData {
t.Errorf("Expected %s, got %s", tt.wantData, result)
}

err := testlog.AssertLoggingOutput(h, tt.wantEntries)
if err != nil {
t.Error(err)
}
})
}
}

0 comments on commit 07672dd

Please sign in to comment.