به گزارش از وبسایت cncf، در بسیاری از سازمان‌ها Kyverno در بخش امنیت قرار می‌گیرد؛ جایی که کنار OPA/Gatekeeper ارزیابی می‌شود، تیم امنیت آن را تأیید می‌کند و همراه با مجموعه‌ای از سیاست‌های Pod Security Standard روی cluster نصب می‌شود. اما در عمل، اغلب فقط همان‌جا می‌ماند و گهگاه جلوی اجرای یک container با root access را می‌گیرد. 🔒

با این حال، بیشترین ارزش Kyverno را معمولاً تیم‌هایی می‌گیرند که آن را برای کارهای دیگری به‌کار می‌برند؛ کارهایی که توجه را جلب می‌کند و یادداشت‌برداری را به‌دنبال دارد. این تیم‌ها تقریباً هیچ‌وقت تیم‌های امنیتی نیستند، بلکه تیم‌های platform هستند. و به‌نظر می‌رسد این تصادفی نیست. Kyverno در ذهن بسیاری از ما در دسته اشتباهی قرار گرفته و همین دسته‌بندی نادرست باعث شده از بخش بزرگی از توانایی‌های آن استفاده نکنیم. ⚙️

نویسنده این نگاه را مدت‌هاست دنبال می‌کند. نخستین سخنرانی او درباره Kyverno در KCD Munich 2023 با عنوان «Securing Your Kubernetes Workloads with Kyverno» بود؛ یعنی خودش هم آن را در همان جعبه امنیت گذاشته بود. اما پس از سه سال تجربه در محیط production، موضوع سخنرانی‌های او به governance، CEL و platform self-service رسیده و در نوشته‌ای در Platform Engineering blog هم توضیح داده که Kyverno دیگر از عنوان «policy engine» فراتر رفته است. در این مطلب، او می‌خواهد یک جمله اصلی را روشن کند: Kyverno یک platform primitive است؛ نه فقط یک ابزار امنیتی که تیم‌های platform از آن استفاده می‌کنند، بلکه یک بلوک سازنده برای platform، درست مثل Pods و Services، که البته برای امنیت هم مفید است. 🚀

مشکل نگاه امنیتی

البته منظور این نیست که Kyverno کار امنیتی انجام نمی‌دهد. این ابزار می‌تواند configurationهای ناامن را متوقف کند، PSS را اعمال کند و امضای imageها را بررسی کند. اگر CISO بپرسد آیا برای compliance مفید است، پاسخ قطعاً بله است. اما «security tool» یک مدل ذهنی خاص را هم به‌همراه دارد: policy به‌عنوان gate. چیزی بد وارد می‌شود و gate جلوی آن را می‌گیرد. در این نگاه، فعل اصلی deny است و موفقیت با تعداد deploymentهای مسدودشده سنجیده می‌شود.

اما اگر به خود Kyverno نگاه کنیم، چهار کار اصلی انجام می‌دهد: validate، mutate، generate و verify images. فقط مورد اول واقعاً با مدل gate هماهنگ است. mutate منابع را هنگام ورود به cluster تغییر می‌دهد. generate منابع تازه‌ای را در واکنش به اتفاقات می‌سازد. verify images هم بیشتر از آن‌که صرفاً تهدید را متوقف کند، درباره ایجاد trust است. به زبان ساده، سه‌چهارم قابلیت‌های آن سازنده‌اند: چیزی اضافه می‌کنند، چیزی را تغییر می‌دهند یا چیزی می‌سازند. با این حال، در بیشتر سازمان‌ها Kyverno عمدتاً با validation policy به‌کار می‌رود. این همان اثر نگاه امنیتی بر configهاست. وقتی ذهنیت شما «policy = deny» باشد، فقط از بخشی کوچک از ابزار استفاده می‌کنید. 🙂

پس platform primitive یعنی چه؟

چون کل نوشته بر این اصطلاح تکیه دارد، لازم است آن را دقیق‌تر تعریف کنیم. وقتی گفته می‌شود primitive، منظور همان چیزی است که در زبان‌های برنامه‌نویسی هم داریم: یک building block کوچک و روشن که با ترکیب آن می‌توان چیزهای بزرگ‌تر ساخت. برای یک platform، primitive باید چهار ویژگی داشته باشد:

