@@ -78,9 +78,19 @@ public async virtual Task<HostSecretsInfo> GetHostSecretsAsync()
7878 await PersistSecretsAsync ( hostSecrets ) ;
7979 }
8080
81- // Host secrets will be in the original persisted state at this point (e.g. encrypted),
82- // so we read the secrets running them through the appropriate readers
83- hostSecrets = ReadHostSecrets ( hostSecrets ) ;
81+ try
82+ {
83+ // Host secrets will be in the original persisted state at this point (e.g. encrypted),
84+ // so we read the secrets running them through the appropriate readers
85+ hostSecrets = ReadHostSecrets ( hostSecrets ) ;
86+ }
87+ catch ( CryptographicException )
88+ {
89+ _traceWriter . Verbose ( Resources . TraceNonDecryptedHostSecretRefresh ) ;
90+ _logger ? . LogDebug ( Resources . TraceNonDecryptedHostSecretRefresh ) ;
91+ await PersistSecretsAsync ( hostSecrets , null , true ) ;
92+ await RefreshSecretsAsync ( hostSecrets ) ;
93+ }
8494
8595 // If the persistence state of any of our secrets is stale (e.g. the encryption key has been rotated), update
8696 // the state and persist the secrets
@@ -132,8 +142,19 @@ public async virtual Task<IDictionary<string, string>> GetFunctionSecretsAsync(s
132142 await PersistSecretsAsync ( secrets , functionName ) ;
133143 }
134144
135- // Read all secrets, which will run the keys through the appropriate readers
136- secrets . Keys = secrets . Keys . Select ( k => _keyValueConverterFactory . ReadKey ( k ) ) . ToList ( ) ;
145+ try
146+ {
147+ // Read all secrets, which will run the keys through the appropriate readers
148+ secrets . Keys = secrets . Keys . Select ( k => _keyValueConverterFactory . ReadKey ( k ) ) . ToList ( ) ;
149+ }
150+ catch ( CryptographicException )
151+ {
152+ string message = string . Format ( Resources . TraceNonDecryptedFunctionSecretRefresh , functionName ) ;
153+ _traceWriter . Verbose ( message ) ;
154+ _logger ? . LogDebug ( message ) ;
155+ await PersistSecretsAsync ( secrets , functionName , true ) ;
156+ await RefreshSecretsAsync ( secrets , functionName ) ;
157+ }
137158
138159 if ( secrets . HasStaleKeys )
139160 {
@@ -372,10 +393,27 @@ private Task RefreshSecretsAsync<T>(T secrets, string keyScope = null) where T :
372393 return PersistSecretsAsync ( refreshedSecrets , keyScope ) ;
373394 }
374395
375- private Task PersistSecretsAsync < T > ( T secrets , string keyScope = null ) where T : ScriptSecrets
396+ private async Task PersistSecretsAsync < T > ( T secrets , string keyScope = null , bool isNonDecryptable = false ) where T : ScriptSecrets
376397 {
398+ ScriptSecretsType secretsType = secrets . SecretsType ;
377399 string secretsContent = ScriptSecretSerializer . SerializeSecrets < T > ( secrets ) ;
378- return _repository . WriteAsync ( secrets . SecretsType , keyScope , secretsContent ) ;
400+ if ( isNonDecryptable )
401+ {
402+ string [ ] secretBackups = await _repository . GetSecretSnapshots ( secrets . SecretsType , keyScope ) ;
403+
404+ if ( secretBackups . Length >= ScriptConstants . MaximumSecretBackupCount )
405+ {
406+ string message = string . Format ( Resources . ErrorTooManySecretBackups , ScriptConstants . MaximumSecretBackupCount , string . IsNullOrEmpty ( keyScope ) ? "host" : keyScope ) ;
407+ _traceWriter . Verbose ( message ) ;
408+ _logger ? . LogDebug ( message ) ;
409+ throw new InvalidOperationException ( message ) ;
410+ }
411+ await _repository . WriteSnapshotAsync ( secretsType , keyScope , secretsContent ) ;
412+ }
413+ else
414+ {
415+ await _repository . WriteAsync ( secretsType , keyScope , secretsContent ) ;
416+ }
379417 }
380418
381419 private HostSecrets ReadHostSecrets ( HostSecrets hostSecrets )
0 commit comments