Skip to content

Commit e14272c

Browse files
committed
fixup! support secondary cipher in dbcrypt
1 parent d4c74bf commit e14272c

File tree

4 files changed

+35
-35
lines changed

4 files changed

+35
-35
lines changed

cli/testdata/coder_server_--help.golden

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -458,15 +458,13 @@ These options are only available in the Enterprise Edition.
458458
An HTTP URL that is accessible by other replicas to relay DERP
459459
traffic. Required for high availability.
460460

461-
--external-token-encryption-key string, $CODER_EXTERNAL_TOKEN_ENCRYPTION_KEY
461+
--external-token-encryption-keys string-array, $CODER_EXTERNAL_TOKEN_ENCRYPTION_KEYS
462462
Encrypt OIDC and Git authentication tokens with AES-256-GCM in the
463-
database. The value must be a base64-encoded key exactly 32 bytes in
464-
length.
465-
466-
--previous-external-token-encryption-key string, $CODER_PREVIOUS_EXTERNAL_TOKEN_ENCRYPTION_KEY
467-
When rotating external token encryption key, provide the previous
468-
encryption key. The value must be a base64-encoded key exactly 32
469-
bytes in length.
463+
database. The value must be a comma-separated list of base64-encoded
464+
keys. A maximum of two keys may be provided. Each key, when
465+
base64-decoded, must be exactly 32 bytes in length. The first key will
466+
be used to encrypt new values. Subsequent keys will be used as a
467+
fallback when decrypting.
470468

471469
--scim-auth-header string, $CODER_SCIM_AUTH_HEADER
472470
Enables SCIM and sets the authentication header for the built-in SCIM

enterprise/cli/testdata/coder_server_--help.golden

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -458,15 +458,13 @@ These options are only available in the Enterprise Edition.
458458
An HTTP URL that is accessible by other replicas to relay DERP
459459
traffic. Required for high availability.
460460

461-
--external-token-encryption-key string, $CODER_EXTERNAL_TOKEN_ENCRYPTION_KEY
461+
--external-token-encryption-keys string-array, $CODER_EXTERNAL_TOKEN_ENCRYPTION_KEYS
462462
Encrypt OIDC and Git authentication tokens with AES-256-GCM in the
463-
database. The value must be a base64-encoded key exactly 32 bytes in
464-
length.
465-
466-
--previous-external-token-encryption-key string, $CODER_PREVIOUS_EXTERNAL_TOKEN_ENCRYPTION_KEY
467-
When rotating external token encryption key, provide the previous
468-
encryption key. The value must be a base64-encoded key exactly 32
469-
bytes in length.
463+
database. The value must be a comma-separated list of base64-encoded
464+
keys. A maximum of two keys may be provided. Each key, when
465+
base64-decoded, must be exactly 32 bytes in length. The first key will
466+
be used to encrypt new values. Subsequent keys will be used as a
467+
fallback when decrypting.
470468

471469
--scim-auth-header string, $CODER_SCIM_AUTH_HEADER
472470
Enables SCIM and sets the authentication header for the built-in SCIM

enterprise/coderd/coderd.go

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -64,21 +64,28 @@ func New(ctx context.Context, options *Options) (_ *API, err error) {
6464

6565
ctx, cancelFunc := context.WithCancel(ctx)
6666

67-
externalTokenCipher := &atomic.Pointer[dbcrypt.Cipher]{}
68-
cryptDB, err := dbcrypt.New(ctx, options.Database, &dbcrypt.Options{
69-
PrimaryCipher: externalTokenCipher,
70-
})
71-
if err != nil {
72-
cancelFunc()
73-
return nil, xerrors.Errorf("init dbcrypt: %w", err)
67+
if options.PrimaryExternalTokenEncryption != nil {
68+
primaryExternalTokenCipher := atomic.Pointer[dbcrypt.Cipher]{}
69+
primaryExternalTokenCipher.Store(&options.PrimaryExternalTokenEncryption)
70+
secondaryExternalTokenCipher := atomic.Pointer[dbcrypt.Cipher]{}
71+
if options.SecondaryExternalTokenEncryption != nil {
72+
secondaryExternalTokenCipher.Store(&options.SecondaryExternalTokenEncryption)
73+
}
74+
cryptDB, err := dbcrypt.New(ctx, options.Database, &dbcrypt.Options{
75+
PrimaryCipher: &primaryExternalTokenCipher,
76+
SecondaryCipher: &secondaryExternalTokenCipher,
77+
})
78+
79+
if err != nil {
80+
cancelFunc()
81+
return nil, xerrors.Errorf("init dbcrypt: %w", err)
82+
}
83+
options.Database = cryptDB
7484
}
75-
options.Database = cryptDB
7685

7786
api := &API{
78-
ctx: ctx,
79-
cancel: cancelFunc,
80-
externalTokenCipher: externalTokenCipher,
81-
87+
ctx: ctx,
88+
cancel: cancelFunc,
8289
AGPL: coderd.New(options.Options),
8390
Options: options,
8491
provisionerDaemonAuth: &provisionerDaemonAuth{
@@ -407,8 +414,6 @@ type API struct {
407414
ctx context.Context
408415
cancel context.CancelFunc
409416

410-
externalTokenCipher *atomic.Pointer[dbcrypt.Cipher]
411-
412417
// Detects multiple Coder replicas running at the same time.
413418
replicaManager *replicasync.Manager
414419
// Meshes DERP connections from multiple replicas.

enterprise/dbcrypt/dbcrypt_test.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -217,12 +217,11 @@ func TestNew(t *testing.T) {
217217
})
218218

219219
// Then: an error is returned
220-
require.ErrorContains(t, err, "at least one cipher must be provided")
220+
require.ErrorContains(t, err, "at least one cipher is required")
221221

222-
// And: the sentinel value is not encrypted
223-
rawVal, err := rawDB.GetDBCryptSentinelValue(ctx)
224-
require.NoError(t, err)
225-
require.Equal(t, "coder", rawVal)
222+
// And: the sentinel value is not present
223+
_, err = rawDB.GetDBCryptSentinelValue(ctx)
224+
require.ErrorIs(t, err, sql.ErrNoRows)
226225
})
227226

228227
t.Run("CipherChanged", func(t *testing.T) {

0 commit comments

Comments
 (0)