1. پیچیدگی را پنهان کند؛ developer بدون دانستن جزئیات زیرساخت از آن استفاده کند.

2. ضمانت ایجاد کند؛ استفاده از آن یعنی برخی ویژگی‌ها خودکار برقرار شوند.

3. قابلیت ترکیب داشته باشد؛ بتوان آن را با primitiveهای دیگر برای ساخت لایه‌های بالاتر ترکیب کرد.

4. self-service باشد؛ از platform دریافت شود، نه از مسیر ticket.

Pods، Services و ConfigMaps نمونه‌هایی از primitive هستند. Crossplane compositionها هم همین‌طور. و نویسنده می‌خواهد نشان دهد که policyهای Kyverno هم باید در همین فهرست قرار بگیرند. 🧩

platform teamها عملاً با آن چه می‌سازند

برای روشن شدن موضوع، بهترین کار این است که چند نمونه واقعی از استفاده platform teamها از Kyverno را ببینیم؛ زمانی که دیگر آن را یک امنیت‌سنج با نظر شخصی در نظر نمی‌گیرند.

namespace furnishing. وقتی یک developer یک namespace می‌سازد، Kyverno به‌طور خودکار NetworkPolicy، ResourceQuota، LimitRange، RoleBindings و موارد مشابه را تولید می‌کند. دیگر لازم نیست کسی یک wiki page را بخواند و شش موردی را که باید به خاطر بسپارد مرور کند. namespace از همان ابتدا آماده و مجهز ایجاد می‌شود.

sidecar injection. agentهای observability، mesh proxyها و secret sync containerها در زمان admission به Pod spec اضافه می‌شوند. manifest مربوط به Deployment برای developer تمیز و ساده می‌ماند و در عین حال نیازهای platform هم برآورده می‌شود. اینجا مذاکره‌ای در کار نیست.

image reference rewriting. این مورد یکی از جذاب‌ترین مثال‌هاست، چون بسیار ساده است و دردسر زیادی را از بین می‌برد. اگر platform بخواهد imageها از طریق internal mirror دریافت شوند، می‌توان از هر developer خواست همیشه prefixهایی مثل mirror.internal/ را به خاطر بسپارد؛ اما این راه‌حل معمولاً جواب نمی‌دهد و حتی ممکن است هنگام rate-limit شدن Docker Hub، buildها ناپایدار شوند. در مقابل، Kyverno می‌تواند nginx:1.25 را در زمان admission به mirror.internal/nginx:1.25 بازنویسی کند و مسئله را عملاً حذف کند. developer همان چیزی را می‌نویسد که طبیعی است و سیستم کار درست را انجام می‌دهد. ✅

default resource requests. به‌جای آن‌که Pods بدون CPU و memory request را مسدود کنیم ــ کاری که از نظر فنی درست است اما در عمل آزاردهنده ــ می‌توان مقدارهای پیش‌فرض مناسب workload را تزریق کرد. در این حالت scheduler داده‌های لازم را دارد و developer فقط زمانی با جزئیات درگیر می‌شود که واقعاً نیاز به تنظیم دقیق داشته باشد.

ownership labels. برچسب‌هایی مثل team، cost center و environment را در جایی که ابهام واقعی وجود دارد enforce کنید و در جاهایی که نیازی نیست به‌صورت پیش‌فرض بگذارید. اگر دوباره به این فهرست نگاه کنیم، می‌بینیم هیچ‌کدام ذاتاً امنیتی نیستند. این‌ها بیشتر به developer experience و operational hygiene مربوط‌اند؛ همان کارهای به‌ظاهر ساده اما حیاتی برای اداره یک platform. وجه مشترک همه آن‌ها این است که یک باور سازمانی درباره «چطور باید کار کند» را به یک enforcement خودکار و نامرئی تبدیل می‌کنند. کسی لازم نیست آن را به خاطر بسپارد. دقیقاً همین‌جا است که یک primitive معنا پیدا می‌کند: ضمانت را طوری ارائه می‌دهد که شما دیگر مجبور نباشید دائم به آن فکر کنید. 🛠️

policy زبان platform برای بیان intent است

