@ -146,11 +146,13 @@ func (s *SecretsService) EncryptWithDBSession(ctx context.Context, payload []byt
// If encryption featuremgmt.FlagEnvelopeEncryption toggle is on, use envelope encryption
scope := opt ( )
name := secrets . KeyName ( scope , s . currentProviderID )
label := secrets . KeyLabel ( scope , s . currentProviderID )
id , dataKey , err := s . currentDataKey ( ctx , name , scope , sess )
var id string
var dataKey [ ] byte
id , dataKey , err = s . currentDataKey ( ctx , label , scope , sess )
if err != nil {
s . log . Error ( "Failed to get current data key" , "error" , err , "name" , name )
s . log . Error ( "Failed to get current data key" , "error" , err , "label" , label )
return nil , err
}
@ -176,21 +178,21 @@ func (s *SecretsService) EncryptWithDBSession(ctx context.Context, payload []byt
// currentDataKey looks up for current data key in cache or database by name, and decrypts it.
// If there's no current data key in cache nor in database it generates a new random data key,
// and stores it into both the in-memory cache and database (encrypted by the encryption provider).
func ( s * SecretsService ) currentDataKey ( ctx context . Context , name string , scope string , sess * xorm . Session ) ( string , [ ] byte , error ) {
func ( s * SecretsService ) currentDataKey ( ctx context . Context , label string , scope string , sess * xorm . Session ) ( string , [ ] byte , error ) {
// We want only one request fetching current data key at time to
// avoid the creation of multiple ones in case there's no one existing.
s . mtx . Lock ( )
defer s . mtx . Unlock ( )
// We try to fetch the data key, either from cache or database
id , dataKey , err := s . dataKeyByName ( ctx , name )
id , dataKey , err := s . dataKeyByLabel ( ctx , label )
if err != nil {
return "" , nil , err
}
// If no existing data key was found, create a new one
if dataKey == nil {
id , dataKey , err = s . newDataKey ( ctx , name , scope , sess )
id , dataKey , err = s . newDataKey ( ctx , label , scope , sess )
if err != nil {
return "" , nil , err
}
@ -199,16 +201,16 @@ func (s *SecretsService) currentDataKey(ctx context.Context, name string, scope
return id , dataKey , nil
}
// dataKeyByName looks up for data key in cache.
// dataKeyByLabel looks up for data key in cache.
// Otherwise, it fetches it from database, decrypts it and caches it decrypted.
func ( s * SecretsService ) dataKeyByName ( ctx context . Context , name string ) ( string , [ ] byte , error ) {
func ( s * SecretsService ) dataKeyByLabel ( ctx context . Context , label string ) ( string , [ ] byte , error ) {
// 0. Get data key from in-memory cache.
if entry , exists := s . dataKeyCache . getByName ( name ) ; exists {
if entry , exists := s . dataKeyCache . getByLabel ( label ) ; exists && entry . active {
return entry . id , entry . dataKey , nil
}
// 1. Get data key from database.
dataKey , err := s . store . GetCurrentDataKey ( ctx , name )
dataKey , err := s . store . GetCurrentDataKey ( ctx , label )
if err != nil {
if errors . Is ( err , secrets . ErrDataKeyNotFound ) {
return "" , nil , nil
@ -229,13 +231,18 @@ func (s *SecretsService) dataKeyByName(ctx context.Context, name string) (string
}
// 3. Store the decrypted data key into the in-memory cache.
s . dataKeyCache . add ( & dataKeyCacheEntry { id : dataKey . Id , name : dataKey . Name , dataKey : decrypted } )
s . dataKeyCache . add ( & dataKeyCacheEntry {
id : dataKey . Id ,
label : dataKey . Label ,
dataKey : decrypted ,
active : dataKey . Active ,
} )
return dataKey . Id , decrypted , nil
}
// newDataKey creates a new random data key, encrypts it and stores it into the database and cache.
func ( s * SecretsService ) newDataKey ( ctx context . Context , name string , scope string , sess * xorm . Session ) ( string , [ ] byte , error ) {
func ( s * SecretsService ) newDataKey ( ctx context . Context , label string , scope string , sess * xorm . Session ) ( string , [ ] byte , error ) {
// 1. Create new data key.
dataKey , err := newRandomDataKey ( )
if err != nil {
@ -257,11 +264,11 @@ func (s *SecretsService) newDataKey(ctx context.Context, name string, scope stri
// 3. Store its encrypted value into the DB.
id := util . GenerateShortUID ( )
dbDataKey := secrets . DataKey {
Id : id ,
Active : true ,
Name : name ,
Id : id ,
Provider : s . currentProviderID ,
EncryptedData : encrypted ,
Label : label ,
Scope : scope ,
}
@ -276,7 +283,12 @@ func (s *SecretsService) newDataKey(ctx context.Context, name string, scope stri
}
// 4. Store the decrypted data key into the in-memory cache.
s . dataKeyCache . add ( & dataKeyCacheEntry { id : id , name : name , dataKey : dataKey } )
s . dataKeyCache . add ( & dataKeyCacheEntry {
id : id ,
label : label ,
dataKey : dataKey ,
active : true ,
} )
return id , dataKey , nil
}
@ -419,7 +431,12 @@ func (s *SecretsService) dataKeyById(ctx context.Context, id string) ([]byte, er
}
// 3. Store the decrypted data key into the in-memory cache.
s . dataKeyCache . add ( & dataKeyCacheEntry { id : id , name : dataKey . Name , dataKey : decrypted } )
s . dataKeyCache . add ( & dataKeyCacheEntry {
id : dataKey . Id ,
label : dataKey . Label ,
dataKey : decrypted ,
active : dataKey . Active ,
} )
return decrypted , nil
}