پیادهسازی کنترل دسترسی مبتنی بر ویژگی را برای APIها (Implement Attribute-Based Access Control For APIs)
وقتی درباره کنترل دسترسی صحبت میکنیم، ممکن است با دو روش رایج روبهرو شویم. اولی، و احتمالاً شناختهشدهتر، رویکرد سنتی کنترل دسترسی مبتنی بر نقش (RBAC) است. بااینحال گزینهای ثانویه نیز وجود دارد، یعنی کنترل دسترسی مبتنی بر ویژگی (ABAC)، که دقت و قابلیت گسترش بیشتری ارائه میدهد.
اما دقیقاً ABAC چگونه کار میکند و تفاوت میان RBAC و ABAC چیست؟
در ادامه به هر دو RBAC و ABAC میپردازیم و تصویری واضح از آنها ایجاد میکنیم. سپس یک درک سطحبالا از نحوه پیادهسازی ABAC برای افزایش امنیت API ارائه میکنیم.
کنترل دسترسی مبتنی بر نقش (RBAC) چیست؟
وقتی درباره کنترل دسترسی مبتنی بر ویژگی صحبت میکنیم، مفید است که ابتدا بفهمیم کنترل دسترسی مبتنی بر نقش چگونه کار میکند. برای سیستمی با چند نوع کاربر، میتوانید این کاربران را براساس نقشی که در سازمان دارند و بر همین اساس در خود سیستم، بخشبندی کنید. برای مثال، کاربری که اقدامات مدیریتی انجام میدهد، مانند مدیر سیستم، نیازهای سطح بالاتری نسبت به یک نماینده فروش دارد. بر این اساس، ممکن است آن کاربر به سطحی از دسترسی به سیستم زیربنایی نیاز داشته باشد که از دیگر کارکنان بیشتر است و این سطح براساس نقش تعیین میشود.
از نظر عملکردی، این به محدودیت روی توابع و منابع براساس نقشی که به آنها دسترسی دارد ترجمه میشود. مدیر سیستم ذکرشده ممکن است اجازه دسترسی به تابعی که روی کنترل دسترسی داخلی کار میکند داشته باشد یا بتواند به اطلاعات دارای مجوز سطح بالا دسترسی یابد. نماینده فروش، در مقابل، شاید فقط بتواند به عناصری مانند تولید کد احراز هویت نسخه آزمایشی یا کارکردهای پایه کاربری دسترسی داشته باشد.
درحالیکه RBAC کار قابلقبولی در کنترل دسترسی انجام میدهد، اما معایب قابلتوجهی دارد.
معایب RBAC
اول و مهمتر از همه، مدل RBAC یک ضعف اساسی دارد نگاشت نقشها به عملیات همیشه واضح نیست. در مثال نماینده فروش، اگر سازمان تصمیم بگیرد که نمایندگان فروش باید بتوانند برای اهداف نمایشی حساب کاربری ایجاد کنند چه؟ اصول کنترل دسترسی به ما میگوید که نمیخواهیم آنها را مدیر سیستم کنیم، اما نقش فعلی آنها پاسخگوی نیازشان نیست. تنها راهحل در این حالت ایجاد یک نقش جدید است. نقش «نماینده فروش ارتقاءیافته» بهسرعت قابل ایجاد است. آسان است، درست؟
اما سناریوی بعدی چه؟ اگر یک معاون بازاریابی نیاز به دسترسی متفاوتی نسبت به یک مدیر بازاریابی داشته باشد؟ یا مدیران پایه در مقابل ناظران سیستمهای کاربرمحور؟ اگر هر سناریوی جدید یعنی یک نقش جدید، آنگاه تنوع عظیمی ایجاد میکنیم و با ضعفی به نام «انفجار نقشها» روبهرو میشویم. حتی با مدیریت صحیح نقشها، این مشکل ذاتی در رویکرد مبتنی بر نقش است و قابلحذف نیست.
حتی اگر این مشکل را حل کنیم، واقعیت این است که RBAC در مقیاسپذیری مشکل دارد. حتی در سازمانی کامل که نقشها بهخوبی تعریف و کنترل شدهاند، این وضعیت فقط موقتی است. نقشها دائمی نیستند و ثابت نمیمانند. در چنین حالتی نقشها ممکن است منفجر نشوند، اما تغییر شکل میدهند و هر تغییر در کارکرد یا هدف نقش نیازمند تغییر در لایه پشتیبان نقش در کد و دسترسی منابع است. این موضوع کسبوکار را به API در یک جهت متصل میکند و ناکارآمدی و مشکل در مقیاسپذیری و گسترشپذیری ایجاد میکند.
علاوه بر این، RBAC به هزینه و پیچیدگی وضعیت امنیتی میافزاید. وقتی امنیت منابع را براساس اینکه چه کسی باید به آنها دسترسی داشته باشد تعریف میکنید، رویکردی جهتدار اتخاذ میکنید که کد را به سازمان متصل میکند. این نیازمند فردی برای مدیریت موضوع، فردی برای بازبینی دائمی نقشها و دسترسیهای آنها، و فردی برای اطمینان از تخصیص نقش صحیح در فرایند ورود کارکنان جدید است. در طول زمان، این هزینه بهشدت افزایش مییابد، و درحالیکه شاید مدیریت آن برای یک استارتاپ ۲۰نفره آسان باشد، یک سازمان وسیع با صدها یا هزاران عضو سریعاً درمییابد که مدیریت و لجستیک لازم برای امنیت مبتنی بر نقش بسیار پرهزینه — گاهی غیرممکن — است.
کنترل دسترسی مبتنی بر ویژگی (ABAC) چیست؟
بهعنوان جایگزینی برای RBAC، مدل ABAC وجود دارد. برخلاف RBAC که دسترسی را براساس نقش کاربر محدود میکند، ABAC بهطور خاص کنترل را از طریق ایجاد ویژگیها دنبال میکند. این ویژگیها فقط محدود به منبع یا نقش کاربر نیستند. درواقع، ویژگیها میتوانند به هر عنصر در شبکه اضافه شوند بدون توجه به منشأ، نوع یا ساختار.
برای مثال، میتوان ویژگیها را به شکلهای زیر اضافه کرد:
کاربران: ویژگیهایی مانند نوع کاربر (کارمند، کاربر عادی، مدیر)، آدرس IP، داخلی یا خارجی بودن نسبت به شبکه. این ویژگیها میتوانند از خود احراز هویت نیز ناشی شوند، مانند سطح قدرت احراز هویت یا منشأ احراز هویت.
منابع: اینکه منبع دارای سطح دسترسی بالا باشد، نیازمند اعتبار قوی باشد، جدید باشد یا قدیمیتر از تاریخ مشخصی باشد.
درخواستها: دادههای درخواست، زمان ارسال درخواست، یا تعداد درخواستهای مشابه ارسالشده.
محیط: تاریخ، میزان بار سیستم، سطح ترافیک و…
این فهرست کامل نیست. درواقع، ویژگیها تقریباً به هر عنصر شبکه قابل اتصال هستند و سپس بهعنوان عناصر محدودکننده برای کنترل تعاملها استفاده میشوند.
ABAC چگونه کار میکند
بیایید ببینیم ABAC در اصل چگونه کار میکند و چگونه مشکل انفجار نقشها را حل میکند. فرض کنید نماینده فروشی تلاش میکند به اطلاعات سفارش مشتری دسترسی پیدا کند. او ویژگیهای زیر را در توکن دسترسی خود دارد:
وقتی نماینده فروش سیستم را برای بازیابی اطلاعات سفارش فراخوانی میکند، سیستم بررسی میکند آیا سطح دسترسی لازم را دارد یا نه. در ABAC میتوان قوانین را براساس ویژگیها تعریف کرد. برای مثال، ممکن است فقط کاربرانی با admin_level برابر یا بزرگتر از ۳ اجازه مشاهده جزئیات سفارش را داشته باشند. علاوه بر این، قانونی مرتبط با user_id میتواند تضمین کند نماینده فروش فقط سفارشهایی را ببیند که مربوط به مشتریان تحت مدیریت او هستند.
ویژگیها همچنین میتوانند بهصورت خودکار براساس رفتار سازمان تنظیم شوند. برای مثال اگر نماینده فروش کاربر جدیدی ایجاد کند، سیستم ویژگی created_by را مطابق user_id او در پروفایل مشتری جدید قرار میدهد:
گام بعدی این است که شناسه نماینده فروش به ابتدای شماره سفارش اضافه شود:
این موضوع شماره سفارشی مانند «۱۲۳-۰۰۰۱۱» تولید میکند. از اینجا میتوان تضمین کرد که نماینده فروش فقط به سفارشهایی که این مقدار در ابتدای آنها وجود دارد دسترسی داشته باشد.
این کار خطر دسترسی یک مشتری به سفارش مشتری دیگر را از بین میبرد و روشی پویا برای جلوگیری از انفجار نقشها فراهم میکند.
طراحی ABAC برای APIها
اکنون که فهمیدیم ABAC چگونه عمل میکند، باید ببینیم هنگام طراحی آن برای APIها چه ملاحظاتی مهم است.
در نظر گرفتن ویژگیهای طراحی
از آنجا که کنترل اصلی در ویژگیها قرار دارد و نه در کاربر، ارائهدهندگان API باید با دقت ویژگیهایی که باید وجود داشته باشند را انتخاب کنند. برخلاف نقشها، ویژگیها انعطاف بیشتری دارند و تعیین آنها به نیازهای API بستگی دارد. APIهایی که با دادههای حساس سروکار دارند باید ویژگیها را با جزئیات بالا تعریف کنند و مواردی مانند ویژگیهای کاربر، محیط، نحوه تعامل، و حتی زمان میان ارسال و دریافت درخواست را برای جلوگیری از حملات دخالت واسط یا بازپخش در نظر بگیرند.
APIهای سادهتر نباید ABAC را بهانهای برای ایجاد سیستم بسیار پیچیده کنند — تعداد حداقلی ویژگیهای لازم باید در نظر گرفته شود.
جریانهای احراز مجوز
جریان احراز مجوز باید به کلاینت اجازه دهد توکنی حاوی ویژگیها دریافت کرده و به API ارسال کند. وقتی کاربر درخواست میفرستد، کلاینت او را برای احراز هویت به سیستم هویتی هدایت میکند و توکنی شامل ویژگیها دریافت میشود. API توکن را بررسی و اعتبارسنجی میکند و ویژگیها را بهکار میگیرد.
همچنین باید برنامهای برای لغو دسترسی از طریق بهروزرسانی ویژگیها و انقضا وجود داشته باشد. ویژگیها دائمی نیستند؛ باید بتوان آنها را تغییر داد، لغو کرد و مدیریت کرد.
معماری مبتنی بر توکن برای فعالسازی ABAC
بخش بزرگی از این رویکرد به سبک معماری سیستم بستگی دارد. مدیریت ویژگیها باید سازگار و منسجم باشد، اما معماریهایی مانند GraphQL که امکان ترکیب و تغییر ساختار را دارند باید مشکلاتی مانند تزریق، اسکریپتنویسی بینسایتی و… را در نظر بگیرند — مخصوصاً ویژگیهایی که خودکار بهروزرسانی میشوند.
ویژگیها باید مانند کلید یا توکن مدیریت شوند: رمزگذاریشده، قابلردگیری، دارای الگوی منقضیسازی و… . برای رسیدن به چنین معماری، راهحلهای یکپارچه و قدرتمند لازم است.
خوشبختانه راهحلهایی مانند OAuth 2.0 کنترل دسترسی قدرتمند، در مقیاس گسترده ارائه میدهند و شروع کار با ABAC را ساده میکنند.
استفاده از ABAC برای احراز مجوز API
ABAC رویکردی قدرتمندتر از RBAC است و مزایای قابلتوجهی در گسترشپذیری و توسعه ارائه میدهد. اما اجرای ABAC نیازمند جداسازی بیشتر و جریانهای پیچیدهتر است. برای برخی APIها این موضوع میتواند بیشازحد پیچیده شود و مدیریت آن مشکل ایجاد کند.
با برنامهریزی کافی و طرحی برای ردیابی، بهروزرسانی، لغو و منقضیسازی ویژگیها، ABAC میتواند سیستم بسیار امنی ایجاد کند.

