SigningKeys: Clean old keys by expiry (#76048)

* clean old keys by expiry

* nit
This commit is contained in:
Jo 2023-10-06 10:45:24 +02:00 committed by GitHub
parent 0081d6baf3
commit 12ccc8ca23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 0 deletions

View File

@ -13,6 +13,8 @@ import (
"github.com/go-jose/go-jose/v3"
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/infra/localcache"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/secrets"
"github.com/grafana/grafana/pkg/services/signingkeys"
"github.com/grafana/grafana/pkg/services/sqlstore"
@ -32,9 +34,13 @@ type SigningStore interface {
var _ SigningStore = (*Store)(nil)
const cleanupRateLimitKey = "signingkeys-cleanup"
type Store struct {
dbStore db.DB
secretsService secrets.Service
log log.Logger
localCache *localcache.CacheService
}
type SigningKey struct {
@ -50,6 +56,8 @@ func NewSigningKeyStore(dbStore db.DB, secretsService secrets.Service) *Store {
return &Store{
dbStore: dbStore,
secretsService: secretsService,
log: log.New("signing.key_service"),
localCache: localcache.New(12*time.Hour, 4*time.Hour),
}
}
@ -130,6 +138,24 @@ func (s *Store) AddPrivateKey(ctx context.Context,
return signingkeys.ErrSigningKeyAlreadyExists.Errorf("The specified key already exists: %s", keyID)
})
if _, ok := s.localCache.Get(cleanupRateLimitKey); !ok {
go func() {
defer func() {
if err := recover(); err != nil {
s.log.Error("panic during expired signing key cleanup", "err", err)
}
}()
ctxGo, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
if err := s.cleanupExpiredKeys(ctxGo); err != nil {
s.log.Error("Failed to cleanup expired signing keys", "err", err)
}
}()
s.localCache.Set(cleanupRateLimitKey, true, 1*time.Hour)
}
return signer, err
}
@ -218,3 +244,14 @@ func (s *Store) decodePrivateKey(ctx context.Context, signingKey *SigningKey) (c
}
return assertedKey, nil
}
// cleanupExpiredKeys removes expired keys from the database that have expired more than 61 days ago
func (s *Store) cleanupExpiredKeys(ctx context.Context) error {
err := s.dbStore.WithTransactionalDbSession(ctx, func(tx *sqlstore.DBSession) error {
_, err := tx.Exec("DELETE FROM signing_key WHERE expires_at IS NOT NULL AND expires_at < ?",
time.Now().UTC().Add(-61*24*time.Hour))
return err
})
return err
}

View File

@ -162,6 +162,9 @@ func TestIntegrationAddPrivateKey(t *testing.T) {
},
}
_, exists := store.localCache.Get(cleanupRateLimitKey)
require.False(t, exists)
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
got, err := store.AddPrivateKey(ctx, tc.keyID, tc.alg, tc.privateKey, tc.expiresAt, tc.force)
@ -184,6 +187,9 @@ func TestIntegrationAddPrivateKey(t *testing.T) {
}
})
}
_, exists = store.localCache.Get(cleanupRateLimitKey)
require.True(t, exists)
}
func generateRSAKey(t *testing.T) *rsa.PrivateKey {