allow rotating encryption key in `concourse migrate`
concourse/concourse#5960
When `--old-encryption-key` is provided to `concourse migrate` (without
also specifying `--migrate-db-to-version`, the user can either decrypt
the database (by not providing `--encryption-key`) or re-encrypt the
database with a new key.
@@ -253,6 +253,7 @@ type RunCommand struct {
type Migration struct {
Postgres flag.PostgresConfig `group:"PostgreSQL Configuration" namespace:"postgres"`
EncryptionKey flag.Cipher `long:"encryption-key" description:"A 16 or 32 length key used to encrypt sensitive information before storing it in the database."`
+ OldEncryptionKey flag.Cipher `long:"old-encryption-key" description:"Encryption key previously used for encrypting sensitive information. If provided without a new key, data is decrypted. If provided with a new key, data is re-encrypted."`
CurrentDBVersion bool `long:"current-db-version" description:"Print the current database version and exit"`
SupportedDBVersion bool `long:"supported-db-version" description:"Print the max supported database version and exit"`
MigrateDBToVersion int `long:"migrate-db-to-version" description:"Migrate to the specified database version and exit"`
@@ -268,7 +269,10 @@ func (m *Migration) Execute(args []string) error {
if m.MigrateDBToVersion > 0 {
return m.migrateDBToVersion()
}
- return errors.New("must specify one of `--current-db-version`, `--supported-db-version`, or `--migrate-db-to-version`")
+ if m.OldEncryptionKey.AEAD != nil {
+ return m.rotateEncryptionKey()
+ }
+ return errors.New("must specify one of `--current-db-version`, `--supported-db-version`, `--migrate-db-to-version`, or `--old-encryption-key`")
}
@@ -338,6 +342,33 @@ func (cmd *Migration) migrateDBToVersion() error {
return nil
}
+func (cmd *Migration) rotateEncryptionKey() error {
+ var newKey *encryption.Key
+ var oldKey *encryption.Key
+
+ if cmd.EncryptionKey.AEAD != nil {
+ newKey = encryption.NewKey(cmd.EncryptionKey.AEAD)
+ }
+ if cmd.OldEncryptionKey.AEAD != nil {
+ oldKey = encryption.NewKey(cmd.OldEncryptionKey.AEAD)
+ }
+
+ helper := migration.NewOpenHelper(
+ defaultDriverName,
+ cmd.Postgres.ConnectionString(),
+ nil,
+ newKey,
+ oldKey,
+ )
+
+ version, err := helper.CurrentVersion()
+ if err != nil {
+ return err
+ }
+
+ return helper.MigrateToVersion(version)
+}
+
func (cmd *ATCCommand) WireDynamicFlags(commandFlags *flags.Command) {
cmd.RunCommand.WireDynamicFlags(commandFlags)
}
