{
    "componentChunkName": "component---src-templates-issues-tsx",
    "path": "/issues/503",
    "result": {"data":{"issuesJson":{"id":"67f7d2ef-b506-5fdf-b332-52b15cd265a7","title":"bitnami-labs/sealed-secrets: 一款 Kubernetes 控制器並用于实现单向加密 Secrets 的工具","number":503,"bodyHTML":"<div align=\"center\" dir=\"auto\">\n<p dir=\"auto\"><a target=\"_blank\" rel=\"noopener noreferrer nofollow\" href=\"https://camo.githubusercontent.com/a15b413168923d02e21292705ceaf86b92675f98e250c5c896a02ba7504a6eae/68747470733a2f2f63646e2e6a7364656c6976722e6e65742f67682f657279616a662f7475406d61696e2f696d672f696d6167655f32303234303432305f3231343430382e676966\"><img src=\"https://camo.githubusercontent.com/a15b413168923d02e21292705ceaf86b92675f98e250c5c896a02ba7504a6eae/68747470733a2f2f63646e2e6a7364656c6976722e6e65742f67682f657279616a662f7475406d61696e2f696d672f696d6167655f32303234303432305f3231343430382e676966\" width=\"100%\" height=\"3\" data-animated-image=\"\" data-canonical-src=\"https://cdn.jsdelivr.net/gh/eryajf/tu@main/img/image_20240420_214408.gif\" style=\"max-width: 100%; height: auto; max-height: 3px;\"></a><br><br></p>\n<markdown-accessiblity-table><table role=\"table\">\n<thead>\n<tr>\n<th align=\"right\">Repos</th>\n<th align=\"left\"><a href=\"https://github.com/bitnami-labs/sealed-secrets\">bitnami-labs/sealed-secrets</a></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"right\"><strong>Views</strong></td>\n<td align=\"left\"><a href=\"https://github.com/opsre/awesome-ops\"><img src=\"https://camo.githubusercontent.com/18d0060ca14a07e6e403fdb9868638e2bd85ed5d0b0c536ca884b4f2cc2df7c9/68747470733a2f2f76696577732e77686174696c656172656e65642e746f6461792f76696577732f6769746875622f6269746e616d692d6c6162732f7365616c65642d736563726574732e737667\" alt=\"views\" data-canonical-src=\"https://views.whatilearened.today/views/github/bitnami-labs/sealed-secrets.svg\" style=\"max-width: 100%;\"></a></td>\n</tr>\n<tr>\n<td align=\"right\"><strong>Stars</strong></td>\n<td align=\"left\"><a href=\"https://github.com/opsre/awesome-ops\"><img src=\"https://camo.githubusercontent.com/60d88b97c9543195813f05f71e150a6222a20965a606ac331ec1fdabdc2d1159/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f6269746e616d692d6c6162732f7365616c65642d736563726574733f636f6c6f723d663266303864266c6f676f3d556e64657274616c65266c6f676f436f6c6f723d656234363330\" alt=\"stars\" data-canonical-src=\"https://img.shields.io/github/stars/bitnami-labs/sealed-secrets?color=f2f08d&amp;logo=Undertale&amp;logoColor=eb4630\" style=\"max-width: 100%;\"></a></td>\n</tr>\n<tr>\n<td align=\"right\"><strong>Forks</strong></td>\n<td align=\"left\"><a href=\"https://github.com/opsre/awesome-ops\"><img src=\"https://camo.githubusercontent.com/c444171250e40b961900a8f86a0461931b9ef91d65a12582852b867c3f76f39a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f666f726b732f6269746e616d692d6c6162732f7365616c65642d736563726574733f636f6c6f723d626138366562266c6f676f3d48616e647368616b65266c6f676f436f6c6f723d656136616136\" alt=\"forks\" data-canonical-src=\"https://img.shields.io/github/forks/bitnami-labs/sealed-secrets?color=ba86eb&amp;logo=Handshake&amp;logoColor=ea6aa6\" style=\"max-width: 100%;\"></a></td>\n</tr>\n<tr>\n<td align=\"right\"><strong>License</strong></td>\n<td align=\"left\"><a href=\"https://github.com/opsre/awesome-ops\"><img src=\"https://camo.githubusercontent.com/e19c45c336bfc40cc8590492fd31393562d30bb2333bdf2eb0a23af2be04c1a1/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6269746e616d692d6c6162732f7365616c65642d736563726574733f6c6f676f3d64617461253341696d616765253246706e672533426261736536342532436956424f5277304b47676f414141414e53556845556741414144414141414177434159414141425841766d48414141414358424957584d41414173544141414c457745416d70775941414144336b6c45515652346e4f335953557a5555426748384a726f57567255474a66456d3773584e63534446784d544c327069347348456778654e526f77586770455742445552522532424e414e4f4b4f4b36366f6f4b4a4742586545475263574163455646475152484677516d483525324630774861655748493944554455354c356b6e6568644f62377a66652532423139636e434a47495243516945596c514237594a4979474c38616f73756c565a36695246516a69474b6b7564576735614c6c704f70704e586e665071773555304459524a6d56786a4367464633424c755a476d416f5655694b4541726d583744375553677351706f72674761336748664b34483663754262435644334771683141352532424c6745253242467749656e514d306a6f446f66714c6f48564e7742796d384370546e416d327a51713073676478624964515a556c416b7150415a3664676a303541446f59526f6f66792532466f5869726f376b3551586a4c6f70677a4b69514e6c4c4461716f4967754577426a7a7150355066446a45394479495879493633464d547751464d43567271774e61763451666f52673538514625324266724d485172454b3844546f434d714e4179574e4866786d54526f4c4f726d5352566747744466714345715a4f4851727a6f34706243557341333431365169364551394b476a6345465267484f724f4b6e5536574162396247455459656b4b7843766a546167394534706a653534446b3551503862624d4859762532464333756541654a6b50304f4778422532424a70426e4172595238455951516e6f4e31414e4661426e5050356c385372736559514c303641646b30464a5938484f5761424d6c6541486a683068506f73497a6c6f3876304125324633345a694f6548726130714b52504d5653493774762532423932747725324676687855654252713456454c674d376642714b354770526d6f514c584e7075625475367a6f4e52706754386e5051627138347764253246494375767978694b4871694e41664933774d367549684271476b4c696977414f734b44714f68743749747239567938536a52424557667941627225324668523142667056514664484a42253246423268683778376a36517077435665655951326b72554235436c636a3641326d3067576a25324244306d4c34397a573563517943484c4e37726a6c6d6d6174457958582532464372547a412532466f51785a6b576c39474a5443566f25324279546a3837253242346769504b6376307149486f344156344430565a727251493334706e70524d36357875652532467a417265453425324654253246536f676c664542794d7369517441546c4c3352414a355948725378365a44665337307337754d486842705225324659423573305057366f455270316236253246667252684b3353444c35546965364f515548516c5133735644752532427a50636b397657453973747225324236496a533967486d5750616861444a25324277434b364e494242587348423948796b587378774470686c436d416476706c6162554a4e6e5a504239342532464e7436784f6538587a4562503257684d335741673147756236744825324233513150673337365239713475716c6e6f36676448476a444f5139306562303141484d3672596975554a314f713472344656756a35765239427a4d3957674e764f7977446869495951467667626366774166774d764863615067425041253246447948476a50624e394138616d6562636477416444354e6633373574787165774e5552656f797677424958594c645170576c6877465771745061435044334173467541535636717171496c62304a766b564331464c39576b4c55556c55574b337a585a4c46432532423125324642726f46746f364f7358497545594a5034447a7a5732594656316f4a614141414141456c46546b5375516d4343\" alt=\"license\" data-canonical-src=\"https://img.shields.io/github/license/bitnami-labs/sealed-secrets?logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAD3klEQVR4nO3YSUzUUBgH8JroWVrUGJfEm7sXNcSDFxMTL2pi4sHEgxeNRowXgpEWBDURR%2BNANOKOK66ooKJGBXeEGRcWAcEVFGQRHFwQmH5%2F0wHaeWHI9DUDU5L5knehdOb7zfe%2B19cnCJGIRCQiEYlQB7YJIyGL8aosulVZ6iRFQjiGKkudWg5aLlpOppNXnfPqw5U0DYRJmVxjCgFF3BLuZGmAoVUiKEArmX7D7USgsQporgGa3gHfK4H6cuBbCVD3Gqh1A5%2BLgE%2BFwIenQM0joDofqLoHVNwBym8CpTnAm2zQq0sgdxbIdQZUlAkqPAZ6dgj05ADoYRoofy%2FoXiro7k5QXjLopgzKiQNlLDaqoIguEwBjzqP5PfDjE9DyIXyI63FMTwQFMCVrqwNav4QfoRg58QF%2BfrMHQrEK8DToCMqNAyWNHfxmTRoLOrmSRVgGtDfqCEqZOHQrzo4pbCUsA3416Qi6EQ9KGjcEFRgHOrOKnU6WAb9bGETYekKxCvjTag9E4pje54Dk5QP8bbMHYv%2FC3ueAeJkP0OGxB%2BJpBnArYR8EYQQnoN1ANFaBnPP5l8SrseYQL06Adk0FJY8HOWaBMleAHjh0hPosIzlo8v0A%2F34ZiOeHra0qKRPMVSI7tv%2B92tw%2FvhxUeBRq4VELgM7fBqK5GpRmoQLXNpubTu6zoNRpgT8nPQbq84wd%2FICuvyxiKHqiNAfI3wM6uIhBqGkLiiwAOsKDqOht7Itr9Vy8SjRBEWfyAbr%2FhR1BfpVQFdHJB%2FB2hh7x7j6QpwCVeeYQ2krUB5Clcj6A2m0gWj%2BD0mL49zW5cQyCHLN7rjlmmatEyXX%2FCrTzA%2FoQxZkWl9GJTCVo%2ByTj87%2B4giPKcv0qIHo4AV4D0VZrrQI34pnpRM65xue%2FzAreE4%2FT%2FSoglfEByMsiQtATlL3RAJ5YHrSx6ZDfS70s7uMHhBpR%2FYB5s0PW6oERp1b6%2FfrRhK3SDL5Tie6OQUHQlQ3sVDu%2BzPck9vWE9str%2B6IjS9gHmWPahaDJ%2BwCK6NIBBXsHB9HykXsxwDphlCmAdvplabUJNnZPB94%2FNt6xOe8XzEbP2WhM3WAg1Gub6tH%2B3Q1Pg376R9q4uqlno6gdHGjDOQ90eb01AHM6rYiuUJ1Oq4r4FVuj5vR9BzM9WgNvOywDhiIYQFvgbcfwAfwMvHcaPgBPA%2FDyHGjPbN9A8amebcdwAdD5Nf375txqewNUReoyvwBIXYLdQpWlhwFWqtPaCPD3AsFuASV6qqqIlb0JvkVC1FL9WkLUUlUWK3zXZLFC%2B1%2FBroFto6OsXIuEYJP4DzzW2YFV1oJaAAAAAElFTkSuQmCC\" style=\"max-width: 100%;\"></a></td>\n</tr>\n<tr>\n<td align=\"right\"><strong>UpdatedAt</strong></td>\n<td align=\"left\"><a href=\"https://github.com/opsre/awesome-ops\"><img src=\"https://camo.githubusercontent.com/6dafba7a4c0ec102d7f979c1a3d48cd23fd32c739a211a09bbc6985f516c6efb/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f6269746e616d692d6c6162732f7365616c65642d736563726574733f646973706c61795f74696d657374616d703d636f6d6d6974746572266c6f676f3d64617461253341696d616765253246706e672533426261736536342532436956424f5277304b47676f414141414e5355684555674141414234414141416543415941414141374d4b3669414141414358424957584d41414173544141414c457745416d7077594141414648556c45515652346e4c5658375539615678776d3236646c582532466468627825324232253246516e626b7655627264554151674a4a496655444e574454546d4f76314651554661504a346b7573725630314a7431734e70637453327533626f745a746d786439744a5346536f714b71494635625944464c436f76436c656673747a4a387758524c445a4c7a6e6b634f343535376e3364332532466e655a3472454f515a74315771462532423858467234253242664f4c4565326a6f59307a776638546f795a50766a45676b4c592532426b306d6d72584f36644b696e787a476b30666a5430782532425279723055716e6359637a4d317263347451253242497270324c4758646f344e4334567657715453373277716c632532427231334f527269364b6458646e624f484c6c776c7a4a70524b6e3657342532424b36706f4f434e6e494166486a253246253242776168495a4234764b6e715a6630714a704e49716c2532467638545530634e6c3572627963337730516e54703379324c54614a374d314e617844723266526e315370504736476961323174664533345463614f617931694d55564f5146624659714957536f31573854694156616e43306576584f4542375770313448466232327a453566714c4f433545524c515769644e614e49347545636339693768634a6c644868324e57725135674464624f6c7061756d49754c62326174415144506e7a3062384e6257636d785656524a33486d7870536377777a4f4a6d4b44524765384c6c435a444c4739673754496e5631516c376462586256316533675430574b697243466f6d6b5079767758466c5a474a4f6a563625324253743634757564445a4f55354555636f782532464d455144567674364d62634e3237593341797a687633737061557242365a3971724a534f3139657a6a387032704c426b4a792532426343484a7857493567573574636652527a31645531394766476b6f7539505a4f34736d52396a4746777065783444793362766e6d4b79706f74625531335669646a71595a68726a343972764d457425324625324659714c7a396430304e6a57253246637a67796f394f35317a7336614e6c6f354644747530445a675146686c47584a30644241446f4e6864367576703657686f617967374e394c564748386d443462253246486e667455516f4e4734764c51306769784d716c5725324234714f6a744e48446733723166365969525347785279375576714c62395534716b716e78504f4e7661356c447048723125324279794b524e4b57425a793565644d554842326d3572792532422532424551772532427a6766347a6f39253246306f634e3357527a4c4277344a2532424a7950574372716d4967475974554f735744346f785a46516f50556a4770564871493425324661666b51504336665a5165654d31253242764c7549516e6a754257514444437363726d485039656f4e5041744271664f6e5875614b25324268364a45624772732532427076764d6d78654962683836336162565065597953456f39464a48704e4d464a59253242503563575a6b6667374f3174537759436553514c54593345385130392532464256504a556c78516a7368543142736343593032723955445542667643484236367063665041336c794165336e6772332532463437584467614a7a736c7937787741364e5a746c555550437541487161536a5549502532427375653842525741432532464e6651374a5a505a35397330476a3756747049537a34685125324243706658474d4b685a63764c70554b7866574d386f68766637702532464f446a4842666356463849736b383267314648796b63564645253242555a414158343761452532464d6c34504f3530506e75683025324678346e6d637957507364774468427836436d6b4c562532466746446a594b784f4a4f4674623077517949684c39527943774b33414f664947703159464542686e4d4a634c525745624b644b516f55366e63545a6b494544696341792532463831645675454d3552775066657934784f7830496b25324649324e6e466b692532425761664f6f464959466367595a43797864376543556a626334416d46363566742532466b4d686b336f25324235686337734d4a79716a4a45477659466151464972375930775077384246415925324236253242766d6b3377367a7a5275444d6d5a5652736668385274413075455453443775434254364459514e36697665553066706b594c6a453671725672744f78654e4b553954484c5a4a396b4255324a427342685635416976422532466f4b61514e4b675043427744596149665a4334616454684f71463457454e56694c4a77566f586f62664c424b56773637414f6154734c6336355461564b32317651344c613939654b6359673576627873624f627a5451394e37554b4467554f3177446a6944494942736868357a746733396e514d4c535a4248344f7a424f55444551586d323036643366634c67737762585141345068634b336e6873775531427a3877765130395248472532466f597933656a6677424e6d746f59714c4130586741414141424a52553545726b4a676767253344253344266c6162656c3d557064617465644174\" alt=\"last-commit\" data-canonical-src=\"https://img.shields.io/github/last-commit/bitnami-labs/sealed-secrets?display_timestamp=committer&amp;logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFHUlEQVR4nLVX7U9aVxwm26dlX%2Fdhbx%2B2%2FQnbkvUbrdUAQgJJIfUDNWDTTmOv1FQUFaPJ4kusrV01Jt1sNpctS2u3botZtmxd9tJSFSoqKqIF5bYDFLCovClefstzJ8wXRLDZLznkcO4557n3d3%2FneZ4rEOQZt1WqF%2B8XFr4%2BfOLEe2joY0zwf8ToyZPvjEgkLY%2Bk0mmrXO6dKinxzGk0fjT0x%2BRyr0UqncYczM1rc4tQ%2BIrp2LGXdo4NC4VvWqTS72wqlc%2Br13ORri6KdXdnbOHLlwlzJpRKn6W4%2BK6poOCNnIAfHj%2F%2BwahIZB4vKnqZf0qJpNIql%2Fv8TU0cNl5rbyc3w0QnTp3y2LTaJ7M1NaxDr2fRn1SpPG6Gia21tfE34TcaOay1iMUVOQFbFYqIWSo1W8TiAVanC0evXOEB7Wp14HFb22zE5fqLOC5ERLQWidNaNI4uEcc9i7hcJldHh2NWrQ5gDdbOlpaumIuLb2atAQDPnz0b8NbWcmxVVRJ3HmxpScwwzOJmKDRGe8LlCZDLG9g7TInV1Ql7dbXbV1e3gT0WKirCFomkPyvwXFlZGJOjV6%2BSt64uudDZOU5EUcox%2FMEQDVvt6MbcN27Y3Ayzhv3spaUrB6Z9qrJSO19ezj8p2pLBkJy%2BcCHJxWI5gW5tcfRRz1dU19GfGkou9PZO4smR9jGFwpex4Dy3bvnmKypotbU13VidjqYZhrj49rvMEt%2F%2FYqLz9d00NjW%2Fczgyo9O51zs6aNlo5FDtu0DZgQFhlGXJ0dBADoNhd6uvp6Whoayg7N9LVGH8mD4b%2FHnftUQoNG4vLQ0gixMqlW%2B4qOjtNHDg3r1f6YiRSGxRy7UvqLb9U4qkqnxPONva5lDpHr1%2ByyKRNKWBZy5edMUHB2m5ry%2B%2BEQw%2Bzgf4zo9%2F0ocN3WRzLBw4J%2BJyPWCrqmIgGYtUOsWD4oxZFQoPUjGpVHqI4%2FafkQPC6fZQeeM1%2BvLuIQnjuBWQDDCscrmHP9eoNPAtBqfOnXuaK%2Bh6JEbGrs%2BpvvMmxeIbh863abVPeYySEo9FJHpNMFJY%2BP5cWZkfg7O1tSwYCeSQLTY3E8Q09%2FBVPJUlxQjshT1BscCY02r9UDUBfvCHB66pcfPA3lyAe3ngr3%2F47XDgaJzsly7xwA6NZtlUUPCuAHqaSjUIP%2Bsue8BRWAC%2FNfQ7JZPZ59s0Gj7VtpISz4hQ%2BCpfXGMKhZcvLpUKxfWM8ohvf7p%2FODjHBfcVF8Isk82g1FHykcVFE%2BUZAAX47aE%2FMl4PO50Pnuh0%2Fx4nmcyWPsdwDhBx6CmkLV%2FgFDjYKxOJOFtb0wQyIhL9RyCwK3AOfIGp1YFEBhnMJcLRWEbKdKQoU6ncTZkIEDicAy%2F81dVuEM5RwPfey4xOx0Ik%2FI2NnFki%2BWafOoFIYFcgYZCyxd7eCUjbc4AmF65ft%2FkMhk3o%2B5hc7sMJyqjJEGvYFaQFIr7Y0wPw8BFAY%2B6%2Bvmk3w6zzRuDMmZVRsfh8RtA0uETSD7uCBT6DYQN6iveU0fpkYLjE6qrVrtOxeNKU9THLZJ9kBU2JBsBhV5AivB%2FoKaQNKgPCBwDYaIfZC4adThOqF4WENViLJwVoXobfLBKVw67AOaTsLc65TaVK21vQ4La99eKcYg5vbxsbObzTQ9N7UKDgUO1wDjiDIIBshh5ztg39nQMLSZBH4OzBOUDEQXm206d3fcLgswbXQA4PhcK3nhswU1Bz8wvQ09RHG%2FoYy3ejfwBNmtoYqLA0XgAAAABJRU5ErkJggg%3D%3D&amp;label=UpdatedAt\" style=\"max-width: 100%;\"></a></td>\n</tr>\n<tr>\n<td align=\"right\"><strong>CreatedAt</strong></td>\n<td align=\"left\"><a href=\"https://github.com/opsre/awesome-ops\"><img src=\"https://camo.githubusercontent.com/ec73531084f6ca1ed9147b1f3353ac9661b353ebbcff5be109c3010b7292516d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f637265617465642d61742f6269746e616d692d6c6162732f7365616c65642d736563726574733f6c6f676f3d64617461253341696d616765253246706e672533426261736536342532436956424f5277304b47676f414141414e5355684555674141414234414141416543415941414141374d4b3669414141414358424957584d41414173544141414c457745416d7077594141414648556c45515652346e4c5658375539615678776d3236646c582532466468627825324232253246516e626b7655627264554151674a4a496655444e574454546d4f76314651554661504a346b7573725630314a7431734e70637453327533626f745a746d786439744a5346536f714b71494635625944464c436f76436c656673747a4a387758524c445a4c7a6e6b634f343535376e3364332532466e655a3472454f515a74315771462532423858467234253242664f4c4565326a6f59307a776638546f795a50766a45676b4c592532426b306d6d72584f36644b696e787a476b30666a5430782532425279723055716e6359637a4d317263347451253242497270324c4758646f344e4334567657715453373277716c632532427231334f527269364b6458646e624f484c6c776c7a4a70524b6e3657342532424b36706f4f434e6e494166486a253246253242776168495a4234764b6e715a6630714a704e49716c2532467638545530634e6c3572627963337730516e54703379324c54614a374d314e617844723266526e315370504736476961323174664533345463614f617931694d55564f5146624659714957536f31573854694156616e43306576584f4542375770313448466232327a453566714c4f433545524c515769644e614e49347545636339693768634a6c644868324e57725135674464624f6c7061756d49754c62326174415144506e7a3062384e6257636d785656524a33486d7870536377777a4f4a6d4b44524765384c6c435a444c4739673754496e5631516c376462586256316533675430574b697243466f6d6b5079767758466c5a474a4f6a563625324253743634757564445a4f55354555636f782532464d455144567674364d62634e3237593341797a687633737061557242365a3971724a534f3139657a6a387032704c426b4a792532426343484a7857493567573574636652527a31645531394766476b6f7539505a4f34736d52396a4746777065783444793362766e6d4b79706f74625531335669646a71595a68726a343972764d457425324625324659714c7a396430304e6a57253246637a67796f394f35317a7336614e6c6f354644747530445a675146686c47584a30644241446f4e6864367576703657686f617967374e394c564748386d443462253246486e667455516f4e4734764c51306769784d716c5725324234714f6a744e48446733723166365969525347785279375576714c62395534716b716e78504f4e7661356c447048723125324279794b524e4b57425a793565644d554842326d3572792532422532424551772532427a6766347a6f39253246306f634e3357527a4c4277344a2532424a7950574372716d4967475974554f735744346f785a46516f50556a4770564871493425324661666b51504336665a5165654d31253242764c7549516e6a754257514444437363726d485039656f4e5041744271664f6e5875614b25324268364a45624772732532427076764d6d78654962683836336162565065597953456f39464a48704e4d464a59253242503563575a6b6667374f3174537759436553514c54593345385130392532464256504a556c78516a7368543142736343593032723955445542667643484236367063665041336c794165336e6772332532463437584467614a7a736c7937787741364e5a746c555550437541487161536a5549502532427375653842525741432532464e6651374a5a505a35397330476a3756747049537a34685125324243706658474d4b685a63764c70554b7866574d386f68766637702532464f446a4842666356463849736b383267314648796b63564645253242555a414158343761452532464d6c34504f3530506e75683025324678346e6d637957507364774468427836436d6b4c562532466746446a594b784f4a4f4674623077517949684c39527943774b33414f664947703159464542686e4d4a634c525745624b644b516f55366e63545a6b494544696341792532463831645675454d3552775066657934784f7830496b25324649324e6e466b692532425761664f6f464959466367595a43797864376543556a626334416d46363566742532466b4d686b336f25324235686337734d4a79716a4a45477659466151464972375930775077384246415925324236253242766d6b3377367a7a5275444d6d5a5652736668385274413075455453443775434254364459514e36697665553066706b594c6a453671725672744f78654e4b553954484c5a4a396b4255324a427342685635416976422532466f4b61514e4b675043427744596149665a4334616454684f71463457454e56694c4a77566f586f62664c424b56773637414f6154734c6336355461564b32317651344c613939654b6359673576627873624f627a5451394e37554b4467554f3177446a6944494942736868357a746733396e514d4c535a4248344f7a424f55444551586d323036643366634c67737762585141345068634b336e6873775531427a3877765130395248472532466f597933656a6677424e6d746f59714c4130586741414141424a52553545726b4a676767253344253344266c6162656c3d437265617465644174\" alt=\"create-at\" data-canonical-src=\"https://img.shields.io/github/created-at/bitnami-labs/sealed-secrets?logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFHUlEQVR4nLVX7U9aVxwm26dlX%2Fdhbx%2B2%2FQnbkvUbrdUAQgJJIfUDNWDTTmOv1FQUFaPJ4kusrV01Jt1sNpctS2u3botZtmxd9tJSFSoqKqIF5bYDFLCovClefstzJ8wXRLDZLznkcO4557n3d3%2FneZ4rEOQZt1WqF%2B8XFr4%2BfOLEe2joY0zwf8ToyZPvjEgkLY%2Bk0mmrXO6dKinxzGk0fjT0x%2BRyr0UqncYczM1rc4tQ%2BIrp2LGXdo4NC4VvWqTS72wqlc%2Br13ORri6KdXdnbOHLlwlzJpRKn6W4%2BK6poOCNnIAfHj%2F%2BwahIZB4vKnqZf0qJpNIql%2Fv8TU0cNl5rbyc3w0QnTp3y2LTaJ7M1NaxDr2fRn1SpPG6Gia21tfE34TcaOay1iMUVOQFbFYqIWSo1W8TiAVanC0evXOEB7Wp14HFb22zE5fqLOC5ERLQWidNaNI4uEcc9i7hcJldHh2NWrQ5gDdbOlpaumIuLb2atAQDPnz0b8NbWcmxVVRJ3HmxpScwwzOJmKDRGe8LlCZDLG9g7TInV1Ql7dbXbV1e3gT0WKirCFomkPyvwXFlZGJOjV6%2BSt64uudDZOU5EUcox%2FMEQDVvt6MbcN27Y3Ayzhv3spaUrB6Z9qrJSO19ezj8p2pLBkJy%2BcCHJxWI5gW5tcfRRz1dU19GfGkou9PZO4smR9jGFwpex4Dy3bvnmKypotbU13VidjqYZhrj49rvMEt%2F%2FYqLz9d00NjW%2Fczgyo9O51zs6aNlo5FDtu0DZgQFhlGXJ0dBADoNhd6uvp6Whoayg7N9LVGH8mD4b%2FHnftUQoNG4vLQ0gixMqlW%2B4qOjtNHDg3r1f6YiRSGxRy7UvqLb9U4qkqnxPONva5lDpHr1%2ByyKRNKWBZy5edMUHB2m5ry%2B%2BEQw%2Bzgf4zo9%2F0ocN3WRzLBw4J%2BJyPWCrqmIgGYtUOsWD4oxZFQoPUjGpVHqI4%2FafkQPC6fZQeeM1%2BvLuIQnjuBWQDDCscrmHP9eoNPAtBqfOnXuaK%2Bh6JEbGrs%2BpvvMmxeIbh863abVPeYySEo9FJHpNMFJY%2BP5cWZkfg7O1tSwYCeSQLTY3E8Q09%2FBVPJUlxQjshT1BscCY02r9UDUBfvCHB66pcfPA3lyAe3ngr3%2F47XDgaJzsly7xwA6NZtlUUPCuAHqaSjUIP%2Bsue8BRWAC%2FNfQ7JZPZ59s0Gj7VtpISz4hQ%2BCpfXGMKhZcvLpUKxfWM8ohvf7p%2FODjHBfcVF8Isk82g1FHykcVFE%2BUZAAX47aE%2FMl4PO50Pnuh0%2Fx4nmcyWPsdwDhBx6CmkLV%2FgFDjYKxOJOFtb0wQyIhL9RyCwK3AOfIGp1YFEBhnMJcLRWEbKdKQoU6ncTZkIEDicAy%2F81dVuEM5RwPfey4xOx0Ik%2FI2NnFki%2BWafOoFIYFcgYZCyxd7eCUjbc4AmF65ft%2FkMhk3o%2B5hc7sMJyqjJEGvYFaQFIr7Y0wPw8BFAY%2B6%2Bvmk3w6zzRuDMmZVRsfh8RtA0uETSD7uCBT6DYQN6iveU0fpkYLjE6qrVrtOxeNKU9THLZJ9kBU2JBsBhV5AivB%2FoKaQNKgPCBwDYaIfZC4adThOqF4WENViLJwVoXobfLBKVw67AOaTsLc65TaVK21vQ4La99eKcYg5vbxsbObzTQ9N7UKDgUO1wDjiDIIBshh5ztg39nQMLSZBH4OzBOUDEQXm206d3fcLgswbXQA4PhcK3nhswU1Bz8wvQ09RHG%2FoYy3ejfwBNmtoYqLA0XgAAAABJRU5ErkJggg%3D%3D&amp;label=CreatedAt\" style=\"max-width: 100%;\"></a></td>\n</tr>\n</tbody>\n</table></markdown-accessiblity-table>\n<a href=\"https://github.com/opsre/awesome-ops\">\n</a><p dir=\"auto\"><a href=\"https://github.com/opsre/awesome-ops\"><img src=\"https://camo.githubusercontent.com/b964a36ea4078c39f603d46a29436371c7541a2f26e0228d7b21b9d9805b43d3/68747470733a2f2f736f6369616c6966792e6769742e63692f6f707372652f617765736f6d652d6f70732f696d6167653f6465736372697074696f6e3d3126666f6e743d42697474657226666f726b733d31266973737565733d31266c616e67756167653d31266c6f676f3d6874747073253341253246253246617661746172732e67697468756275736572636f6e74656e742e636f6d25324675253246313838353638303230266e616d653d31266f776e65723d31267061747465726e3d436972637569742b426f6172642670756c6c733d31267374617267617a6572733d31267468656d653d4c69676874\" alt=\"\" data-canonical-src=\"https://socialify.git.ci/opsre/awesome-ops/image?description=1&amp;font=Bitter&amp;forks=1&amp;issues=1&amp;language=1&amp;logo=https%3A%2F%2Favatars.githubusercontent.com%2Fu%2F188568020&amp;name=1&amp;owner=1&amp;pattern=Circuit+Board&amp;pulls=1&amp;stargazers=1&amp;theme=Light\" style=\"max-width: 100%;\"></a></p>\n<a target=\"_blank\" rel=\"noopener noreferrer nofollow\" href=\"https://camo.githubusercontent.com/a15b413168923d02e21292705ceaf86b92675f98e250c5c896a02ba7504a6eae/68747470733a2f2f63646e2e6a7364656c6976722e6e65742f67682f657279616a662f7475406d61696e2f696d672f696d6167655f32303234303432305f3231343430382e676966\"><img src=\"https://camo.githubusercontent.com/a15b413168923d02e21292705ceaf86b92675f98e250c5c896a02ba7504a6eae/68747470733a2f2f63646e2e6a7364656c6976722e6e65742f67682f657279616a662f7475406d61696e2f696d672f696d6167655f32303234303432305f3231343430382e676966\" width=\"100%\" height=\"3\" data-animated-image=\"\" data-canonical-src=\"https://cdn.jsdelivr.net/gh/eryajf/tu@main/img/image_20240420_214408.gif\" style=\"max-width: 100%; height: auto; max-height: 3px;\"></a>\n</div>\n<h1 dir=\"auto\">\"Sealed Secrets\" for Kubernetes</h1>\n<p dir=\"auto\"><a href=\"#Installation\"><img src=\"https://camo.githubusercontent.com/7bea9a060ed7db92258fec8d3e98bb05db3e2ed5f0b179b3551a605ea0a8b663/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f696e7374616c6c2d646f63732d627269676874677265656e2e737667\" alt=\"\" data-canonical-src=\"https://img.shields.io/badge/install-docs-brightgreen.svg\" style=\"max-width: 100%;\"></a><br>\n<a href=\"https://github.com/bitnami-labs/sealed-secrets/releases/latest\"><img src=\"https://camo.githubusercontent.com/2011657ba9b09ee9cbedf7400f5c9eeacc9afd39fd686c71038faa765edf7874/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652f6269746e616d692d6c6162732f7365616c65642d736563726574732e737667\" alt=\"\" data-canonical-src=\"https://img.shields.io/github/release/bitnami-labs/sealed-secrets.svg\" style=\"max-width: 100%;\"></a><br>\n<a href=\"https://formulae.brew.sh/formula/kubeseal\" rel=\"nofollow\"><img src=\"https://camo.githubusercontent.com/55a2b9ab5f5081a982be5ecd09f05088c951054b068813dd068d572a7e03b9b6/68747470733a2f2f696d672e736869656c64732e696f2f686f6d65627265772f762f6b7562657365616c\" alt=\"\" data-canonical-src=\"https://img.shields.io/homebrew/v/kubeseal\" style=\"max-width: 100%;\"></a><br>\n<a href=\"https://github.com/bitnami-labs/sealed-secrets/actions/workflows/ci.yml\"><img src=\"https://github.com/bitnami-labs/sealed-secrets/actions/workflows/ci.yml/badge.svg\" alt=\"Build Status\" style=\"max-width: 100%;\"></a><br>\n<a href=\"https://github.com/bitnami-labs/sealed-secrets/releases\"><img src=\"https://camo.githubusercontent.com/f05fb23bcb38369df329296a12546d9a761b80f8df8d9f98500b258681f4404e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f6269746e616d692d6c6162732f7365616c65642d736563726574733f696e636c7564655f70726572656c6561736573266c6162656c3d68656c6d26736f72743d73656d766572\" alt=\"\" data-canonical-src=\"https://img.shields.io/github/v/release/bitnami-labs/sealed-secrets?include_prereleases&amp;label=helm&amp;sort=semver\" style=\"max-width: 100%;\"></a><br>\n<a href=\"https://hub.docker.com/r/bitnami/sealed-secrets-controller\" rel=\"nofollow\"><img src=\"https://camo.githubusercontent.com/5230c040c5c2055871dc861acd5b2dd8c57c5e92bea052b4c6152368e7336b15/68747470733a2f2f696d672e736869656c64732e696f2f646f636b65722f70756c6c732f6269746e616d692f7365616c65642d736563726574732d636f6e74726f6c6c65722e737667\" alt=\"Download Status\" data-canonical-src=\"https://img.shields.io/docker/pulls/bitnami/sealed-secrets-controller.svg\" style=\"max-width: 100%;\"></a><br>\n<a href=\"https://goreportcard.com/report/github.com/bitnami-labs/sealed-secrets\" rel=\"nofollow\"><img src=\"https://camo.githubusercontent.com/86d619e4082044ab74373222af0dc5f3dce9978604063bb27fd0221a7ce38a5d/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f6269746e616d692d6c6162732f7365616c65642d73656372657473\" alt=\"Go Report Card\" data-canonical-src=\"https://goreportcard.com/badge/github.com/bitnami-labs/sealed-secrets\" style=\"max-width: 100%;\"></a><br>\n<a target=\"_blank\" rel=\"noopener noreferrer nofollow\" href=\"https://camo.githubusercontent.com/57494adb4f0997535d1798eeb35db77c7a1de20af527554880707774c028fb32/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f646f776e6c6f6164732f6269746e616d692d6c6162732f7365616c65642d736563726574732f746f74616c2e737667\"><img src=\"https://camo.githubusercontent.com/57494adb4f0997535d1798eeb35db77c7a1de20af527554880707774c028fb32/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f646f776e6c6f6164732f6269746e616d692d6c6162732f7365616c65642d736563726574732f746f74616c2e737667\" alt=\"Downloads\" data-canonical-src=\"https://img.shields.io/github/downloads/bitnami-labs/sealed-secrets/total.svg\" style=\"max-width: 100%;\"></a></p>\n<p dir=\"auto\"><strong>Problem:</strong> \"I can manage all my K8s config in git, except Secrets.\"</p>\n<p dir=\"auto\"><strong>Solution:</strong> Encrypt your Secret into a SealedSecret, which <em>is</em> safe<br>\nto store - even inside a public repository. The SealedSecret can be<br>\ndecrypted only by the controller running in the target cluster and<br>\nnobody else (not even the original author) is able to obtain the<br>\noriginal Secret from the SealedSecret.</p>\n\n\n<ul dir=\"auto\">\n<li>\n<p dir=\"auto\"><a href=\"#overview\">Overview</a></p>\n<ul dir=\"auto\">\n<li><a href=\"#sealedsecrets-as-templates-for-secrets\">SealedSecrets as templates for secrets</a></li>\n<li><a href=\"#public-key--certificate\">Public key / Certificate</a></li>\n<li><a href=\"#scopes\">Scopes</a></li>\n</ul>\n</li>\n<li>\n<p dir=\"auto\"><a href=\"#installation\">Installation</a></p>\n<ul dir=\"auto\">\n<li><a href=\"#controller\">Controller</a>\n<ul dir=\"auto\">\n<li><a href=\"#kustomize\">Kustomize</a></li>\n<li><a href=\"#helm-chart\">Helm Chart</a></li>\n</ul>\n</li>\n<li><a href=\"#kubeseal\">Kubeseal</a>\n<ul dir=\"auto\">\n<li><a href=\"#homebrew\">Homebrew</a></li>\n<li><a href=\"#macports\">MacPorts</a></li>\n<li><a href=\"#linux\">Linux</a></li>\n<li><a href=\"#installation-from-source\">Installation from source</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li>\n<p dir=\"auto\"><a href=\"#upgrade\">Upgrade</a></p>\n</li>\n<li>\n<p dir=\"auto\"><a href=\"#usage\">Usage</a></p>\n<ul dir=\"auto\">\n<li><a href=\"#managing-existing-secrets\">Managing existing secrets</a></li>\n<li><a href=\"#patching-existing-secrets\">Patching existing secrets</a></li>\n<li><a href=\"#update-existing-secrets\">Update existing secrets</a></li>\n<li><a href=\"#raw-mode-experimental\">Raw mode (experimental)</a></li>\n<li><a href=\"#validate-a-sealed-secret\">Validate a Sealed Secret</a></li>\n</ul>\n</li>\n<li>\n<p dir=\"auto\"><a href=\"#secret-rotation\">Secret Rotation</a></p>\n<ul dir=\"auto\">\n<li><a href=\"#sealing-key-renewal\">Sealing key renewal</a></li>\n<li><a href=\"#user-secret-rotation\">User secret rotation</a></li>\n<li><a href=\"#early-key-renewal\">Early key renewal</a></li>\n<li><a href=\"#common-misconceptions-about-key-renewal\">Common misconceptions about key renewal</a></li>\n<li><a href=\"#manual-key-management-advanced\">Manual key management (advanced)</a></li>\n<li><a href=\"#re-encryption-advanced\">Re-encryption (advanced)</a></li>\n</ul>\n</li>\n<li>\n<p dir=\"auto\"><a href=\"#details-advanced\">Details (advanced)</a></p>\n<ul dir=\"auto\">\n<li><a href=\"#crypto\">Crypto</a></li>\n</ul>\n</li>\n<li>\n<p dir=\"auto\"><a href=\"#developing\">Developing</a></p>\n</li>\n<li>\n<p dir=\"auto\"><a href=\"#faq\">FAQ</a></p>\n<ul dir=\"auto\">\n<li><a href=\"#will-you-still-be-able-to-decrypt-if-you-no-longer-have-access-to-your-cluster\">Will you still be able to decrypt if you no longer have access to your cluster?</a></li>\n<li><a href=\"#how-can-i-do-a-backup-of-my-sealedsecrets\">How can I do a backup of my SealedSecrets?</a></li>\n<li><a href=\"#can-i-decrypt-my-secrets-offline-with-a-backup-key\">Can I decrypt my secrets offline with a backup key?</a></li>\n<li><a href=\"#what-flags-are-available-for-kubeseal\">What flags are available for kubeseal?</a></li>\n<li><a href=\"#how-do-i-update-parts-of-jsonyamltoml-file-encrypted-with-sealed-secrets\">How do I update parts of JSON/YAML/TOML/.. file encrypted with sealed secrets?</a></li>\n<li><a href=\"#can-i-bring-my-own-pre-generated-certificates\">Can I bring my own (pre-generated) certificates?</a></li>\n<li><a href=\"#how-to-use-kubeseal-if-the-controller-is-not-running-within-the-kube-system-namespace\">How to use kubeseal if the controller is not running within the <code class=\"notranslate\">kube-system</code> namespace?</a></li>\n<li><a href=\"#how-to-verify-the-images\">How to verify the images?</a></li>\n<li><a href=\"#How-to-use-one-controller-for-a-subset-of-namespaces\">How to use one controller for a subset of namespaces</a></li>\n<li><a href=\"#can-i-configure-the-controller-unseal-retries\">Can I configure the controller unseal retries</a></li>\n</ul>\n</li>\n<li>\n<p dir=\"auto\"><a href=\"#community\">Community</a></p>\n<ul dir=\"auto\">\n<li><a href=\"#related-projects\">Related projects</a></li>\n</ul>\n</li>\n</ul>\n\n<h2 dir=\"auto\">Overview</h2>\n<p dir=\"auto\">Sealed Secrets is composed of two parts:</p>\n<ul dir=\"auto\">\n<li>A cluster-side controller / operator</li>\n<li>A client-side utility: <code class=\"notranslate\">kubeseal</code></li>\n</ul>\n<p dir=\"auto\">The <code class=\"notranslate\">kubeseal</code> utility uses asymmetric crypto to encrypt secrets that only the controller can decrypt.</p>\n<p dir=\"auto\">These encrypted secrets are encoded in a <code class=\"notranslate\">SealedSecret</code> resource, which you can see as a recipe for creating<br>\na secret. Here is how it looks:</p>\n<div class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"apiVersion: bitnami.com/v1alpha1\nkind: SealedSecret\nmetadata:\n  name: mysecret\n  namespace: mynamespace\nspec:\n  encryptedData:\n    foo: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq.....\"><pre class=\"notranslate\"><span class=\"pl-ent\">apiVersion</span>: <span class=\"pl-s\">bitnami.com/v1alpha1</span>\n<span class=\"pl-ent\">kind</span>: <span class=\"pl-s\">SealedSecret</span>\n<span class=\"pl-ent\">metadata</span>:\n  <span class=\"pl-ent\">name</span>: <span class=\"pl-s\">mysecret</span>\n  <span class=\"pl-ent\">namespace</span>: <span class=\"pl-s\">mynamespace</span>\n<span class=\"pl-ent\">spec</span>:\n  <span class=\"pl-ent\">encryptedData</span>:\n    <span class=\"pl-ent\">foo</span>: <span class=\"pl-s\">AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq.....</span></pre></div>\n<p dir=\"auto\">Once unsealed this will produce a secret equivalent to this:</p>\n<div class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"apiVersion: v1\nkind: Secret\nmetadata:\n  name: mysecret\n  namespace: mynamespace\ndata:\n  foo: YmFy  # &lt;- base64 encoded &quot;bar&quot;\"><pre class=\"notranslate\"><span class=\"pl-ent\">apiVersion</span>: <span class=\"pl-c1\">v1</span>\n<span class=\"pl-ent\">kind</span>: <span class=\"pl-s\">Secret</span>\n<span class=\"pl-ent\">metadata</span>:\n  <span class=\"pl-ent\">name</span>: <span class=\"pl-s\">mysecret</span>\n  <span class=\"pl-ent\">namespace</span>: <span class=\"pl-s\">mynamespace</span>\n<span class=\"pl-ent\">data</span>:\n  <span class=\"pl-ent\">foo</span>: <span class=\"pl-s\">YmFy  </span><span class=\"pl-c\"><span class=\"pl-c\">#</span> &lt;- base64 encoded \"bar\"</span></pre></div>\n<p dir=\"auto\">This normal <a href=\"https://kubernetes.io/docs/concepts/configuration/secret/\" rel=\"nofollow\">kubernetes secret</a> will appear in the cluster<br>\nafter a few seconds you can use it as you would use any secret that you would have created directly (e.g. reference it from a <code class=\"notranslate\">Pod</code>).</p>\n<p dir=\"auto\">Jump to the <a href=\"#installation\">Installation</a> section to get up and running.</p>\n<p dir=\"auto\">The <a href=\"#usage\">Usage</a> section explores in more detail how you craft <code class=\"notranslate\">SealedSecret</code> resources.</p>\n<h3 dir=\"auto\">SealedSecrets as templates for secrets</h3>\n<p dir=\"auto\">The previous example only focused on the encrypted secret items themselves, but the relationship between a <code class=\"notranslate\">SealedSecret</code> custom resource and the <code class=\"notranslate\">Secret</code> it unseals into is similar in many ways (but not in all of them) to the familiar <code class=\"notranslate\">Deployment</code> vs <code class=\"notranslate\">Pod</code>.</p>\n<p dir=\"auto\">In particular, the annotations and labels of a <code class=\"notranslate\">SealedSecret</code> resource are not the same as the annotations of the <code class=\"notranslate\">Secret</code> that gets generated out of it.</p>\n<p dir=\"auto\">To capture this distinction, the <code class=\"notranslate\">SealedSecret</code> object has a <code class=\"notranslate\">template</code> section which encodes all the fields you want the controller to put in the unsealed <code class=\"notranslate\">Secret</code>.</p>\n<p dir=\"auto\">The <a href=\"https://masterminds.github.io/sprig/\" rel=\"nofollow\">Sprig function library</a> is available (except for <code class=\"notranslate\">env</code>, <code class=\"notranslate\">expandenv</code> and <code class=\"notranslate\">getHostByName</code>) in addition to the default Go Text Template functions.</p>\n<p dir=\"auto\">The <code class=\"notranslate\">metadata</code> block is copied as is (the <code class=\"notranslate\">ownerReference</code> field will be updated <a href=\"#seal-secret-which-can-skip-set-owner-references\">unless disabled</a>).</p>\n<p dir=\"auto\">Other secret fields are handled individually. The <code class=\"notranslate\">type</code> and <code class=\"notranslate\">immutable</code> fields are copied, and the <code class=\"notranslate\">data</code> field can be used to <a href=\"docs/examples/config-template\">template complex values</a> on the <code class=\"notranslate\">Secret</code>. All other fields are currently ignored.</p>\n<div class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"apiVersion: bitnami.com/v1alpha1\nkind: SealedSecret\nmetadata:\n  name: mysecret\n  namespace: mynamespace\n  annotations:\n    &quot;kubectl.kubernetes.io/last-applied-configuration&quot;: ....\nspec:\n  encryptedData:\n    .dockerconfigjson: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq.....\n  template:\n    type: kubernetes.io/dockerconfigjson\n    immutable: true\n    # this is an example of labels and annotations that will be added to the output secret\n    metadata:\n      labels:\n        &quot;jenkins.io/credentials-type&quot;: usernamePassword\n      annotations:\n        &quot;jenkins.io/credentials-description&quot;: credentials from Kubernetes\"><pre class=\"notranslate\"><span class=\"pl-ent\">apiVersion</span>: <span class=\"pl-s\">bitnami.com/v1alpha1</span>\n<span class=\"pl-ent\">kind</span>: <span class=\"pl-s\">SealedSecret</span>\n<span class=\"pl-ent\">metadata</span>:\n  <span class=\"pl-ent\">name</span>: <span class=\"pl-s\">mysecret</span>\n  <span class=\"pl-ent\">namespace</span>: <span class=\"pl-s\">mynamespace</span>\n  <span class=\"pl-ent\">annotations</span>:\n    <span class=\"pl-s\"><span class=\"pl-pds\">\"</span><span class=\"pl-ent\">kubectl.kubernetes.io/last-applied-configuration</span><span class=\"pl-pds\">\"</span></span>: <span class=\"pl-s\">....</span>\n<span class=\"pl-ent\">spec</span>:\n  <span class=\"pl-ent\">encryptedData</span>:\n    <span class=\"pl-ent\">.dockerconfigjson</span>: <span class=\"pl-s\">AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq.....</span>\n  <span class=\"pl-ent\">template</span>:\n    <span class=\"pl-ent\">type</span>: <span class=\"pl-s\">kubernetes.io/dockerconfigjson</span>\n    <span class=\"pl-ent\">immutable</span>: <span class=\"pl-c1\">true</span>\n    <span class=\"pl-c\"><span class=\"pl-c\">#</span> this is an example of labels and annotations that will be added to the output secret</span>\n    <span class=\"pl-ent\">metadata</span>:\n      <span class=\"pl-ent\">labels</span>:\n        <span class=\"pl-s\"><span class=\"pl-pds\">\"</span><span class=\"pl-ent\">jenkins.io/credentials-type</span><span class=\"pl-pds\">\"</span></span>: <span class=\"pl-s\">usernamePassword</span>\n      <span class=\"pl-ent\">annotations</span>:\n        <span class=\"pl-s\"><span class=\"pl-pds\">\"</span><span class=\"pl-ent\">jenkins.io/credentials-description</span><span class=\"pl-pds\">\"</span></span>: <span class=\"pl-s\">credentials from Kubernetes</span></pre></div>\n<p dir=\"auto\">The controller would unseal that into something like:</p>\n<div class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"apiVersion: v1\nkind: Secret\nmetadata:\n  name: mysecret\n  namespace: mynamespace\n  labels:\n    &quot;jenkins.io/credentials-type&quot;: usernamePassword\n  annotations:\n    &quot;jenkins.io/credentials-description&quot;: credentials from Kubernetes\n  ownerReferences:\n  - apiVersion: bitnami.com/v1alpha1\n    controller: true\n    kind: SealedSecret\n    name: mysecret\n    uid: 5caff6a0-c9ac-11e9-881e-42010aac003e\ntype: kubernetes.io/dockerconfigjson\nimmutable: true\ndata:\n  .dockerconfigjson: ewogICJjcmVk...\"><pre class=\"notranslate\"><span class=\"pl-ent\">apiVersion</span>: <span class=\"pl-c1\">v1</span>\n<span class=\"pl-ent\">kind</span>: <span class=\"pl-s\">Secret</span>\n<span class=\"pl-ent\">metadata</span>:\n  <span class=\"pl-ent\">name</span>: <span class=\"pl-s\">mysecret</span>\n  <span class=\"pl-ent\">namespace</span>: <span class=\"pl-s\">mynamespace</span>\n  <span class=\"pl-ent\">labels</span>:\n    <span class=\"pl-s\"><span class=\"pl-pds\">\"</span><span class=\"pl-ent\">jenkins.io/credentials-type</span><span class=\"pl-pds\">\"</span></span>: <span class=\"pl-s\">usernamePassword</span>\n  <span class=\"pl-ent\">annotations</span>:\n    <span class=\"pl-s\"><span class=\"pl-pds\">\"</span><span class=\"pl-ent\">jenkins.io/credentials-description</span><span class=\"pl-pds\">\"</span></span>: <span class=\"pl-s\">credentials from Kubernetes</span>\n  <span class=\"pl-ent\">ownerReferences</span>:\n  - <span class=\"pl-ent\">apiVersion</span>: <span class=\"pl-s\">bitnami.com/v1alpha1</span>\n    <span class=\"pl-ent\">controller</span>: <span class=\"pl-c1\">true</span>\n    <span class=\"pl-ent\">kind</span>: <span class=\"pl-s\">SealedSecret</span>\n    <span class=\"pl-ent\">name</span>: <span class=\"pl-s\">mysecret</span>\n    <span class=\"pl-ent\">uid</span>: <span class=\"pl-s\">5caff6a0-c9ac-11e9-881e-42010aac003e</span>\n<span class=\"pl-ent\">type</span>: <span class=\"pl-s\">kubernetes.io/dockerconfigjson</span>\n<span class=\"pl-ent\">immutable</span>: <span class=\"pl-c1\">true</span>\n<span class=\"pl-ent\">data</span>:\n  <span class=\"pl-ent\">.dockerconfigjson</span>: <span class=\"pl-s\">ewogICJjcmVk...</span></pre></div>\n<p dir=\"auto\">As you can see, the generated <code class=\"notranslate\">Secret</code> resource is a \"dependent object\" of the <code class=\"notranslate\">SealedSecret</code> and as such<br>\nit will be updated and deleted whenever the <code class=\"notranslate\">SealedSecret</code> object gets updated or deleted.</p>\n<h3 dir=\"auto\">Public key / Certificate</h3>\n<p dir=\"auto\">The key certificate (public key portion) is used for sealing secrets,<br>\nand needs to be available wherever <code class=\"notranslate\">kubeseal</code> is going to be<br>\nused. The certificate is not secret information, although you need to<br>\nensure you are using the correct one.</p>\n<p dir=\"auto\"><code class=\"notranslate\">kubeseal</code> will fetch the certificate from the controller at runtime<br>\n(requires secure access to the Kubernetes API server), which is<br>\nconvenient for interactive use, but it's known to be brittle when users<br>\nhave clusters with special configurations such as <a href=\"docs/GKE.md#private-gke-clusters\">private GKE clusters</a> that have<br>\nfirewalls between control plane and nodes.</p>\n<p dir=\"auto\">An alternative workflow<br>\nis to store the certificate somewhere (e.g. local disk) with<br>\n<code class=\"notranslate\">kubeseal --fetch-cert &gt;mycert.pem</code>,<br>\nand use it offline with <code class=\"notranslate\">kubeseal --cert mycert.pem</code>.<br>\nThe certificate is also printed to the controller log on startup.</p>\n<p dir=\"auto\">Since v0.9.x certificates get automatically renewed every 30 days. It's good practice that you and your team<br>\nupdate your offline certificate periodically. To help you with that, since v0.9.2 <code class=\"notranslate\">kubeseal</code> accepts URLs too. You can set up your internal automation to publish certificates somewhere you trust.</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"kubeseal --cert https://your.intranet.company.com/sealed-secrets/your-cluster.cert\"><pre class=\"notranslate\">kubeseal --cert https://your.intranet.company.com/sealed-secrets/your-cluster.cert</pre></div>\n<p dir=\"auto\">It also recognizes the <code class=\"notranslate\">SEALED_SECRETS_CERT</code> env var. (pro-tip: see also <a href=\"https://github.com/direnv/direnv\">direnv</a>).</p>\n<blockquote>\n<p dir=\"auto\"><strong>NOTE</strong>: we are working on providing key management mechanisms that offload the encryption to HSM based modules or managed cloud crypto solutions such as KMS.</p>\n</blockquote>\n<h3 dir=\"auto\">Scopes</h3>\n<p dir=\"auto\">SealedSecrets are from the POV of an end user a \"write only\" device.</p>\n<p dir=\"auto\">The idea is that the SealedSecret can be decrypted only by the controller running in the target cluster and<br>\nnobody else (not even the original author) is able to obtain the original Secret from the SealedSecret.</p>\n<p dir=\"auto\">The user may or may not have direct access to the target cluster.<br>\nMore specifically, the user might or might not have access to the Secret unsealed by the controller.</p>\n<p dir=\"auto\">There are many ways to configure RBAC on k8s, but it's quite common to forbid low-privilege users<br>\nfrom reading Secrets. It's also common to give users one or more namespaces where they have higher privileges,<br>\nwhich would allow them to create and read secrets (and/or create deployments that can reference those secrets).</p>\n<p dir=\"auto\">Encrypted <code class=\"notranslate\">SealedSecret</code> resources are designed to be safe to be looked at without gaining any knowledge about the secrets it conceals. This implies that we cannot allow users to read a SealedSecret meant for a namespace they wouldn't have access to<br>\nand just push a copy of it in a namespace where they can read secrets from.</p>\n<p dir=\"auto\">Sealed-secrets thus behaves <em>as if</em> each namespace had its own independent encryption key and thus once you<br>\nseal a secret for a namespace, it cannot be moved in another namespace and decrypted there.</p>\n<p dir=\"auto\">We don't technically use an independent private key for each namespace, but instead we <em>include</em> the namespace name<br>\nduring the encryption process, effectively achieving the same result.</p>\n<p dir=\"auto\">Furthermore, namespaces are not the only level at which RBAC configurations can decide who can see which secret. In fact, it's possible that users can access a secret called <code class=\"notranslate\">foo</code> in a given namespace but not any other secret in the same namespace. We cannot thus by default let users freely rename <code class=\"notranslate\">SealedSecret</code> resources otherwise a malicious user would be able to decrypt any SealedSecret for that namespace by just renaming it to overwrite the one secret user does have access to. We use the same mechanism used to include the namespace in the encryption key to also include the secret name.</p>\n<p dir=\"auto\">That said, there are many scenarios where you might not care about this level of protection. For example, the only people who have access to your clusters are either admins or they cannot read any <code class=\"notranslate\">Secret</code> resource at all. You might have a use case for moving a sealed secret to other namespaces (e.g. you might not know the namespace name upfront), or you might not know the name of the secret (e.g. it could contain a unique suffix based on the hash of the contents etc).</p>\n<p dir=\"auto\">These are the possible scopes:</p>\n<ul dir=\"auto\">\n<li><code class=\"notranslate\">strict</code> (default): the secret must be sealed with exactly the same <em>name</em> and <em>namespace</em>. These attributes become <em>part of the encrypted data</em> and thus changing name and/or namespace would lead to \"decryption error\".</li>\n<li><code class=\"notranslate\">namespace-wide</code>: you can freely <em>rename</em> the sealed secret within a given namespace.</li>\n<li><code class=\"notranslate\">cluster-wide</code>: the secret can be unsealed in <em>any</em> namespace and can be given <em>any</em> name.</li>\n</ul>\n<p dir=\"auto\">In contrast to the restrictions of <em>name</em> and <em>namespace</em>, secret <em>items</em> (i.e. JSON object keys like <code class=\"notranslate\">spec.encryptedData.my-key</code>) can be renamed at will without losing the ability to decrypt the sealed secret.</p>\n<p dir=\"auto\">The scope is selected with the <code class=\"notranslate\">--scope</code> flag:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"kubeseal --scope cluster-wide &lt;secret.yaml &gt;sealed-secret.json\"><pre class=\"notranslate\">kubeseal --scope cluster-wide <span class=\"pl-k\">&lt;</span>secret.yaml <span class=\"pl-k\">&gt;</span>sealed-secret.json</pre></div>\n<p dir=\"auto\">It's also possible to request a scope via annotations in the input secret you pass to <code class=\"notranslate\">kubeseal</code>:</p>\n<ul dir=\"auto\">\n<li><code class=\"notranslate\">sealedsecrets.bitnami.com/namespace-wide: \"true\"</code> -&gt; for <code class=\"notranslate\">namespace-wide</code></li>\n<li><code class=\"notranslate\">sealedsecrets.bitnami.com/cluster-wide: \"true\"</code> -&gt; for <code class=\"notranslate\">cluster-wide</code></li>\n</ul>\n<p dir=\"auto\">The lack of any of such annotations means <code class=\"notranslate\">strict</code> mode. If both are set, <code class=\"notranslate\">cluster-wide</code> takes precedence.</p>\n<blockquote>\n<p dir=\"auto\">NOTE: Next release will consolidate this into a single <code class=\"notranslate\">sealedsecrets.bitnami.com/scope</code> annotation.</p>\n</blockquote>\n<h2 dir=\"auto\">Installation</h2>\n<p dir=\"auto\">See <a href=\"https://github.com/bitnami-labs/sealed-secrets/releases\">https://github.com/bitnami-labs/sealed-secrets/releases</a> for the latest release and detailed installation instructions.</p>\n<p dir=\"auto\">Cloud platform specific notes and instructions:</p>\n<ul dir=\"auto\">\n<li><a href=\"docs/GKE.md\">GKE</a></li>\n</ul>\n<h3 dir=\"auto\">Controller</h3>\n<p dir=\"auto\">Once you deploy the manifest it will create the <code class=\"notranslate\">SealedSecret</code> resource<br>\nand install the controller into <code class=\"notranslate\">kube-system</code> namespace, create a service<br>\naccount and necessary RBAC roles.</p>\n<p dir=\"auto\">After a few moments, the controller will start, generate a key pair,<br>\nand be ready for operation. If it does not, check the controller logs.</p>\n<h4 dir=\"auto\">Kustomize</h4>\n<p dir=\"auto\">The official controller manifest installation mechanism is just a YAML file.</p>\n<p dir=\"auto\">In some cases you might need to apply your own customizations, like set a custom namespace or set some env variables.</p>\n<p dir=\"auto\"><code class=\"notranslate\">kubectl</code> has native support for that, see <a href=\"https://kustomize.io/\" rel=\"nofollow\">kustomize</a>.</p>\n<h4 dir=\"auto\">Helm Chart</h4>\n<p dir=\"auto\">The Sealed Secrets helm chart is now officially supported and hosted in this GitHub repo.</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets\"><pre class=\"notranslate\">helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets</pre></div>\n<blockquote>\n<p dir=\"auto\">NOTE: The versioning scheme of the helm chart differs from the versioning scheme of the sealed secrets project itself.</p>\n</blockquote>\n<p dir=\"auto\">Originally the helm chart was maintained by the community and the first version adopted a major version of 1 while the<br>\nsealed secrets project itself is still at major 0.<br>\nThis is ok because the version of the helm chart itself is not meant to be necessarily the version of the app itself.<br>\nHowever this is confusing, so our current versioning rule is:</p>\n<ol dir=\"auto\">\n<li>The <code class=\"notranslate\">SealedSecret</code> controller version scheme: 0.X.Y</li>\n<li>The helm chart version scheme: 1.X.Y-rZ</li>\n</ol>\n<p dir=\"auto\">There can be thus multiple revisions of the helm chart, with fixes that apply only to the helm chart without<br>\naffecting the static YAML manifests or the controller image itself.</p>\n<blockquote>\n<p dir=\"auto\">NOTE: The helm chart readme still contains a deprecation notice, but it no longer reflects reality and will be removed upon the next release.</p>\n</blockquote>\n<blockquote>\n<p dir=\"auto\">NOTE: The helm chart by default installs the controller with the name <code class=\"notranslate\">sealed-secrets</code>, while the <code class=\"notranslate\">kubeseal</code> command line interface (CLI) tries to access the controller with the name <code class=\"notranslate\">sealed-secrets-controller</code>. You can explicitly pass <code class=\"notranslate\">--controller-name</code> to the CLI:</p>\n</blockquote>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"kubeseal --controller-name sealed-secrets &lt;args&gt;\"><pre class=\"notranslate\">kubeseal --controller-name sealed-secrets <span class=\"pl-k\">&lt;</span>args<span class=\"pl-k\">&gt;</span></pre></div>\n<p dir=\"auto\">Alternatively, you can set <code class=\"notranslate\">fullnameOverride</code> when installing the chart to override the name. Note also that <code class=\"notranslate\">kubeseal</code> assumes that the controller is installed within the <code class=\"notranslate\">kube-system</code> namespace by default. So if you want to use the <code class=\"notranslate\">kubeseal</code> CLI without having to pass the expected controller name and namespace you should install the Helm Chart like this:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"helm install sealed-secrets -n kube-system --set-string fullnameOverride=sealed-secrets-controller sealed-secrets/sealed-secrets\"><pre class=\"notranslate\">helm install sealed-secrets -n kube-system --set-string fullnameOverride=sealed-secrets-controller sealed-secrets/sealed-secrets</pre></div>\n<h5 dir=\"auto\">Helm Chart on a restricted environment</h5>\n<p dir=\"auto\">In some companies you might be given access only to a single namespace, not a full cluster.</p>\n<p dir=\"auto\">One of the most restrictive environments you can encounter is:</p>\n<ul dir=\"auto\">\n<li>A <code class=\"notranslate\">namespace</code> was allocated to you with some <code class=\"notranslate\">service account</code>.</li>\n<li>You do not have access to the rest of the cluster, not even cluster CRDs.</li>\n<li>You may not even be able to create further service accounts or roles in your namespace.</li>\n<li>You are required to include resource limits in all your deployments.</li>\n</ul>\n<p dir=\"auto\">Even with these restrictions you can still install the sealed secrets Helm Chart, there is only one pre-requisite:</p>\n<ul dir=\"auto\">\n<li><em>The cluster must already have the sealed secrets CRDs installed</em>.</li>\n</ul>\n<p dir=\"auto\">Once your admins installed the CRDs, if they were not there already, you can install the chart by preparing a YAML config file such as this:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"serviceAccount:\n  create: false\n  name: {allocated-service-account}\nrbac:\n  create: false\n  clusterRole: false\nresources:\n  limits:\n    cpu: 150m\n    memory: 256Mi\"><pre class=\"notranslate\">serviceAccount:\n  create: <span class=\"pl-c1\">false</span>\n  name: {allocated-service-account}\nrbac:\n  create: <span class=\"pl-c1\">false</span>\n  clusterRole: <span class=\"pl-c1\">false</span>\nresources:\n  limits:\n    cpu: 150m\n    memory: 256Mi</pre></div>\n<p dir=\"auto\">Note that:</p>\n<ul dir=\"auto\">\n<li>No service accounts are created, instead the one allocated to you will be used.\n<ul dir=\"auto\">\n<li><code class=\"notranslate\">{allocated-service-account}</code> is the name of the <code class=\"notranslate\">service account</code> you were allocated on the cluster.</li>\n</ul>\n</li>\n<li>No RBAC roles are created neither in the namespace nor the cluster.</li>\n<li>Resource limits must be specified.\n<ul dir=\"auto\">\n<li>The limits are samples that should work, but you might want to review them in your particular setup.</li>\n</ul>\n</li>\n</ul>\n<p dir=\"auto\">Once that file is ready, if you named it <code class=\"notranslate\">config.yaml</code> you now can install the sealed secrets Helm Chart like this:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"helm install sealed-secrets -n {allocated-namespace} sealed-secrets/sealed-secrets --skip-crds -f config.yaml\"><pre class=\"notranslate\">helm install sealed-secrets -n {allocated-namespace} sealed-secrets/sealed-secrets --skip-crds -f config.yaml</pre></div>\n<p dir=\"auto\">Where <code class=\"notranslate\">{allocated-namespace}</code> is the name of the <code class=\"notranslate\">namespace</code> you were allocated in the cluster.</p>\n<h3 dir=\"auto\">Kubeseal</h3>\n<h4 dir=\"auto\">Homebrew</h4>\n<p dir=\"auto\">The <code class=\"notranslate\">kubeseal</code> client is also available on <a href=\"https://formulae.brew.sh/formula/kubeseal\" rel=\"nofollow\">homebrew</a>:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"brew install kubeseal\"><pre class=\"notranslate\">brew install kubeseal</pre></div>\n<h4 dir=\"auto\">MacPorts</h4>\n<p dir=\"auto\">The <code class=\"notranslate\">kubeseal</code> client is also available on <a href=\"https://ports.macports.org/port/kubeseal/summary\" rel=\"nofollow\">MacPorts</a>:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"port install kubeseal\"><pre class=\"notranslate\">port install kubeseal</pre></div>\n<h4 dir=\"auto\">Nixpkgs</h4>\n<p dir=\"auto\">The <code class=\"notranslate\">kubeseal</code> client is also available on <a href=\"https://search.nixos.org/packages?channel=unstable&amp;show=kubeseal&amp;from=0&amp;size=50&amp;sort=relevance&amp;type=packages&amp;query=kubeseal\" rel=\"nofollow\">Nixpkgs</a>: (<strong>DISCLAIMER</strong>: Not maintained by bitnami-labs)</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"nix-env -iA nixpkgs.kubeseal\"><pre class=\"notranslate\">nix-env -iA nixpkgs.kubeseal</pre></div>\n<h4 dir=\"auto\">Linux</h4>\n<p dir=\"auto\">The <code class=\"notranslate\">kubeseal</code> client can be installed on Linux, using the below commands:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"KUBESEAL_VERSION='' # Set this to, for example, KUBESEAL_VERSION='0.23.0'\ncurl -OL &quot;https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION:?}/kubeseal-${KUBESEAL_VERSION:?}-linux-amd64.tar.gz&quot;\ntar -xvzf kubeseal-${KUBESEAL_VERSION:?}-linux-amd64.tar.gz kubeseal\nsudo install -m 755 kubeseal /usr/local/bin/kubeseal\"><pre class=\"notranslate\">KUBESEAL_VERSION=<span class=\"pl-s\"><span class=\"pl-pds\">'</span><span class=\"pl-pds\">'</span></span> <span class=\"pl-c\"><span class=\"pl-c\">#</span> Set this to, for example, KUBESEAL_VERSION='0.23.0'</span>\ncurl -OL <span class=\"pl-s\"><span class=\"pl-pds\">\"</span>https://github.com/bitnami-labs/sealed-secrets/releases/download/v<span class=\"pl-smi\">${KUBESEAL_VERSION<span class=\"pl-k\">:?</span>}</span>/kubeseal-<span class=\"pl-smi\">${KUBESEAL_VERSION<span class=\"pl-k\">:?</span>}</span>-linux-amd64.tar.gz<span class=\"pl-pds\">\"</span></span>\ntar -xvzf kubeseal-<span class=\"pl-smi\">${KUBESEAL_VERSION<span class=\"pl-k\">:?</span>}</span>-linux-amd64.tar.gz kubeseal\nsudo install -m 755 kubeseal /usr/local/bin/kubeseal</pre></div>\n<p dir=\"auto\">If you have <code class=\"notranslate\">curl</code> and <code class=\"notranslate\">jq</code> installed on your machine, you can get the version dynamically this way. This can be useful for environments used in automation and such.</p>\n<div class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"# Fetch the latest sealed-secrets version using GitHub API\nKUBESEAL_VERSION=$(curl -s https://api.github.com/repos/bitnami-labs/sealed-secrets/tags | jq -r '.[0].name' | cut -c 2-)\n\n# Check if the version was fetched successfully\nif [ -z &quot;$KUBESEAL_VERSION&quot; ]; then\n    echo &quot;Failed to fetch the latest KUBESEAL_VERSION&quot;\n    exit 1\nfi\n\ncurl -OL &quot;https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION}/kubeseal-${KUBESEAL_VERSION}-linux-amd64.tar.gz&quot;\ntar -xvzf kubeseal-${KUBESEAL_VERSION}-linux-amd64.tar.gz kubeseal\nsudo install -m 755 kubeseal /usr/local/bin/kubeseal\"><pre class=\"notranslate\"><code class=\"notranslate\"># Fetch the latest sealed-secrets version using GitHub API\nKUBESEAL_VERSION=$(curl -s https://api.github.com/repos/bitnami-labs/sealed-secrets/tags | jq -r '.[0].name' | cut -c 2-)\n\n# Check if the version was fetched successfully\nif [ -z \"$KUBESEAL_VERSION\" ]; then\n    echo \"Failed to fetch the latest KUBESEAL_VERSION\"\n    exit 1\nfi\n\ncurl -OL \"https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION}/kubeseal-${KUBESEAL_VERSION}-linux-amd64.tar.gz\"\ntar -xvzf kubeseal-${KUBESEAL_VERSION}-linux-amd64.tar.gz kubeseal\nsudo install -m 755 kubeseal /usr/local/bin/kubeseal\n</code></pre></div>\n<p dir=\"auto\">where <code class=\"notranslate\">KUBESEAL_VERSION</code> is the <a href=\"https://github.com/bitnami-labs/sealed-secrets/tags\">version tag</a> of the kubeseal release you want to use. For example: <code class=\"notranslate\">v0.18.0</code>.</p>\n<h4 dir=\"auto\">Installation from source</h4>\n<p dir=\"auto\">If you just want the latest client tool, it can be installed into<br>\n<code class=\"notranslate\">$GOPATH/bin</code> with:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"go install github.com/bitnami-labs/sealed-secrets/cmd/kubeseal@main\"><pre class=\"notranslate\">go install github.com/bitnami-labs/sealed-secrets/cmd/kubeseal@main</pre></div>\n<p dir=\"auto\">You can specify a release tag or a commit SHA instead of <code class=\"notranslate\">main</code>.</p>\n<p dir=\"auto\">The <code class=\"notranslate\">go install</code> command will place the <code class=\"notranslate\">kubeseal</code> binary at <code class=\"notranslate\">$GOPATH/bin</code>:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"$(go env GOPATH)/bin/kubeseal\"><pre class=\"notranslate\"><span class=\"pl-s\"><span class=\"pl-pds\">$(</span>go env GOPATH<span class=\"pl-pds\">)</span></span>/bin/kubeseal</pre></div>\n<h2 dir=\"auto\">Upgrade</h2>\n<p dir=\"auto\">Don't forget to check the <a href=\"RELEASE-NOTES.md\">release notes</a> for guidance about<br>\npossible breaking changes when you upgrade the client tool<br>\nand/or the controller.</p>\n<h3 dir=\"auto\">Supported Versions</h3>\n<p dir=\"auto\">Currently, only the latest version of Sealed Secrets is supported for production environments.</p>\n<h3 dir=\"auto\">Compatibility with Kubernetes versions</h3>\n<p dir=\"auto\">The Sealed Secrets controller ensures compatibility with different versions of Kubernetes by relying on a stable Kubernetes API. Typically, Kubernetes versions above 1.16 are considered compatible. However, we officially support the <a href=\"https://kubernetes.io/releases/\" rel=\"nofollow\">currently recommended Kubernetes versions</a>. Additionally, versions above 1.24 undergo thorough verification through our CI process with every release.</p>\n<h2 dir=\"auto\">Usage</h2>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# Create a json/yaml-encoded Secret somehow:\n# (note use of `--dry-run` - this is just a local file!)\necho -n bar | kubectl create secret generic mysecret --dry-run=client --from-file=foo=/dev/stdin -o json &gt;mysecret.json\n\n# This is the important bit:\nkubeseal -f mysecret.json -w mysealedsecret.json\n\n# At this point mysealedsecret.json is safe to upload to Github,\n# post on Twitter, etc.\n\n# Eventually:\nkubectl create -f mysealedsecret.json\n\n# Profit!\nkubectl get secret mysecret\"><pre class=\"notranslate\"><span class=\"pl-c\"><span class=\"pl-c\">#</span> Create a json/yaml-encoded Secret somehow:</span>\n<span class=\"pl-c\"><span class=\"pl-c\">#</span> (note use of `--dry-run` - this is just a local file!)</span>\n<span class=\"pl-c1\">echo</span> -n bar <span class=\"pl-k\">|</span> kubectl create secret generic mysecret --dry-run=client --from-file=foo=/dev/stdin -o json <span class=\"pl-k\">&gt;</span>mysecret.json\n\n<span class=\"pl-c\"><span class=\"pl-c\">#</span> This is the important bit:</span>\nkubeseal -f mysecret.json -w mysealedsecret.json\n\n<span class=\"pl-c\"><span class=\"pl-c\">#</span> At this point mysealedsecret.json is safe to upload to Github,</span>\n<span class=\"pl-c\"><span class=\"pl-c\">#</span> post on Twitter, etc.</span>\n\n<span class=\"pl-c\"><span class=\"pl-c\">#</span> Eventually:</span>\nkubectl create -f mysealedsecret.json\n\n<span class=\"pl-c\"><span class=\"pl-c\">#</span> Profit!</span>\nkubectl get secret mysecret</pre></div>\n<p dir=\"auto\">Note the <code class=\"notranslate\">SealedSecret</code> and <code class=\"notranslate\">Secret</code> must have <strong>the same namespace and<br>\nname</strong>. This is a feature to prevent other users on the same cluster<br>\nfrom re-using your sealed secrets. See the <a href=\"#scopes\">Scopes</a> section for more info.</p>\n<p dir=\"auto\"><code class=\"notranslate\">kubeseal</code> reads the namespace from the input secret, accepts an explicit <code class=\"notranslate\">--namespace</code> argument, and uses<br>\nthe <code class=\"notranslate\">kubectl</code> default namespace (in that order). Any labels,<br>\nannotations, etc on the original <code class=\"notranslate\">Secret</code> are preserved, but not<br>\nautomatically reflected in the <code class=\"notranslate\">SealedSecret</code>.</p>\n<p dir=\"auto\">By design, this scheme <em>does not authenticate the user</em>. In other<br>\nwords, <em>anyone</em> can create a <code class=\"notranslate\">SealedSecret</code> containing any <code class=\"notranslate\">Secret</code><br>\nthey like (provided the namespace/name matches). It is up to your<br>\nexisting config management workflow, cluster RBAC rules, etc to ensure<br>\nthat only the intended <code class=\"notranslate\">SealedSecret</code> is uploaded to the cluster. The<br>\nonly change from existing Kubernetes is that the <em>contents</em> of the<br>\n<code class=\"notranslate\">Secret</code> are now hidden while outside the cluster.</p>\n<h3 dir=\"auto\">Managing existing secrets</h3>\n<p dir=\"auto\">If you want the Sealed Secrets controller to manage an existing <code class=\"notranslate\">Secret</code>, you can annotate your <code class=\"notranslate\">Secret</code> with the <code class=\"notranslate\">sealedsecrets.bitnami.com/managed: \"true\"</code> annotation. The existing <code class=\"notranslate\">Secret</code> will be overwritten when unsealing a <code class=\"notranslate\">SealedSecret</code> with the same name and namespace, and the <code class=\"notranslate\">SealedSecret</code> will take ownership of the <code class=\"notranslate\">Secret</code> (so that when the <code class=\"notranslate\">SealedSecret</code> is deleted the <code class=\"notranslate\">Secret</code> will also be deleted).</p>\n<h3 dir=\"auto\">Patching existing secrets</h3>\n<blockquote>\n<p dir=\"auto\">New in v0.23.0</p>\n</blockquote>\n<p dir=\"auto\">There are some use cases in which you don't want to replace the whole <code class=\"notranslate\">Secret</code> but just add or modify some keys from the existing <code class=\"notranslate\">Secret</code>. For this, you can annotate your <code class=\"notranslate\">Secret</code> with <code class=\"notranslate\">sealedsecrets.bitnami.com/patch: \"true\"</code>. Using this annotation will make sure that secret keys, labels and annotations in the <code class=\"notranslate\">Secret</code> that are not present in the <code class=\"notranslate\">SealedSecret</code> won't be deleted, and those present in the <code class=\"notranslate\">SealedSecret</code> will be added to the <code class=\"notranslate\">Secret</code> (secret keys, labels and annotations that exist both in the <code class=\"notranslate\">Secret</code> and the <code class=\"notranslate\">SealedSecret</code> will be modified by the <code class=\"notranslate\">SealedSecret</code>).</p>\n<p dir=\"auto\">This annotation does not make the <code class=\"notranslate\">SealedSecret</code> take ownership of the <code class=\"notranslate\">Secret</code>. You can add both the <code class=\"notranslate\">patch</code> and <code class=\"notranslate\">managed</code> annotations to obtain the patching behavior while also taking ownership of the <code class=\"notranslate\">Secret</code>.</p>\n<h3 dir=\"auto\">Seal secret which can skip set owner references</h3>\n<p dir=\"auto\">If you want <code class=\"notranslate\">SealedSecret</code> and the <code class=\"notranslate\">Secret</code> to be independent, which mean when you delete the <code class=\"notranslate\">SealedSecret</code> the <code class=\"notranslate\">Secret</code> won't disappear with it, then you have to annotate that Secret with the annotation <code class=\"notranslate\">sealedsecrets.bitnami.com/skip-set-owner-references: \"true\"</code> ahead of applying the Usage steps. You still may also add <code class=\"notranslate\">sealedsecrets.bitnami.com/managed: \"true\"</code> to your <code class=\"notranslate\">Secret</code> so that your secret will be updated when <code class=\"notranslate\">SealedSecret</code> is updated.</p>\n<h3 dir=\"auto\">Update existing secrets</h3>\n<p dir=\"auto\">If you want to add or update existing sealed secrets without having the cleartext for the other items,<br>\nyou can just copy&amp;paste the new encrypted data items and merge it into an existing sealed secret.</p>\n<p dir=\"auto\">You must take care of sealing the updated items with a compatible name and namespace (see note about scopes above).</p>\n<p dir=\"auto\">You can use the <code class=\"notranslate\">--merge-into</code> command to update an existing sealed secrets if you don't want to copy&amp;paste:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"echo -n bar | kubectl create secret generic mysecret --dry-run=client --from-file=foo=/dev/stdin -o json \\\n  | kubeseal &gt; mysealedsecret.json\necho -n baz | kubectl create secret generic mysecret --dry-run=client --from-file=bar=/dev/stdin -o json \\\n  | kubeseal --merge-into mysealedsecret.json\"><pre class=\"notranslate\"><span class=\"pl-c1\">echo</span> -n bar <span class=\"pl-k\">|</span> kubectl create secret generic mysecret --dry-run=client --from-file=foo=/dev/stdin -o json \\\n  <span class=\"pl-k\">|</span> kubeseal <span class=\"pl-k\">&gt;</span> mysealedsecret.json\n<span class=\"pl-c1\">echo</span> -n baz <span class=\"pl-k\">|</span> kubectl create secret generic mysecret --dry-run=client --from-file=bar=/dev/stdin -o json \\\n  <span class=\"pl-k\">|</span> kubeseal --merge-into mysealedsecret.json</pre></div>\n<h3 dir=\"auto\">Raw mode (experimental)</h3>\n<p dir=\"auto\">Creating temporary Secret with the <code class=\"notranslate\">kubectl</code> command, only to throw it away once piped to <code class=\"notranslate\">kubeseal</code> can<br>\nbe a quite unfriendly user experience. We're working on an overhaul of the CLI experience. In the meantime,<br>\nwe offer an alternative mode where kubeseal only cares about encrypting a value to stdout, and it's your responsibility to put it inside a <code class=\"notranslate\">SealedSecret</code> resource (not unlike any of the other k8s resources).</p>\n<p dir=\"auto\">It can also be useful as a building block for editor/IDE integrations.</p>\n<p dir=\"auto\">The downside is that you have to be careful to be consistent with the sealing scope, the namespace and the name.</p>\n<p dir=\"auto\">See <a href=\"#scopes\">Scopes</a></p>\n<p dir=\"auto\"><code class=\"notranslate\">strict</code> scope (default):</p>\n<div class=\"highlight highlight-text-shell-session notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"$ echo -n foo | kubeseal --raw --namespace bar --name mysecret\nAgBChHUWLMx...\"><pre class=\"notranslate\">$ <span class=\"pl-s1\"><span class=\"pl-c1\">echo</span> -n foo <span class=\"pl-k\">|</span> kubeseal --raw --namespace bar --name mysecret</span>\n<span class=\"pl-c1\">AgBChHUWLMx...</span></pre></div>\n<p dir=\"auto\"><code class=\"notranslate\">namespace-wide</code> scope:</p>\n<div class=\"highlight highlight-text-shell-session notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"$ echo -n foo | kubeseal --raw --namespace bar --scope namespace-wide\nAgAbbFNkM54...\"><pre class=\"notranslate\">$ <span class=\"pl-s1\"><span class=\"pl-c1\">echo</span> -n foo <span class=\"pl-k\">|</span> kubeseal --raw --namespace bar --scope namespace-wide</span>\n<span class=\"pl-c1\">AgAbbFNkM54...</span></pre></div>\n<p dir=\"auto\">Include the <code class=\"notranslate\">sealedsecrets.bitnami.com/namespace-wide</code> annotation in the <code class=\"notranslate\">SealedSecret</code></p>\n<div class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"metadata:\n  annotations:\n    sealedsecrets.bitnami.com/namespace-wide: &quot;true&quot;\"><pre class=\"notranslate\"><span class=\"pl-ent\">metadata</span>:\n  <span class=\"pl-ent\">annotations</span>:\n    <span class=\"pl-ent\">sealedsecrets.bitnami.com/namespace-wide</span>: <span class=\"pl-s\"><span class=\"pl-pds\">\"</span>true<span class=\"pl-pds\">\"</span></span></pre></div>\n<p dir=\"auto\"><code class=\"notranslate\">cluster-wide</code> scope:</p>\n<div class=\"highlight highlight-text-shell-session notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"$ echo -n foo | kubeseal --raw --scope cluster-wide\nAgAjLKpIYV+...\"><pre class=\"notranslate\">$ <span class=\"pl-s1\"><span class=\"pl-c1\">echo</span> -n foo <span class=\"pl-k\">|</span> kubeseal --raw --scope cluster-wide</span>\n<span class=\"pl-c1\">AgAjLKpIYV+...</span></pre></div>\n<p dir=\"auto\">Include the <code class=\"notranslate\">sealedsecrets.bitnami.com/cluster-wide</code> annotation in the <code class=\"notranslate\">SealedSecret</code></p>\n<div class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"metadata:\n  annotations:\n    sealedsecrets.bitnami.com/cluster-wide: &quot;true&quot;\"><pre class=\"notranslate\"><span class=\"pl-ent\">metadata</span>:\n  <span class=\"pl-ent\">annotations</span>:\n    <span class=\"pl-ent\">sealedsecrets.bitnami.com/cluster-wide</span>: <span class=\"pl-s\"><span class=\"pl-pds\">\"</span>true<span class=\"pl-pds\">\"</span></span></pre></div>\n<h3 dir=\"auto\">Validate a Sealed Secret</h3>\n<p dir=\"auto\">If you want to validate an existing sealed secret, <code class=\"notranslate\">kubeseal</code> has the flag <code class=\"notranslate\">--validate</code> to help you.</p>\n<p dir=\"auto\">Giving a file named <code class=\"notranslate\">sealed-secrets.yaml</code> containing the following sealed secret:</p>\n<div class=\"highlight highlight-source-yaml notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"apiVersion: bitnami.com/v1alpha1\nkind: SealedSecret\nmetadata:\n  name: mysecret\n  namespace: mynamespace\nspec:\n  encryptedData:\n    foo: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq.....\"><pre class=\"notranslate\"><span class=\"pl-ent\">apiVersion</span>: <span class=\"pl-s\">bitnami.com/v1alpha1</span>\n<span class=\"pl-ent\">kind</span>: <span class=\"pl-s\">SealedSecret</span>\n<span class=\"pl-ent\">metadata</span>:\n  <span class=\"pl-ent\">name</span>: <span class=\"pl-s\">mysecret</span>\n  <span class=\"pl-ent\">namespace</span>: <span class=\"pl-s\">mynamespace</span>\n<span class=\"pl-ent\">spec</span>:\n  <span class=\"pl-ent\">encryptedData</span>:\n    <span class=\"pl-ent\">foo</span>: <span class=\"pl-s\">AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq.....</span></pre></div>\n<p dir=\"auto\">You can validate if the sealed secret was properly created or not:</p>\n<div class=\"highlight highlight-text-shell-session notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"$ cat sealed-secrets.yaml | kubeseal --validate\"><pre class=\"notranslate\">$ <span class=\"pl-s1\">cat sealed-secrets.yaml <span class=\"pl-k\">|</span> kubeseal --validate</span></pre></div>\n<p dir=\"auto\">In case of an invalid sealed secret, <code class=\"notranslate\">kubeseal</code> will show:</p>\n<div class=\"highlight highlight-text-shell-session notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"$ cat sealed-secrets.yaml | kubeseal --validate\nerror: unable to decrypt sealed secret\"><pre class=\"notranslate\">$ <span class=\"pl-s1\">cat sealed-secrets.yaml <span class=\"pl-k\">|</span> kubeseal --validate</span>\n<span class=\"pl-c1\">error: unable to decrypt sealed secret</span></pre></div>\n<h2 dir=\"auto\">Secret Rotation</h2>\n<p dir=\"auto\">You should always rotate your secrets. But since your secrets are encrypted with another secret,<br>\nyou need to understand how these two layers relate to take the right decisions.</p>\n<p dir=\"auto\">TL;DR:</p>\n<blockquote>\n<p dir=\"auto\">If a <em>sealing</em> private key is compromised, you need to follow the instructions below in \"Early key renewal\"<br>\nsection before rotating any of your actual secret values.</p>\n<p dir=\"auto\">SealedSecret key renewal and re-encryption features are <strong>not a substitute</strong> for periodical rotation of your actual secret values.</p>\n</blockquote>\n<h3 dir=\"auto\">Sealing key renewal</h3>\n<p dir=\"auto\">Sealing keys are automatically renewed every 30 days. Which means a new sealing key is created and appended to the set of active sealing keys the controller can use to unseal <code class=\"notranslate\">SealedSecret</code> resources.</p>\n<p dir=\"auto\">The most recently created sealing key is the one used to seal new secrets when you use <code class=\"notranslate\">kubeseal</code> and it's the one whose certificate is downloaded when you use <code class=\"notranslate\">kubeseal --fetch-cert</code>.</p>\n<p dir=\"auto\">The renewal time of 30 days is a reasonable default, but it can be tweaked as needed<br>\nwith the <code class=\"notranslate\">--key-renew-period=&lt;value&gt;</code> flag for the command in the pod template of the <code class=\"notranslate\">SealedSecret</code> controller. The <code class=\"notranslate\">value</code> field can be given as golang<br>\nduration flag (eg: <code class=\"notranslate\">720h30m</code>). Assuming that you've installed Sealed Secrets into the <code class=\"notranslate\">kube-system</code> namespace, use the following command to edit the Deployment controller, and add the <code class=\"notranslate\">--key-renew-period</code> parameter. Once you close your text editor, and the Deployment controller has been modified, a new Pod will be automatically created to replace the old Pod.</p>\n<div class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"kubectl edit deployment/sealed-secrets-controller --namespace=kube-system\"><pre class=\"notranslate\"><code class=\"notranslate\">kubectl edit deployment/sealed-secrets-controller --namespace=kube-system\n</code></pre></div>\n<p dir=\"auto\">A value of <code class=\"notranslate\">0</code> will deactivate automatic key renewal. Of course, you may have a valid use case for deactivating automatic sealing key renewal but experience has shown that new users often tend to jump to conclusions that they want control over key renewal, before fully understanding how sealed secrets work. Read more about this in the <a href=\"#common-misconceptions-about-key-renewal\">common misconceptions</a> section below.</p>\n<blockquote>\n<p dir=\"auto\">Unfortunately, you cannot use e.g. \"d\" as a unit for days because that's not supported by the Go stdlib. Instead of hitting your face with a palm, take this as an opportunity to meditate on the <a href=\"https://infiniteundo.com/post/25326999628/falsehoods-programmers-believe-about-time\" rel=\"nofollow\">falsehoods programmers believe about time</a>.</p>\n</blockquote>\n<p dir=\"auto\">A common misunderstanding is that key renewal is often thought of as a form of key rotation, where the old key is not only obsolete but actually bad and that you thus want to get rid of it.<br>\nIt doesn't help that this feature has been historically called \"key rotation\", which can add to the confusion.</p>\n<p dir=\"auto\">Sealed secrets are not automatically rotated and old keys are not deleted<br>\nwhen new keys are generated. Old <code class=\"notranslate\">SealedSecret</code> resources can be still decrypted (that's because old sealing keys are not deleted).</p>\n<h3 dir=\"auto\">Key registry init priority order</h3>\n<p dir=\"auto\">When the controller starts, it will initialize the key registry. The most recent key is used to seal secrets. By default, this certificate is chosen based on the NotBefore attribute of the certificate. If you want to change the priority order of the keys in the registry, you can use the <code class=\"notranslate\">--key-order-priority</code> flag.</p>\n<p dir=\"auto\">The <code class=\"notranslate\">--key-order-priority</code> flag accepts the following values:</p>\n<ul dir=\"auto\">\n<li><code class=\"notranslate\">CertNotBefore</code>: (default) The key registry will be ordered based on the NotBefore attribute of the key certificate.</li>\n<li><code class=\"notranslate\">SecretCreationTimestamp</code>: The key registry will be ordered based on the creation timestamp of the secret.</li>\n</ul>\n<p dir=\"auto\">This flag influences the public key used to encrypt secrets and the certificate retrieved by <code class=\"notranslate\">kubeseal --fetch-cert</code>.</p>\n<h3 dir=\"auto\">User secret rotation</h3>\n<p dir=\"auto\">The <em>sealing key</em> renewal and SealedSecret rotation are <strong>not a substitute</strong> for rotating your actual secrets.</p>\n<p dir=\"auto\">A core value proposition of this tool is:</p>\n<blockquote>\n<p dir=\"auto\">Encrypt your Secret into a SealedSecret, which <em>is</em> safe to store - even inside a public repository.</p>\n</blockquote>\n<p dir=\"auto\">If you store anything in a version control storage, and in a public one in particular, you must assume<br>\nyou cannot ever delete that information.</p>\n<p dir=\"auto\"><em>If</em> a sealing key somehow leaks out of the cluster you must consider all your <code class=\"notranslate\">SealedSecret</code> resources<br>\nencrypted with that key as compromised. No amount of sealing key rotation in the cluster or even re-encryption of existing SealedSecrets files can change that.</p>\n<p dir=\"auto\">The best practice is to periodically rotate all your actual secrets (e.g. change the password) <strong>and</strong> craft new<br>\n<code class=\"notranslate\">SealedSecret</code> resources with those new secrets.</p>\n<p dir=\"auto\">But if the <code class=\"notranslate\">SealedSecret</code> controller was not renewing the <em>sealing key</em> that rotation would be moot,<br>\nsince the attacker could just decrypt the new secrets as well. Thus, you need to do both: periodically renew the sealing key and rotate your actual secrets!</p>\n<h3 dir=\"auto\">Early key renewal</h3>\n<p dir=\"auto\">If you know or suspect a <em>sealing key</em> has been compromised you should renew the key ASAP before you<br>\nstart sealing your new rotated secrets, otherwise you'll be giving attackers access to your new secrets as well.</p>\n<p dir=\"auto\">A key can be generated early by passing the current timestamp to the controller into a flag called <code class=\"notranslate\">--key-cutoff-time</code> or an env var called <code class=\"notranslate\">SEALED_SECRETS_KEY_CUTOFF_TIME</code>. The expected format is RFC1123, you can generate it with the <code class=\"notranslate\">date -R</code> unix command.</p>\n<h3 dir=\"auto\">Common misconceptions about key renewal</h3>\n<p dir=\"auto\">Sealed secrets sealing keys are not access control keys (e.g. a password). They are more like the GPG key you might use to read encrypted mail sent to you. Let's continue with the email analogy for a bit:</p>\n<p dir=\"auto\">Imagine you have reasons to believe your private GPG key might have been compromised. You'd have more to lose than to gain if the first thing you do is just delete your private key. All the previous emails sent with that key are no longer accessible to you (unless you have a decrypted copy of those emails), nor are new emails sent by your friends whom you have not yet managed to tell to use the new key.</p>\n<p dir=\"auto\">Sure, the content of those encrypted emails is not secure, as an attacker might now be able to decrypt them, but what's done is done. Your sudden loss of the ability to read those emails surely doesn't undo the damage. If anything, it's worse because you no longer know for sure what secret the attacker got to know. What you really want to do is to make sure that your friend stops using your old key and that from now on all further communication is encrypted with a new key pair (i.e. your friend must know about that new key).</p>\n<p dir=\"auto\">The same logic applies to SealedSecrets. The ultimate goal is to secure your actual \"user\" secrets. The \"sealing\" secrets are just a mechanism, an \"envelope\". If a secret is leaked there is no going back, what's done is done.</p>\n<p dir=\"auto\">You first need to ensure that new secrets don't get encrypted with that old compromised key (in the email analogy above that's: create a new key pair and give all your friends your new public key).</p>\n<p dir=\"auto\">The second logical step is to neutralize the damage, which depends on the nature of the secret. A simple example is a database password: if you accidentally leak your database password, the thing you're supposed to do is simply to change your database password (on the database; and revoke the old one!) <em>and</em> update the <code class=\"notranslate\">SealedSecret</code> resource with the new password (i.e. running <code class=\"notranslate\">kubeseal</code> again).</p>\n<p dir=\"auto\">Both steps are described in the previous sections, albeit in a less verbose way. There is no shame in reading them again, now that you have a more in-depth grasp of the underlying rationale.</p>\n<h3 dir=\"auto\">Manual key management (advanced)</h3>\n<p dir=\"auto\">The <code class=\"notranslate\">SealedSecret</code> controller and the associated workflow are designed to keep old sealing keys around and periodically add new ones. You should not delete old keys unless you know what you're doing.</p>\n<p dir=\"auto\">That said, if you want you can manually manage (create, move, delete) <em>sealing keys</em>. They are just normal k8s secrets living in the same namespace where the <code class=\"notranslate\">SealedSecret</code> controller lives (usually <code class=\"notranslate\">kube-system</code>, but it's configurable).</p>\n<p dir=\"auto\">There are advanced use cases that you can address by creative management of the sealing keys.<br>\nFor example, you can share the same sealing key among a few clusters so that you can apply exactly the same sealed secret in multiple clusters.<br>\nSince sealing keys are just normal k8s secrets you can even use sealed secrets themselves and use a GitOps workflow to manage your sealing keys (useful when you want to share the same key among different clusters)!</p>\n<p dir=\"auto\">Labeling a <em>sealing key</em> secret with anything other than <code class=\"notranslate\">active</code> effectively deletes<br>\nthe key from the <code class=\"notranslate\">SealedSecret</code> controller, but it is still available in k8s for<br>\nmanual encryption/decryption if need be.</p>\n<p dir=\"auto\"><strong>NOTE</strong> <code class=\"notranslate\">SealedSecret</code> controller currently does not automatically pick up manually created, deleted or relabeled sealing keys. An admin must restart the controller before the effect will apply.</p>\n<h3 dir=\"auto\">Re-encryption (advanced)</h3>\n<p dir=\"auto\">Before you can get rid of some old sealing keys you need to re-encrypt your SealedSecrets with the latest private key.</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"kubeseal --re-encrypt &lt;my_sealed_secret.json &gt;tmp.json \\\n  &amp;&amp; mv tmp.json my_sealed_secret.json\"><pre class=\"notranslate\">kubeseal --re-encrypt <span class=\"pl-k\">&lt;</span>my_sealed_secret.json <span class=\"pl-k\">&gt;</span>tmp.json \\\n  <span class=\"pl-k\">&amp;&amp;</span> mv tmp.json my_sealed_secret.json</pre></div>\n<p dir=\"auto\">The invocation above will produce a new sealed secret file freshly encrypted with<br>\nthe latest key, without making the secrets leave the cluster to the client. You can then save that file<br>\nin your version control system (<code class=\"notranslate\">kubeseal --re-encrypt</code> doesn't update the in-cluster object).</p>\n<p dir=\"auto\">Currently, old keys are not garbage collected automatically.</p>\n<p dir=\"auto\">It's a good idea to periodically re-encrypt your SealedSecrets. But as mentioned above, don't lull yourself in a false sense of security: you must assume the old version of the <code class=\"notranslate\">SealedSecret</code> resource (the one encrypted with a key you think of as dead) is still potentially around and accessible to attackers. I.e. re-encryption is not a substitute for periodically rotating your actual secrets.</p>\n<h2 dir=\"auto\">Details (advanced)</h2>\n<p dir=\"auto\">This controller adds a new <code class=\"notranslate\">SealedSecret</code> custom resource. The<br>\ninteresting part of a <code class=\"notranslate\">SealedSecret</code> is a base64-encoded<br>\nasymmetrically encrypted <code class=\"notranslate\">Secret</code>.</p>\n<p dir=\"auto\">The controller maintains a set of private/public key pairs as kubernetes<br>\nsecrets. Keys are labeled with <code class=\"notranslate\">sealedsecrets.bitnami.com/sealed-secrets-key</code><br>\nand identified in the label as either <code class=\"notranslate\">active</code> or <code class=\"notranslate\">compromised</code>. On startup,<br>\nThe sealed secrets controller will...</p>\n<ol dir=\"auto\">\n<li>Search for these keys and add them to its local store if they are<br>\nlabeled as active.</li>\n<li>Create a new key</li>\n<li>Start the key rotation cycle</li>\n</ol>\n<h3 dir=\"auto\">Crypto</h3>\n<p dir=\"auto\">More details about crypto can be found <a href=\"docs/developer/crypto.md\">here</a>.</p>\n<h2 dir=\"auto\">Developing</h2>\n<p dir=\"auto\">Developing guidelines can be found <a href=\"docs/developer/README.md\">in the Developer Guide</a>.</p>\n<h2 dir=\"auto\">FAQ</h2>\n<h3 dir=\"auto\">Can I encrypt multiple secrets at once, in one YAML / JSON file?</h3>\n<p dir=\"auto\">Yes, you can! Drop as many secrets as you like in one file. Make sure to separate them via <code class=\"notranslate\">---</code> for YAML and as extra, single objects in JSON.</p>\n<h3 dir=\"auto\">Will you still be able to decrypt if you no longer have access to your cluster?</h3>\n<p dir=\"auto\">No, the private keys are only stored in the Secret managed by the controller (unless you have some other backup of your k8s objects). There are no backdoors - without that private key used to encrypt a given SealedSecrets, you can't decrypt it. If you can't get to the Secrets with the encryption keys, and you also can't get to the decrypted versions of your Secrets live in the cluster, then you will need to regenerate new passwords for everything, seal them again with a new sealing key, etc.</p>\n<h3 dir=\"auto\">How can I do a backup of my SealedSecrets?</h3>\n<p dir=\"auto\">If you do want to make a backup of the encryption private keys, it's easy to do from an account with suitable access:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"kubectl get secret -n kube-system -l sealedsecrets.bitnami.com/sealed-secrets-key -o yaml &gt;main.key\n\necho &quot;---&quot; &gt;&gt; main.key\nkubectl get secret -n kube-system sealed-secrets-key -o yaml &gt;&gt;main.key\"><pre class=\"notranslate\">kubectl get secret -n kube-system -l sealedsecrets.bitnami.com/sealed-secrets-key -o yaml <span class=\"pl-k\">&gt;</span>main.key\n\n<span class=\"pl-c1\">echo</span> <span class=\"pl-s\"><span class=\"pl-pds\">\"</span>---<span class=\"pl-pds\">\"</span></span> <span class=\"pl-k\">&gt;&gt;</span> main.key\nkubectl get secret -n kube-system sealed-secrets-key -o yaml <span class=\"pl-k\">&gt;&gt;</span>main.key</pre></div>\n<blockquote>\n<p dir=\"auto\">NOTE: You need the second statement only if you ever installed sealed-secrets older than version 0.9.x on your cluster.</p>\n</blockquote>\n<blockquote>\n<p dir=\"auto\">NOTE: This file will contain the controller's public + private keys and should be kept omg-safe!</p>\n</blockquote>\n<blockquote>\n<p dir=\"auto\">NOTE: After sealing key renewal you should recreate your backup. Otherwise, your backup won't be able to decrypt new sealed secrets.</p>\n</blockquote>\n<p dir=\"auto\">To restore from a backup after some disaster, just put that secrets back before starting the controller - or if the controller was already started, replace the newly-created secrets and restart the controller:</p>\n<ul dir=\"auto\">\n<li>\n<p dir=\"auto\">For Helm deployment:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"kubectl apply -f main.key\nkubectl delete pod -n kube-system -l app.kubernetes.io/name=sealed-secrets\"><pre class=\"notranslate\">kubectl apply -f main.key\nkubectl delete pod -n kube-system -l app.kubernetes.io/name=sealed-secrets</pre></div>\n</li>\n<li>\n<p dir=\"auto\">For deployment via <code class=\"notranslate\">controller.yaml</code> manifest</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"kubectl apply -f main.key\nkubectl delete pod -n kube-system -l name=sealed-secrets-controller\"><pre class=\"notranslate\">kubectl apply -f main.key\nkubectl delete pod -n kube-system -l name=sealed-secrets-controller</pre></div>\n</li>\n</ul>\n<h3 dir=\"auto\">Can I decrypt my secrets offline with a backup key?</h3>\n<p dir=\"auto\">While treating sealed-secrets as long term storage system for secrets is not the recommended use case, some people<br>\ndo have a legitimate requirement for being able to recover secrets when the k8s cluster is down and restoring a backup into a new <code class=\"notranslate\">SealedSecret</code> controller deployment is not practical.</p>\n<p dir=\"auto\">If you have backed up one or more of your private keys (see previous question), you can use the <code class=\"notranslate\">kubeseal --recovery-unseal --recovery-private-key file1.key,file2.key,...</code> command to decrypt a sealed secrets file.</p>\n<h3 dir=\"auto\">What flags are available for kubeseal?</h3>\n<p dir=\"auto\">You can check the flags available using <code class=\"notranslate\">kubeseal --help</code>.</p>\n<h3 dir=\"auto\">How do I update parts of JSON/YAML/TOML/.. file encrypted with sealed secrets?</h3>\n<p dir=\"auto\">A kubernetes <code class=\"notranslate\">Secret</code> resource contains multiple items, basically a flat map of key/value pairs.<br>\nSealedSecrets operate at that level, and does not care what you put in the values. In other words<br>\nit cannot make sense of any structured configuration file you might have put in a secret and thus<br>\ncannot help you update individual fields in it.</p>\n<p dir=\"auto\">Since this is a common problem, especially when dealing with legacy applications, we do offer an <a href=\"docs/examples/config-template\">example</a> of a possible workaround.</p>\n<h3 dir=\"auto\">Can I bring my own (pre-generated) certificates?</h3>\n<p dir=\"auto\">Yes, you can provide the controller with your own certificates, and it will consume them.<br>\nPlease check <a href=\"docs/bring-your-own-certificates.md\">here</a> for a workaround.</p>\n<h3 dir=\"auto\">How to use kubeseal if the controller is not running within the <code class=\"notranslate\">kube-system</code> namespace?</h3>\n<p dir=\"auto\">If you installed the controller in a different namespace than the default <code class=\"notranslate\">kube-system</code>, you need to provide this namespace<br>\nto the <code class=\"notranslate\">kubeseal</code> commandline tool. There are two options:</p>\n<ol dir=\"auto\">\n<li>You can specify the namespace via the command line option <code class=\"notranslate\">--controller-namespace &lt;namespace&gt;</code>:</li>\n</ol>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"kubeseal --controller-namespace sealed-secrets &lt;mysecret.json &gt;mysealedsecret.json\"><pre class=\"notranslate\">kubeseal --controller-namespace sealed-secrets <span class=\"pl-k\">&lt;</span>mysecret.json <span class=\"pl-k\">&gt;</span>mysealedsecret.json</pre></div>\n<ol start=\"2\" dir=\"auto\">\n<li>Via the environment variable <code class=\"notranslate\">SEALED_SECRETS_CONTROLLER_NAMESPACE</code>:</li>\n</ol>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"export SEALED_SECRETS_CONTROLLER_NAMESPACE=sealed-secrets\nkubeseal &lt;mysecret.json &gt;mysealedsecret.json\"><pre class=\"notranslate\"><span class=\"pl-k\">export</span> SEALED_SECRETS_CONTROLLER_NAMESPACE=sealed-secrets\nkubeseal <span class=\"pl-k\">&lt;</span>mysecret.json <span class=\"pl-k\">&gt;</span>mysealedsecret.json</pre></div>\n<h3 dir=\"auto\">How to verify the images?</h3>\n<p dir=\"auto\">Our images are being signed using <a href=\"https://github.com/sigstore/cosign\">cosign</a>. The signatures have been saved in our <a href=\"https://ghcr.io/bitnami-labs/sealed-secrets-controller/signs\" rel=\"nofollow\">GitHub Container Registry</a>.</p>\n<blockquote>\n<p dir=\"auto\">Images up to and including v0.20.2 were signed using Cosign v1. Newer images are signed with Cosign v2.</p>\n</blockquote>\n<p dir=\"auto\">It is pretty simple to verify the images:</p>\n<div class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# export the COSIGN_VARIABLE setting up the GitHub container registry signs path\nexport COSIGN_REPOSITORY=ghcr.io/bitnami-labs/sealed-secrets-controller/signs\n\n# verify the image uploaded in GHCR\ncosign verify --key .github/workflows/cosign.pub ghcr.io/bitnami-labs/sealed-secrets-controller:latest\n\n# verify the image uploaded in Dockerhub\ncosign verify --key .github/workflows/cosign.pub docker.io/bitnami/sealed-secrets-controller:latest\"><pre class=\"notranslate\"><span class=\"pl-c\"><span class=\"pl-c\">#</span> export the COSIGN_VARIABLE setting up the GitHub container registry signs path</span>\n<span class=\"pl-k\">export</span> COSIGN_REPOSITORY=ghcr.io/bitnami-labs/sealed-secrets-controller/signs\n\n<span class=\"pl-c\"><span class=\"pl-c\">#</span> verify the image uploaded in GHCR</span>\ncosign verify --key .github/workflows/cosign.pub ghcr.io/bitnami-labs/sealed-secrets-controller:latest\n\n<span class=\"pl-c\"><span class=\"pl-c\">#</span> verify the image uploaded in Dockerhub</span>\ncosign verify --key .github/workflows/cosign.pub docker.io/bitnami/sealed-secrets-controller:latest</pre></div>\n<h3 dir=\"auto\">How to use one controller for a subset of namespaces</h3>\n<p dir=\"auto\">If you want to use one controller for more than one namespace, but not all namespaces, you can provide additional namespaces using the command line flag <code class=\"notranslate\">--additional-namespaces=&lt;namespace1&gt;,&lt;namespace2&gt;,&lt;...&gt;</code>. Make sure you provide appropriate roles and rolebindings in the target namespaces, so the controller can manage the secrets in there.</p>\n<h3 dir=\"auto\">Can I configure the Controller unseal retries?</h3>\n<p dir=\"auto\">The answer is yes, you can configure the number of retries in your controller using the flag <code class=\"notranslate\">--max-unseal-retries</code>. This flag allows you to configure the number of maximum retries to unseal your Sealed Secrets.</p>\n<h2 dir=\"auto\">Community</h2>\n<ul dir=\"auto\">\n<li><a href=\"https://kubernetes.slack.com/messages/sealed-secrets\" rel=\"nofollow\">#sealed-secrets on Kubernetes Slack</a></li>\n</ul>\n<p dir=\"auto\">Click <a href=\"http://slack.k8s.io\" rel=\"nofollow\">here</a> to sign up to the Kubernetes Slack org.</p>\n<h3 dir=\"auto\">Related projects</h3>\n<ul dir=\"auto\">\n<li><code class=\"notranslate\">kubeseal-convert</code>: <a href=\"https://github.com/EladLeev/kubeseal-convert\">https://github.com/EladLeev/kubeseal-convert</a></li>\n<li>Visual Studio Code extension: <a href=\"https://marketplace.visualstudio.com/items?itemName=codecontemplator.kubeseal\" rel=\"nofollow\">https://marketplace.visualstudio.com/items?itemName=codecontemplator.kubeseal</a></li>\n<li>WebSeal: generates secrets in the browser: <a href=\"https://socialgouv.github.io/webseal\" rel=\"nofollow\">https://socialgouv.github.io/webseal</a></li>\n<li>HybridEncrypt TypeScript implementation: <a href=\"https://github.com/SocialGouv/aes-gcm-rsa-oaep\">https://github.com/SocialGouv/aes-gcm-rsa-oaep</a></li>\n<li>[DEPRACATED] Sealed Secrets Operator: <a href=\"https://github.com/disposab1e/sealed-secrets-operator-helm\">https://github.com/disposab1e/sealed-secrets-operator-helm</a></li>\n</ul>","updatedAt":"2025-05-22T01:47:41Z","upvoteCount":null,"author":{"login":"eryajf","avatarUrl":"https://avatars.githubusercontent.com/u/33259379?u=e4a4090a38ac2473aaed4ef9945233636776c6c3&v=4","url":"https://github.com/eryajf"},"category":null,"labels":{"edges":[{"node":{"name":"更多","color":"25B472"}},{"node":{"name":"K8S-Tools","color":"2d411a"}},{"node":{"name":"bitnami-labs","color":"4ae529"}}]},"comments":{"edges":[]}}},"pageContext":{"number":503,"previous":{"title":"chmln/sd: 与sed命令类似，但提供更加直观的查找和替换能力","number":502},"next":{"title":"labring/sealos: 专为管理云原生应用程序而设计的云操作系统","number":504}}},
    "staticQueryHashes": ["151096407","2861350382"]}