MCPcopy Index your code
hub / github.com/coder/coder / rotateKeys

Method rotateKeys

coderd/cryptokeys/rotate.go:97–170  ·  view source on GitHub ↗

rotateKeys checks for any keys needing rotation or deletion and may insert a new key if it detects that a valid one does not exist for a feature.

(ctx context.Context)

Source from the content-addressed store, hash-verified

95// may insert a new key if it detects that a valid one does
96// not exist for a feature.
97func (k *rotator) rotateKeys(ctx context.Context) error {
98 return k.db.InTx(
99 func(tx database.Store) error {
100 err := tx.AcquireLock(ctx, database.LockIDCryptoKeyRotation)
101 if err != nil {
102 return xerrors.Errorf("acquire lock: %w", err)
103 }
104
105 cryptokeys, err := tx.GetCryptoKeys(ctx)
106 if err != nil {
107 return xerrors.Errorf("get keys: %w", err)
108 }
109
110 featureKeys, err := keysByFeature(cryptokeys, k.features)
111 if err != nil {
112 return xerrors.Errorf("keys by feature: %w", err)
113 }
114
115 now := dbtime.Time(k.clock.Now().UTC())
116 for feature, keys := range featureKeys {
117 // We'll use a counter to determine if we should insert a new key. We should always have at least one key for a feature.
118 var validKeys int
119 for _, key := range keys {
120 switch {
121 case shouldDeleteKey(key, now):
122 _, err := tx.DeleteCryptoKey(ctx, database.DeleteCryptoKeyParams{
123 Feature: key.Feature,
124 Sequence: key.Sequence,
125 })
126 if err != nil {
127 return xerrors.Errorf("delete key: %w", err)
128 }
129 k.logger.Debug(ctx, "deleted key",
130 slog.F("key", key.Sequence),
131 slog.F("feature", key.Feature),
132 )
133 case shouldRotateKey(key, k.keyDuration, now):
134 _, err := k.rotateKey(ctx, tx, key, now)
135 if err != nil {
136 return xerrors.Errorf("rotate key: %w", err)
137 }
138 k.logger.Debug(ctx, "rotated key",
139 slog.F("key", key.Sequence),
140 slog.F("feature", key.Feature),
141 )
142 validKeys++
143 default:
144 // We only consider keys without a populated deletes_at field as valid.
145 // This is because under normal circumstances the deletes_at field
146 // is set during rotation (meaning a new key was generated)
147 // but it's possible if the database was manually altered to
148 // delete the new key we may be in a situation where there
149 // isn't a key to replace the one scheduled for deletion.
150 if !key.DeletesAt.Valid {
151 validKeys++
152 }
153 }
154 }

Callers 3

Test_rotateKeysFunction · 0.95
StartRotatorFunction · 0.95
startMethod · 0.95

Calls 11

rotateKeyMethod · 0.95
insertNewKeyMethod · 0.95
TimeFunction · 0.92
keysByFeatureFunction · 0.85
shouldDeleteKeyFunction · 0.85
shouldRotateKeyFunction · 0.85
InTxMethod · 0.65
AcquireLockMethod · 0.65
GetCryptoKeysMethod · 0.65
DeleteCryptoKeyMethod · 0.65
ErrorfMethod · 0.45

Tested by 1

Test_rotateKeysFunction · 0.76