هر سازمانی درباره نحوه کار سیستم‌هایش یک‌سری باور دارد. بعضی از این باورها امنیتی‌اند؛ مثلاً container نباید root باشد و imageها باید امضاشده باشند. بعضی عملیاتی‌اند؛ مثلاً همه چیز باید resource limit داشته باشد. بعضی مالی‌اند؛ مثل این‌که هر چیزی باید cost-center label داشته باشد. بعضی هم صرفاً فرهنگی‌اند؛ مثل این‌که هر deployment باید به یک catalog entry برگردد.

جای سنتی این باورها معمولاً documentation است: wikiها، deckهای onboarding، checklistهای PR و گاهی همان senior engineer که همه چیز را دستی review می‌کند. نتیجه این می‌شود که enforcement یکنواخت نیست، دانش در حد tribal knowledge باقی می‌ماند و platform team به یک bottleneck انسانی تبدیل می‌شود، چون هیچ چیز بدون حضور فردی در حلقه کار نمی‌کند.

اما وقتی policy به‌صورت code، versioned در Git، تحویل‌داده‌شده با GitOps tooling و enforce‌شده با Kyverno باشد، این باورها از documentation بیرون می‌آیند و به infrastructure تبدیل می‌شوند. قواعد platform از ذهن افراد خارج می‌شود و در خود سیستم زندگی می‌کند. خلاصه این نگاه در یک جمله: policy، API platform برای intent سازمانی است. 📌

از این نگاه چه نتیجه‌ای می‌گیریم؟

اگر این بازتعریف را بپذیریم، چند نتیجه کاربردی به‌دست می‌آید و همین‌ها تقریباً نقشه راه ادامه این مجموعه هستند.

چهار فعل اصلی دیگر یک فهرست ساده از قابلیت‌ها نیستند، بلکه به سلسله‌مراتب توانمندی‌های platform تبدیل می‌شوند. validation یعنی guardrail، mutation یعنی paved road، generation یعنی scaffolding و verification یعنی trust. mutation به‌ویژه بسیار کم‌تر از ظرفیت واقعی‌اش استفاده می‌شود و همین موضوع به یک مطلب جداگانه نیاز دارد.

policyها هم کم‌کم شبیه محصول می‌شوند: version دارند، user دارند، چرخه deprecation دارند و فرآیند exception management لازم دارند. rollout تدریجی ــ از auditing به warning و بعد enforcement ــ دیگر یک تکنیک پیشرفته نیست، بلکه روش معمول انتشار policy می‌شود. exceptionها هم به‌جای آن‌که در گفت‌وگوهای Slack گم شوند، به debt ثبت‌شده تبدیل می‌شوند.

GitOps هم در این میان بزرگ‌تر می‌شود. اگر policy همان code است و policy زبان بیان intent platform است، پس policy repo به‌اندازه manifestهای برنامه‌ای که کنترل می‌کند اهمیت پیدا می‌کند. در این حالت Argo CD یا Flux دیگر فقط workloadها را deploy نمی‌کنند، بلکه قواعدی را هم deploy می‌کنند که شکل workloadها را تعیین می‌کند. و این موضوع یک سؤال مهم و البته پیچیده هم ایجاد می‌کند: وقتی policy یک resource را mutate می‌کند، اما Argo CD فکر می‌کند همان resource را خودش مالک است، reconciliation چه می‌شود؟ این هم موضوع یک مطلب آینده است. اگر به sync loop علاقه داشته باشید، موضوع سرگرم‌کننده‌ای است. 🔄

جمع‌بندی

دفعه بعد که به مستندات Kyverno سر می‌زنید، آن را مثل یک platform SDK بخوانید، نه مثل یک security manual. سطح API آن بسیار گسترده‌تر از چیزی است که نگاه امنیتی نشان می‌دهد و چیزهایی که می‌توان با آن ساخت، بسیار جالب‌تر از صرفاً «block کردن Podهای بد» است.

Kyverno نگهبانی نیست که دمِ در cluster ایستاده باشد؛ بیشتر شبیه connective tissue است. این ابزار کاری می‌کند که نگاه‌ها و تصمیم‌های platform به رفتار واقعی platform تبدیل شوند. وقتی این موضوع جا بیفتد، دیگر نمی‌شود آن را نادیده گرفت — و ادامه این مجموعه دقیقاً درباره همین است که بعد از این درک، چه باید کرد. 🌟