admin api: Fix reencryption of private_key in signing_key table, introduce test for reencryption (#105010)
* Add integration test for reencrypting secrets. Rotate keys before reencryption. Test for setting table from enterprise repo.
This commit is contained in:
@@ -14,7 +14,9 @@ import (
|
||||
)
|
||||
|
||||
type SecretsRotator interface {
|
||||
// ReEncrypt returns true on success, false on any failure.
|
||||
ReEncrypt(context.Context, *manager.SecretsService, db.DB) bool
|
||||
// Rollback returns true on success, false on any failure.
|
||||
Rollback(context.Context, *manager.SecretsService, encryption.Internal, db.DB, string) bool
|
||||
}
|
||||
|
||||
@@ -43,7 +45,7 @@ func ProvideSecretsMigrator(
|
||||
b64Secret{simpleSecret: simpleSecret{tableName: "secrets", columnName: "value"}, hasUpdatedColumn: true, encoding: base64.RawStdEncoding},
|
||||
jsonSecret{tableName: "data_source"},
|
||||
jsonSecret{tableName: "plugin_setting"},
|
||||
b64Secret{simpleSecret: simpleSecret{tableName: "signing_key", columnName: "private_key"}, encoding: base64.StdEncoding},
|
||||
b64Secret{simpleSecret: simpleSecret{tableName: "signing_key", columnName: "private_key"}, encoding: base64.RawStdEncoding},
|
||||
alertingSecret{},
|
||||
ssoSettingsSecret{},
|
||||
b64Secret{simpleSecret: simpleSecret{tableName: "user_external_session", columnName: "access_token"}, encoding: base64.StdEncoding},
|
||||
@@ -94,12 +96,12 @@ func (m *SecretsMigrator) RollBackSecrets(ctx context.Context) (bool, error) {
|
||||
var anyFailure bool
|
||||
|
||||
for _, r := range m.rotators {
|
||||
if failed := r.Rollback(ctx,
|
||||
if success := r.Rollback(ctx,
|
||||
m.secretsSrv,
|
||||
m.encryptionSrv,
|
||||
m.sqlStore,
|
||||
m.settings.KeyValue("security", "secret_key").Value(),
|
||||
); failed {
|
||||
); !success {
|
||||
anyFailure = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ func (p provisioningSecrets) reEncrypt(
|
||||
} else {
|
||||
logger.Info("Successfully rotated provisioning secrets", "action", action)
|
||||
}
|
||||
return failures > 0
|
||||
return failures == 0
|
||||
}
|
||||
|
||||
func (provisioningSecrets) reEncryptGitHubToken(
|
||||
|
||||
@@ -25,7 +25,7 @@ func (s simpleSecret) ReEncrypt(ctx context.Context, secretsSrv *manager.Secrets
|
||||
if err := sqlStore.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
return sess.Table(s.tableName).Select(fmt.Sprintf("id, %s as secret", s.columnName)).Find(&rows)
|
||||
}); err != nil {
|
||||
logger.Warn("Could not find any secret to re-encrypt", "table", s.tableName)
|
||||
logger.Warn("Could not find any secret to re-encrypt", "table", s.tableName, "error", err)
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ func (s b64Secret) ReEncrypt(ctx context.Context, secretsSrv *manager.SecretsSer
|
||||
if err := sqlStore.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
return sess.Table(s.tableName).Select(fmt.Sprintf("id, %s as secret", s.columnName)).Find(&rows)
|
||||
}); err != nil {
|
||||
logger.Warn("Could not find any secret to re-encrypt", "table", s.tableName)
|
||||
logger.Warn("Could not find any secret to re-encrypt", "table", s.tableName, "error", err)
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ func (s jsonSecret) ReEncrypt(ctx context.Context, secretsSrv *manager.SecretsSe
|
||||
if err := sqlStore.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
return sess.Table(s.tableName).Cols("id", "secure_json_data").Find(&rows)
|
||||
}); err != nil {
|
||||
logger.Warn("Could not find any secret to re-encrypt", "table", s.tableName)
|
||||
logger.Warn("Could not find any secret to re-encrypt", "table", s.tableName, "error", err)
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ func (s alertingSecret) ReEncrypt(ctx context.Context, secretsSrv *manager.Secre
|
||||
if err := sqlStore.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
return sess.SQL(selectSQL).Find(&results)
|
||||
}); err != nil {
|
||||
logger.Warn("Could not find any alert_configuration secret to re-encrypt")
|
||||
logger.Warn("Could not find any alert_configuration secret to re-encrypt", "error", err)
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -299,9 +299,8 @@ func (s ssoSettingsSecret) ReEncrypt(ctx context.Context, secretsSrv *manager.Se
|
||||
err := sqlStore.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
return sess.Find(&results)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
logger.Warn("Failed to fetch SSO settings to re-encrypt", "err", err)
|
||||
logger.Warn("Failed to fetch SSO settings to re-encrypt", "error", err)
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ func (s simpleSecret) Rollback(
|
||||
encryptionSrv encryption.Internal,
|
||||
sqlStore db.DB,
|
||||
secretKey string,
|
||||
) (anyFailure bool) {
|
||||
) bool {
|
||||
var rows []struct {
|
||||
Id int
|
||||
Secret []byte
|
||||
@@ -28,10 +28,11 @@ func (s simpleSecret) Rollback(
|
||||
if err := sqlStore.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
return sess.Table(s.tableName).Select(fmt.Sprintf("id, %s as secret", s.columnName)).Find(&rows)
|
||||
}); err != nil {
|
||||
logger.Warn("Could not find any secret to roll back", "table", s.tableName)
|
||||
return true
|
||||
logger.Warn("Could not find any secret to roll back", "table", s.tableName, "error", err)
|
||||
return false
|
||||
}
|
||||
|
||||
anyFailure := false
|
||||
for _, row := range rows {
|
||||
if len(row.Secret) == 0 {
|
||||
continue
|
||||
@@ -70,7 +71,7 @@ func (s simpleSecret) Rollback(
|
||||
logger.Info(fmt.Sprintf("Column %s from %s has been rolled back successfully", s.columnName, s.tableName))
|
||||
}
|
||||
|
||||
return anyFailure
|
||||
return !anyFailure
|
||||
}
|
||||
|
||||
func (s b64Secret) Rollback(
|
||||
@@ -79,7 +80,7 @@ func (s b64Secret) Rollback(
|
||||
encryptionSrv encryption.Internal,
|
||||
sqlStore db.DB,
|
||||
secretKey string,
|
||||
) (anyFailure bool) {
|
||||
) bool {
|
||||
var rows []struct {
|
||||
Id int
|
||||
Secret string
|
||||
@@ -89,9 +90,10 @@ func (s b64Secret) Rollback(
|
||||
return sess.Table(s.tableName).Select(fmt.Sprintf("id, %s as secret", s.columnName)).Find(&rows)
|
||||
}); err != nil {
|
||||
logger.Warn("Could not find any secret to roll back", "table", s.tableName)
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
anyFailure := false
|
||||
for _, row := range rows {
|
||||
if len(row.Secret) == 0 {
|
||||
continue
|
||||
@@ -144,7 +146,7 @@ func (s b64Secret) Rollback(
|
||||
logger.Info(fmt.Sprintf("Column %s from %s has been rolled back successfully", s.columnName, s.tableName))
|
||||
}
|
||||
|
||||
return anyFailure
|
||||
return !anyFailure
|
||||
}
|
||||
|
||||
func (s jsonSecret) Rollback(
|
||||
@@ -153,7 +155,7 @@ func (s jsonSecret) Rollback(
|
||||
encryptionSrv encryption.Internal,
|
||||
sqlStore db.DB,
|
||||
secretKey string,
|
||||
) (anyFailure bool) {
|
||||
) bool {
|
||||
var rows []struct {
|
||||
Id int
|
||||
SecureJsonData map[string][]byte
|
||||
@@ -162,10 +164,11 @@ func (s jsonSecret) Rollback(
|
||||
if err := sqlStore.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
return sess.Table(s.tableName).Cols("id", "secure_json_data").Find(&rows)
|
||||
}); err != nil {
|
||||
logger.Warn("Could not find any secret to roll back", "table", s.tableName)
|
||||
return true
|
||||
logger.Warn("Could not find any secret to roll back", "table", s.tableName, "error", err)
|
||||
return false
|
||||
}
|
||||
|
||||
anyFailure := false
|
||||
for _, row := range rows {
|
||||
if len(row.SecureJsonData) == 0 {
|
||||
continue
|
||||
@@ -208,7 +211,7 @@ func (s jsonSecret) Rollback(
|
||||
logger.Info(fmt.Sprintf("Secure json data secrets from %s have been rolled back successfully", s.tableName))
|
||||
}
|
||||
|
||||
return anyFailure
|
||||
return !anyFailure
|
||||
}
|
||||
|
||||
func (s alertingSecret) Rollback(
|
||||
@@ -217,7 +220,7 @@ func (s alertingSecret) Rollback(
|
||||
encryptionSrv encryption.Internal,
|
||||
sqlStore db.DB,
|
||||
secretKey string,
|
||||
) (anyFailure bool) {
|
||||
) bool {
|
||||
var results []struct {
|
||||
Id int
|
||||
AlertmanagerConfiguration string
|
||||
@@ -227,17 +230,16 @@ func (s alertingSecret) Rollback(
|
||||
if err := sqlStore.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
return sess.SQL(selectSQL).Find(&results)
|
||||
}); err != nil {
|
||||
logger.Warn("Could not find any alert_configuration secret to roll back")
|
||||
return true
|
||||
logger.Warn("Could not find any alert_configuration secret to roll back", "error", err)
|
||||
return false
|
||||
}
|
||||
|
||||
anyFailure := false
|
||||
for _, result := range results {
|
||||
result := result
|
||||
|
||||
err := sqlStore.WithTransactionalDbSession(ctx, func(sess *db.Session) error {
|
||||
postableUserConfig, err := notifier.Load([]byte(result.AlertmanagerConfiguration))
|
||||
if err != nil {
|
||||
logger.Warn("Could not load configuration (alert_configuration with id: %d) while rolling it back", result.Id, err)
|
||||
logger.Warn("Could not load configuration while rolling it back", "id", result.Id, "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -246,19 +248,19 @@ func (s alertingSecret) Rollback(
|
||||
for k, v := range gmr.SecureSettings {
|
||||
decoded, err := base64.StdEncoding.DecodeString(v)
|
||||
if err != nil {
|
||||
logger.Warn("Could not decode base64-encoded secret (alert_configuration with id: %d, key)", k, result.Id, err)
|
||||
logger.Warn("Could not decode base64-encoded secret", "id", result.Id, "key", k, "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
decrypted, err := secretsSrv.Decrypt(ctx, decoded)
|
||||
if err != nil {
|
||||
logger.Warn("Could not decrypt secret (alert_configuration with id: %d, key)", k, result.Id, err)
|
||||
logger.Warn("Could not decrypt secret", "id", result.Id, "key", k, "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
reencrypted, err := encryptionSrv.Encrypt(ctx, decrypted, secretKey)
|
||||
if err != nil {
|
||||
logger.Warn("Could not re-encrypt secret (alert_configuration with id: %d, key)", k, result.Id, err)
|
||||
logger.Warn("Could not re-encrypt secret", "id", result.Id, "key", k, "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -269,13 +271,13 @@ func (s alertingSecret) Rollback(
|
||||
|
||||
marshalled, err := json.Marshal(postableUserConfig)
|
||||
if err != nil {
|
||||
logger.Warn("Could not marshal configuration (alert_configuration with id: %d) while rolling it back", result.Id, err)
|
||||
logger.Warn("Could not marshal configuration while rolling it back", "id", result.Id, "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
result.AlertmanagerConfiguration = string(marshalled)
|
||||
if _, err := sess.Table("alert_configuration").Where("id = ?", result.Id).Update(&result); err != nil {
|
||||
logger.Warn("Could not update secret (alert_configuration with id: %d) while rolling it back", result.Id, err)
|
||||
logger.Warn("Could not update secret while rolling it back", "id", result.Id, "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -293,7 +295,7 @@ func (s alertingSecret) Rollback(
|
||||
logger.Info("Alerting configuration secrets have been rolled back successfully")
|
||||
}
|
||||
|
||||
return anyFailure
|
||||
return !anyFailure
|
||||
}
|
||||
|
||||
func (s ssoSettingsSecret) Rollback(
|
||||
@@ -302,18 +304,18 @@ func (s ssoSettingsSecret) Rollback(
|
||||
encryptionSrv encryption.Internal,
|
||||
sqlStore db.DB,
|
||||
secretKey string,
|
||||
) (anyFailure bool) {
|
||||
) bool {
|
||||
results := make([]*models.SSOSettings, 0)
|
||||
|
||||
err := sqlStore.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
return sess.Find(&results)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
logger.Warn("Failed to fetch SSO settings to roll back")
|
||||
return true
|
||||
logger.Warn("Failed to fetch SSO settings to roll back", "error", err)
|
||||
return false
|
||||
}
|
||||
|
||||
anyFailure := false
|
||||
for _, result := range results {
|
||||
err := sqlStore.WithTransactionalDbSession(ctx, func(sess *db.Session) error {
|
||||
result.Settings, err = s.reEncryptSecretsInMap(ctx, result.Settings, secretsSrv, encryptionSrv, secretKey)
|
||||
@@ -345,5 +347,5 @@ func (s ssoSettingsSecret) Rollback(
|
||||
logger.Info("SSO settings secrets have been rolled back successfully")
|
||||
}
|
||||
|
||||
return anyFailure
|
||||
return !anyFailure
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user