rotate.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  1. package keyrotate
  2. import (
  3. "fmt"
  4. "encoding/hex"
  5. "github.com/porter-dev/porter/internal/models"
  6. ints "github.com/porter-dev/porter/internal/models/integrations"
  7. gorm "github.com/porter-dev/porter/internal/repository/gorm"
  8. _gorm "gorm.io/gorm"
  9. )
  10. // process 100 records at a time
  11. const stepSize = 100
  12. func Rotate(db *_gorm.DB, oldKey, newKey *[32]byte) error {
  13. oldKeyBytes := make([]byte, 32)
  14. newKeyBytes := make([]byte, 32)
  15. copy(oldKeyBytes[:], oldKey[:])
  16. copy(newKeyBytes[:], newKey[:])
  17. err := rotateClusterModel(db, oldKey, newKey)
  18. if err != nil {
  19. fmt.Printf("failed on cluster rotation: %v\n", err)
  20. return err
  21. }
  22. err = rotateClusterCandidateModel(db, oldKey, newKey)
  23. if err != nil {
  24. fmt.Printf("failed on cc rotation: %v\n", err)
  25. return err
  26. }
  27. err = rotateRegistryModel(db, oldKey, newKey)
  28. if err != nil {
  29. fmt.Printf("failed on registry rotation: %v\n", err)
  30. return err
  31. }
  32. err = rotateHelmRepoModel(db, oldKey, newKey)
  33. if err != nil {
  34. fmt.Printf("failed on hr rotation: %v\n", err)
  35. return err
  36. }
  37. err = rotateInfraModel(db, oldKey, newKey)
  38. if err != nil {
  39. fmt.Printf("failed on infra rotation: %v\n", err)
  40. return err
  41. }
  42. err = rotateKubeIntegrationModel(db, oldKey, newKey)
  43. if err != nil {
  44. fmt.Printf("failed on ki rotation: %v\n", err)
  45. return err
  46. }
  47. err = rotateBasicIntegrationModel(db, oldKey, newKey)
  48. if err != nil {
  49. fmt.Printf("failed on basic rotation: %v\n", err)
  50. return err
  51. }
  52. err = rotateOIDCIntegrationModel(db, oldKey, newKey)
  53. if err != nil {
  54. fmt.Printf("failed on oidc rotation: %v\n", err)
  55. return err
  56. }
  57. err = rotateOAuthIntegrationModel(db, oldKey, newKey)
  58. if err != nil {
  59. fmt.Printf("failed on oauth rotation: %v\n", err)
  60. return err
  61. }
  62. err = rotateGCPIntegrationModel(db, oldKey, newKey)
  63. if err != nil {
  64. fmt.Printf("failed on gcp rotation: %v\n", err)
  65. return err
  66. }
  67. err = rotateAWSIntegrationModel(db, oldKey, newKey)
  68. if err != nil {
  69. fmt.Printf("failed on aws rotation: %v\n", err)
  70. return err
  71. }
  72. return nil
  73. }
  74. func rotateClusterModel(db *_gorm.DB, oldKey, newKey *[32]byte) error {
  75. // get count of model
  76. var count int64
  77. if err := db.Model(&models.Cluster{}).Count(&count).Error; err != nil {
  78. return err
  79. }
  80. // cluster-scoped repository
  81. repo := gorm.NewClusterRepository(db, oldKey).(*gorm.ClusterRepository)
  82. // iterate (count / stepSize) + 1 times using Limit and Offset
  83. for i := 0; i < (int(count)/stepSize)+1; i++ {
  84. clusters := []*models.Cluster{}
  85. if err := db.Order("id asc").Offset(i * stepSize).Limit(stepSize).Find(&clusters).Error; err != nil {
  86. return err
  87. }
  88. // decrypt with the old key
  89. for _, cluster := range clusters {
  90. // attach the token cache, not fatal if it fails
  91. db.Where("id = ?", cluster.TokenCacheID).First(&cluster.TokenCache)
  92. err := repo.DecryptClusterData(cluster, oldKey)
  93. if err != nil {
  94. fmt.Printf("error decrypting cluster %d\n", cluster.ID)
  95. // in these cases we'll wipe the data -- if it can't be decrypted, we can't
  96. // recover it
  97. if err := db.Unscoped().Where("id = ?", cluster.TokenCacheID).Delete(&ints.ClusterTokenCache{}).Error; err != nil {
  98. return err
  99. }
  100. cluster.TokenCacheID = 0
  101. }
  102. }
  103. // encrypt with the new key and re-insert
  104. for _, cluster := range clusters {
  105. err := repo.EncryptClusterData(cluster, newKey)
  106. if err != nil {
  107. fmt.Printf("error encrypting cluster %d\n", cluster.ID)
  108. return err
  109. }
  110. if err := db.Save(cluster).Error; err != nil {
  111. return err
  112. }
  113. if err := db.Save(&cluster.TokenCache).Error; err != nil {
  114. return err
  115. }
  116. }
  117. }
  118. fmt.Printf("rotated %d clusters\n", count)
  119. return nil
  120. }
  121. func rotateClusterCandidateModel(db *_gorm.DB, oldKey, newKey *[32]byte) error {
  122. // get count of model
  123. var count int64
  124. if err := db.Model(&models.ClusterCandidate{}).Count(&count).Error; err != nil {
  125. return err
  126. }
  127. // cluster-scoped repository
  128. repo := gorm.NewClusterRepository(db, oldKey).(*gorm.ClusterRepository)
  129. // iterate (count / stepSize) + 1 times using Limit and Offset
  130. for i := 0; i < (int(count)/stepSize)+1; i++ {
  131. ccs := []*models.ClusterCandidate{}
  132. if err := db.Order("id asc").Offset(i * stepSize).Limit(stepSize).Find(&ccs).Error; err != nil {
  133. return err
  134. }
  135. // decrypt with the old key
  136. for _, cc := range ccs {
  137. err := repo.DecryptClusterCandidateData(cc, oldKey)
  138. if err != nil {
  139. fmt.Printf("error decrypting cluster candidate %d\n", cc.ID)
  140. // in these cases we'll wipe the data -- if it can't be decrypted, we can't
  141. // recover it
  142. cc.AWSClusterIDGuess = []byte{}
  143. cc.Kubeconfig = []byte{}
  144. }
  145. }
  146. // encrypt with the new key and re-insert
  147. for _, cc := range ccs {
  148. err := repo.EncryptClusterCandidateData(cc, newKey)
  149. if err != nil {
  150. fmt.Printf("error encrypting cluster candidate %d\n", cc.ID)
  151. return err
  152. }
  153. if err := db.Save(cc).Error; err != nil {
  154. return err
  155. }
  156. }
  157. }
  158. fmt.Printf("rotated %d cluster candidates\n", count)
  159. return nil
  160. }
  161. func rotateRegistryModel(db *_gorm.DB, oldKey, newKey *[32]byte) error {
  162. // get count of model
  163. var count int64
  164. if err := db.Model(&models.Registry{}).Count(&count).Error; err != nil {
  165. return err
  166. }
  167. // registry-scoped repository
  168. repo := gorm.NewRegistryRepository(db, oldKey).(*gorm.RegistryRepository)
  169. // iterate (count / stepSize) + 1 times using Limit and Offset
  170. for i := 0; i < (int(count)/stepSize)+1; i++ {
  171. regs := []*models.Registry{}
  172. if err := db.Order("id asc").Offset(i * stepSize).Limit(stepSize).Preload("TokenCache").Find(&regs).Error; err != nil {
  173. return err
  174. }
  175. // decrypt with the old key
  176. for _, reg := range regs {
  177. err := repo.DecryptRegistryData(reg, oldKey)
  178. if err != nil {
  179. fmt.Printf("error decrypting registry %d\n", reg.ID)
  180. // in these cases we'll wipe the data -- if it can't be decrypted, we can't
  181. // recover it
  182. reg.TokenCache.Token = []byte{}
  183. }
  184. }
  185. // encrypt with the new key and re-insert
  186. for _, reg := range regs {
  187. err := repo.EncryptRegistryData(reg, newKey)
  188. if err != nil {
  189. fmt.Printf("error encrypting registry %d\n", reg.ID)
  190. return err
  191. }
  192. if err := db.Save(reg).Error; err != nil {
  193. return err
  194. }
  195. }
  196. }
  197. fmt.Printf("rotated %d registries\n", count)
  198. return nil
  199. }
  200. func rotateHelmRepoModel(db *_gorm.DB, oldKey, newKey *[32]byte) error {
  201. // get count of model
  202. var count int64
  203. if err := db.Model(&models.HelmRepo{}).Count(&count).Error; err != nil {
  204. return err
  205. }
  206. // helm repo-scoped repository
  207. repo := gorm.NewHelmRepoRepository(db, oldKey).(*gorm.HelmRepoRepository)
  208. // iterate (count / stepSize) + 1 times using Limit and Offset
  209. for i := 0; i < (int(count)/stepSize)+1; i++ {
  210. hrs := []*models.HelmRepo{}
  211. if err := db.Order("id asc").Offset(i * stepSize).Limit(stepSize).Preload("TokenCache").Find(&hrs).Error; err != nil {
  212. return err
  213. }
  214. // decrypt with the old key
  215. for _, hr := range hrs {
  216. err := repo.DecryptHelmRepoData(hr, oldKey)
  217. if err != nil {
  218. fmt.Printf("error decrypting helm repo %d\n", hr.ID)
  219. // in these cases we'll wipe the data -- if it can't be decrypted, we can't
  220. // recover it
  221. hr.TokenCache.Token = []byte{}
  222. }
  223. }
  224. // encrypt with the new key and re-insert
  225. for _, hr := range hrs {
  226. err := repo.EncryptHelmRepoData(hr, newKey)
  227. if err != nil {
  228. fmt.Printf("error encrypting helm repo %d\n", hr.ID)
  229. return err
  230. }
  231. if err := db.Save(hr).Error; err != nil {
  232. return err
  233. }
  234. }
  235. }
  236. fmt.Printf("rotated %d helm repos\n", count)
  237. return nil
  238. }
  239. func rotateInfraModel(db *_gorm.DB, oldKey, newKey *[32]byte) error {
  240. // get count of model
  241. var count int64
  242. if err := db.Model(&models.Infra{}).Count(&count).Error; err != nil {
  243. return err
  244. }
  245. // helm repo-scoped repository
  246. repo := gorm.NewInfraRepository(db, oldKey).(*gorm.InfraRepository)
  247. // iterate (count / stepSize) + 1 times using Limit and Offset
  248. for i := 0; i < (int(count)/stepSize)+1; i++ {
  249. infras := []*models.Infra{}
  250. if err := db.Order("id asc").Offset(i * stepSize).Limit(stepSize).Find(&infras).Error; err != nil {
  251. return err
  252. }
  253. // decrypt with the old key
  254. for _, infra := range infras {
  255. err := repo.DecryptInfraData(infra, oldKey)
  256. if err != nil {
  257. oldKeyBytes := make([]byte, 32)
  258. newKeyBytes := make([]byte, 32)
  259. copy(oldKeyBytes[:], oldKey[:])
  260. copy(newKeyBytes[:], newKey[:])
  261. fmt.Printf("error decrypting infra %d, %s, %s, %s\n", infra.ID, hex.EncodeToString(infra.LastApplied), string(oldKeyBytes), string(newKeyBytes))
  262. // in these cases we'll wipe the data -- if it can't be decrypted, we can't
  263. // recover it
  264. infra.LastApplied = []byte{}
  265. }
  266. }
  267. // encrypt with the new key and re-insert
  268. for _, infra := range infras {
  269. err := repo.EncryptInfraData(infra, newKey)
  270. if err != nil {
  271. fmt.Printf("error encrypting infra %d\n", infra.ID)
  272. return err
  273. }
  274. if err := db.Save(infra).Error; err != nil {
  275. return err
  276. }
  277. }
  278. }
  279. fmt.Printf("rotated %d infras\n", count)
  280. return nil
  281. }
  282. func rotateKubeIntegrationModel(db *_gorm.DB, oldKey, newKey *[32]byte) error {
  283. // get count of model
  284. var count int64
  285. if err := db.Model(&ints.KubeIntegration{}).Count(&count).Error; err != nil {
  286. return err
  287. }
  288. // cluster-scoped repository
  289. repo := gorm.NewKubeIntegrationRepository(db, oldKey).(*gorm.KubeIntegrationRepository)
  290. // iterate (count / stepSize) + 1 times using Limit and Offset
  291. for i := 0; i < (int(count)/stepSize)+1; i++ {
  292. kis := []*ints.KubeIntegration{}
  293. if err := db.Order("id asc").Offset(i * stepSize).Limit(stepSize).Find(&kis).Error; err != nil {
  294. return err
  295. }
  296. // decrypt with the old key
  297. for _, ki := range kis {
  298. err := repo.DecryptKubeIntegrationData(ki, oldKey)
  299. if err != nil {
  300. fmt.Printf("error decrypting kube integration %d\n", ki.ID)
  301. // in these cases we'll wipe the data -- if it can't be decrypted, we can't
  302. // recover it
  303. ki.ClientCertificateData = []byte{}
  304. ki.ClientKeyData = []byte{}
  305. ki.Token = []byte{}
  306. ki.Username = []byte{}
  307. ki.Password = []byte{}
  308. ki.Kubeconfig = []byte{}
  309. }
  310. }
  311. // encrypt with the new key and re-insert
  312. for _, ki := range kis {
  313. err := repo.EncryptKubeIntegrationData(ki, newKey)
  314. if err != nil {
  315. fmt.Printf("error encrypting kube integration %d\n", ki.ID)
  316. return err
  317. }
  318. if err := db.Save(ki).Error; err != nil {
  319. return err
  320. }
  321. }
  322. }
  323. fmt.Printf("rotated %d kube integrations\n", count)
  324. return nil
  325. }
  326. func rotateBasicIntegrationModel(db *_gorm.DB, oldKey, newKey *[32]byte) error {
  327. // get count of model
  328. var count int64
  329. if err := db.Model(&ints.BasicIntegration{}).Count(&count).Error; err != nil {
  330. return err
  331. }
  332. // cluster-scoped repository
  333. repo := gorm.NewBasicIntegrationRepository(db, oldKey).(*gorm.BasicIntegrationRepository)
  334. // iterate (count / stepSize) + 1 times using Limit and Offset
  335. for i := 0; i < (int(count)/stepSize)+1; i++ {
  336. basics := []*ints.BasicIntegration{}
  337. if err := db.Order("id asc").Offset(i * stepSize).Limit(stepSize).Find(&basics).Error; err != nil {
  338. return err
  339. }
  340. // decrypt with the old key
  341. for _, basic := range basics {
  342. err := repo.DecryptBasicIntegrationData(basic, oldKey)
  343. if err != nil {
  344. fmt.Printf("error decrypting basic integration %d\n", basic.ID)
  345. // in these cases we'll wipe the data -- if it can't be decrypted, we can't
  346. // recover it
  347. basic.Username = []byte{}
  348. basic.Password = []byte{}
  349. }
  350. }
  351. // encrypt with the new key and re-insert
  352. for _, basic := range basics {
  353. err := repo.EncryptBasicIntegrationData(basic, newKey)
  354. if err != nil {
  355. fmt.Printf("error encrypting basic integration %d\n", basic.ID)
  356. return err
  357. }
  358. if err := db.Save(basic).Error; err != nil {
  359. return err
  360. }
  361. }
  362. }
  363. fmt.Printf("rotated %d basic integrations\n", count)
  364. return nil
  365. }
  366. func rotateOIDCIntegrationModel(db *_gorm.DB, oldKey, newKey *[32]byte) error {
  367. // get count of model
  368. var count int64
  369. if err := db.Model(&ints.OIDCIntegration{}).Count(&count).Error; err != nil {
  370. return err
  371. }
  372. // cluster-scoped repository
  373. repo := gorm.NewOIDCIntegrationRepository(db, oldKey).(*gorm.OIDCIntegrationRepository)
  374. // iterate (count / stepSize) + 1 times using Limit and Offset
  375. for i := 0; i < (int(count)/stepSize)+1; i++ {
  376. oidcs := []*ints.OIDCIntegration{}
  377. if err := db.Order("id asc").Offset(i * stepSize).Limit(stepSize).Find(&oidcs).Error; err != nil {
  378. return err
  379. }
  380. // decrypt with the old key
  381. for _, oidc := range oidcs {
  382. err := repo.DecryptOIDCIntegrationData(oidc, oldKey)
  383. if err != nil {
  384. fmt.Printf("error decrypting oidc integration %d\n", oidc.ID)
  385. // in these cases we'll wipe the data -- if it can't be decrypted, we can't
  386. // recover it
  387. oidc.IssuerURL = []byte{}
  388. oidc.ClientID = []byte{}
  389. oidc.ClientSecret = []byte{}
  390. oidc.CertificateAuthorityData = []byte{}
  391. oidc.IDToken = []byte{}
  392. oidc.RefreshToken = []byte{}
  393. }
  394. }
  395. // encrypt with the new key and re-insert
  396. for _, oidc := range oidcs {
  397. err := repo.EncryptOIDCIntegrationData(oidc, newKey)
  398. if err != nil {
  399. fmt.Printf("error encrypting oidc integration %d\n", oidc.ID)
  400. return err
  401. }
  402. if err := db.Save(oidc).Error; err != nil {
  403. return err
  404. }
  405. }
  406. }
  407. fmt.Printf("rotated %d oidc integrations\n", count)
  408. return nil
  409. }
  410. func rotateOAuthIntegrationModel(db *_gorm.DB, oldKey, newKey *[32]byte) error {
  411. // get count of model
  412. var count int64
  413. if err := db.Model(&ints.OAuthIntegration{}).Count(&count).Error; err != nil {
  414. return err
  415. }
  416. // cluster-scoped repository
  417. repo := gorm.NewOAuthIntegrationRepository(db, oldKey, nil).(*gorm.OAuthIntegrationRepository)
  418. // iterate (count / stepSize) + 1 times using Limit and Offset
  419. for i := 0; i < (int(count)/stepSize)+1; i++ {
  420. oauths := []*ints.OAuthIntegration{}
  421. if err := db.Order("id asc").Offset(i * stepSize).Limit(stepSize).Find(&oauths).Error; err != nil {
  422. return err
  423. }
  424. // decrypt with the old key
  425. for _, oauth := range oauths {
  426. err := repo.DecryptOAuthIntegrationData(oauth, oldKey)
  427. if err != nil {
  428. fmt.Printf("error decrypting oauth integration %d\n", oauth.ID)
  429. // in these cases we'll wipe the data -- if it can't be decrypted, we can't
  430. // recover it
  431. oauth.ClientID = []byte{}
  432. oauth.AccessToken = []byte{}
  433. oauth.RefreshToken = []byte{}
  434. }
  435. }
  436. // encrypt with the new key and re-insert
  437. for _, oauth := range oauths {
  438. err := repo.EncryptOAuthIntegrationData(oauth, newKey)
  439. if err != nil {
  440. fmt.Printf("error encrypting oauth integration %d\n", oauth.ID)
  441. return err
  442. }
  443. if err := db.Save(oauth).Error; err != nil {
  444. return err
  445. }
  446. }
  447. }
  448. fmt.Printf("rotated %d oauth integrations\n", count)
  449. return nil
  450. }
  451. func rotateGCPIntegrationModel(db *_gorm.DB, oldKey, newKey *[32]byte) error {
  452. // get count of model
  453. var count int64
  454. if err := db.Model(&ints.GCPIntegration{}).Count(&count).Error; err != nil {
  455. return err
  456. }
  457. // cluster-scoped repository
  458. repo := gorm.NewGCPIntegrationRepository(db, oldKey, nil).(*gorm.GCPIntegrationRepository)
  459. // iterate (count / stepSize) + 1 times using Limit and Offset
  460. for i := 0; i < (int(count)/stepSize)+1; i++ {
  461. gcps := []*ints.GCPIntegration{}
  462. if err := db.Order("id asc").Offset(i * stepSize).Limit(stepSize).Find(&gcps).Error; err != nil {
  463. return err
  464. }
  465. // decrypt with the old key
  466. for _, gcp := range gcps {
  467. err := repo.DecryptGCPIntegrationData(gcp, oldKey)
  468. if err != nil {
  469. fmt.Printf("error decrypting gcp integration %d\n", gcp.ID)
  470. // in these cases we'll wipe the data -- if it can't be decrypted, we can't
  471. // recover it
  472. gcp.GCPKeyData = []byte{}
  473. }
  474. }
  475. // encrypt with the new key and re-insert
  476. for _, gcp := range gcps {
  477. err := repo.EncryptGCPIntegrationData(gcp, newKey)
  478. if err != nil {
  479. fmt.Printf("error encrypting gcp integration %d\n", gcp.ID)
  480. return err
  481. }
  482. if err := db.Save(gcp).Error; err != nil {
  483. return err
  484. }
  485. }
  486. }
  487. fmt.Printf("rotated %d gcp integrations\n", count)
  488. return nil
  489. }
  490. func rotateAWSIntegrationModel(db *_gorm.DB, oldKey, newKey *[32]byte) error {
  491. // get count of model
  492. var count int64
  493. if err := db.Model(&ints.AWSIntegration{}).Count(&count).Error; err != nil {
  494. return err
  495. }
  496. // cluster-scoped repository
  497. repo := gorm.NewAWSIntegrationRepository(db, oldKey, nil).(*gorm.AWSIntegrationRepository)
  498. // iterate (count / stepSize) + 1 times using Limit and Offset
  499. for i := 0; i < (int(count)/stepSize)+1; i++ {
  500. awss := []*ints.AWSIntegration{}
  501. if err := db.Order("id asc").Offset(i * stepSize).Limit(stepSize).Find(&awss).Error; err != nil {
  502. return err
  503. }
  504. // decrypt with the old key
  505. for _, aws := range awss {
  506. err := repo.DecryptAWSIntegrationData(aws, oldKey)
  507. if err != nil {
  508. fmt.Printf("error encrypting aws integration %d\n", aws.ID)
  509. // in these cases we'll wipe the data -- if it can't be decrypted, we can't
  510. // recover it
  511. aws.AWSAccessKeyID = []byte{}
  512. aws.AWSClusterID = []byte{}
  513. aws.AWSSecretAccessKey = []byte{}
  514. aws.AWSSessionToken = []byte{}
  515. }
  516. }
  517. // encrypt with the new key and re-insert
  518. for _, aws := range awss {
  519. err := repo.EncryptAWSIntegrationData(aws, newKey)
  520. if err != nil {
  521. fmt.Printf("error decrypting aws integration %d\n", aws.ID)
  522. return err
  523. }
  524. if err := db.Save(aws).Error; err != nil {
  525. return err
  526. }
  527. }
  528. }
  529. fmt.Printf("rotated %d aws integrations\n", count)
  530. return nil
  531. }