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. fmt.Printf("beginning key rotation from %s to %s\n", string(oldKeyBytes), string(newKeyBytes))
  18. for i, b := range oldKeyBytes {
  19. fmt.Println(i, ":", string(b), string(newKeyBytes[i]))
  20. }
  21. err := rotateClusterModel(db, oldKey, newKey)
  22. if err != nil {
  23. fmt.Printf("failed on cluster rotation: %v\n", err)
  24. return err
  25. }
  26. err = rotateClusterCandidateModel(db, oldKey, newKey)
  27. if err != nil {
  28. fmt.Printf("failed on cc rotation: %v\n", err)
  29. return err
  30. }
  31. err = rotateRegistryModel(db, oldKey, newKey)
  32. if err != nil {
  33. fmt.Printf("failed on registry rotation: %v\n", err)
  34. return err
  35. }
  36. err = rotateHelmRepoModel(db, oldKey, newKey)
  37. if err != nil {
  38. fmt.Printf("failed on hr rotation: %v\n", err)
  39. return err
  40. }
  41. err = rotateInfraModel(db, oldKey, newKey)
  42. if err != nil {
  43. fmt.Printf("failed on infra rotation: %v\n", err)
  44. return err
  45. }
  46. err = rotateKubeIntegrationModel(db, oldKey, newKey)
  47. if err != nil {
  48. fmt.Printf("failed on ki rotation: %v\n", err)
  49. return err
  50. }
  51. err = rotateBasicIntegrationModel(db, oldKey, newKey)
  52. if err != nil {
  53. fmt.Printf("failed on basic rotation: %v\n", err)
  54. return err
  55. }
  56. err = rotateOIDCIntegrationModel(db, oldKey, newKey)
  57. if err != nil {
  58. fmt.Printf("failed on oidc rotation: %v\n", err)
  59. return err
  60. }
  61. err = rotateOAuthIntegrationModel(db, oldKey, newKey)
  62. if err != nil {
  63. fmt.Printf("failed on oauth rotation: %v\n", err)
  64. return err
  65. }
  66. err = rotateGCPIntegrationModel(db, oldKey, newKey)
  67. if err != nil {
  68. fmt.Printf("failed on gcp rotation: %v\n", err)
  69. return err
  70. }
  71. err = rotateAWSIntegrationModel(db, oldKey, newKey)
  72. if err != nil {
  73. fmt.Printf("failed on aws rotation: %v\n", err)
  74. return err
  75. }
  76. return nil
  77. }
  78. func rotateClusterModel(db *_gorm.DB, oldKey, newKey *[32]byte) error {
  79. // get count of model
  80. var count int64
  81. if err := db.Model(&models.Cluster{}).Count(&count).Error; err != nil {
  82. return err
  83. }
  84. // cluster-scoped repository
  85. repo := gorm.NewClusterRepository(db, oldKey).(*gorm.ClusterRepository)
  86. // iterate (count / stepSize) + 1 times using Limit and Offset
  87. for i := 0; i < (int(count)/stepSize)+1; i++ {
  88. clusters := []*models.Cluster{}
  89. if err := db.Order("id asc").Offset(i * stepSize).Limit(stepSize).Preload("TokenCache").Find(&clusters).Error; err != nil {
  90. return err
  91. }
  92. // decrypt with the old key
  93. for _, cluster := range clusters {
  94. err := repo.DecryptClusterData(cluster, oldKey)
  95. if err != nil {
  96. return err
  97. }
  98. if err != nil {
  99. fmt.Printf("error decrypting cluster %d\n", cluster.ID)
  100. // in these cases we'll wipe the data -- if it can't be decrypted, we can't
  101. // recover it
  102. cluster.CertificateAuthorityData = []byte{}
  103. cluster.TokenCache.Token = []byte{}
  104. }
  105. }
  106. // encrypt with the new key and re-insert
  107. for _, cluster := range clusters {
  108. err := repo.EncryptClusterData(cluster, newKey)
  109. if err != nil {
  110. fmt.Printf("error encrypting cluster %d\n", cluster.ID)
  111. return err
  112. }
  113. if err := db.Save(cluster).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).(*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).(*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).(*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. }