@@ -10,6 +10,8 @@ import (
1010 "os"
1111 "path/filepath"
1212 "regexp"
13+ "strconv"
14+ "time"
1315
1416 "github.com/stackitcloud/stackit-cli/internal/pkg/auth"
1517)
@@ -22,16 +24,30 @@ var (
2224 ErrorInvalidCacheIdentifier = fmt .Errorf ("invalid cache identifier" )
2325)
2426
27+ const (
28+ cacheKeyMaxAge = 90 * 24 * time .Hour
29+ )
30+
2531func Init () error {
2632 cacheDir , err := os .UserCacheDir ()
2733 if err != nil {
2834 return fmt .Errorf ("get user cache dir: %w" , err )
2935 }
3036 cacheFolderPath = filepath .Join (cacheDir , "stackit" )
3137
38+ // Encryption keys should only be used a limited number of times for aes-gcm.
39+ // Thus, refresh the key periodically. This will invalidate all cached entries.
3240 key , _ := auth .GetAuthField (auth .CACHE_ENCRYPTION_KEY )
41+ age , _ := auth .GetAuthField (auth .CACHE_ENCRYPTION_KEY_AGE )
3342 cacheEncryptionKey = nil
34- if key != "" {
43+ var keyAge time.Time
44+ if age != "" {
45+ ageSeconds , err := strconv .ParseInt (age , 10 , 64 )
46+ if err == nil {
47+ keyAge = time .Unix (ageSeconds , 0 )
48+ }
49+ }
50+ if key != "" && keyAge .Add (cacheKeyMaxAge ).After (time .Now ()) {
3551 cacheEncryptionKey , _ = base64 .StdEncoding .DecodeString (key )
3652 // invalid key length
3753 if len (cacheEncryptionKey ) != 32 {
@@ -45,7 +61,14 @@ func Init() error {
4561 return fmt .Errorf ("cache encryption key: %v" , err )
4662 }
4763 key := base64 .StdEncoding .EncodeToString (cacheEncryptionKey )
48- return auth .SetAuthField (auth .CACHE_ENCRYPTION_KEY , key )
64+ err = auth .SetAuthField (auth .CACHE_ENCRYPTION_KEY , key )
65+ if err != nil {
66+ return fmt .Errorf ("save cache encryption key: %v" , err )
67+ }
68+ err = auth .SetAuthField (auth .CACHE_ENCRYPTION_KEY_AGE , fmt .Sprint (time .Now ().Unix ()))
69+ if err != nil {
70+ return fmt .Errorf ("save cache encryption key age: %v" , err )
71+ }
4972 }
5073 return nil
5174}
0 commit comments