পাঠ ৩৬ · ৫৮-এর মধ্যে · মডিউল ৮
Home / Courses / Full-Stack Web Frameworks / রোল-বেসড অ্যাক্সেস কন্ট্রোল (RBAC)

রোল-বেসড অ্যাক্সেস কন্ট্রোল (RBAC)

Role-based access control (RBAC)
৯ মিনিট পড়া মধ্যবর্তী · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • RBAC-এর মূল ধারণা — রোল, পারমিশন, ও ইউজার-টু-রোল অ্যাসাইনমেন্ট
  • একটি সত্যিকারের রোল→পারমিশন ম্যাপিং ও has_permission() ফাংশন লেখা
  • একাধিক রোলের পারমিশন ইউনিয়ন সঠিকভাবে গণনা করা
  • একক-রোল চেক বনাম ইউনিয়ন-ভিত্তিক চেকের ফলাফলের পার্থক্য হাতে-কলমে যাচাই করা

১ · RBAC-এর মূল ধারণা

সরাসরি প্রতিটি ইউজারের জন্য আলাদা করে পারমিশন সেট করা (যেমন "সোহেলকে ডিলিট করার অনুমতি দাও") হাজার হাজার ইউজারের সিস্টেমে ব্যবস্থাপনা করা কঠিন হয়ে পড়ে। RBACRole-Based Access Controlইউজারদের সরাসরি পারমিশন না দিয়ে "রোল" দেওয়া হয়, এবং প্রতিটি রোলের সাথে পূর্বনির্ধারিত পারমিশনের সেট যুক্ত থাকে — ফলে হাজারো ইউজার ব্যবস্থাপনা সহজ হয়। এই সমস্যা সমাধান করে একটি মধ্যবর্তী স্তর যোগ করে —

রোল (Role)
একটি নামযুক্ত দায়িত্বের গ্রুপ — যেমন admin, editor, viewer।
পারমিশন (Permission)
একটি নির্দিষ্ট অ্যাকশন করার অনুমতি — যেমন read, write, delete।
অ্যাসাইনমেন্ট
একজন ইউজারকে এক বা একাধিক রোল দেওয়া হয় — সরাসরি পারমিশন নয়, রোলের মাধ্যমে পরোক্ষভাবে।

২ · একাধিক রোল ও পারমিশন ইউনিয়ন

একজন ইউজারের একাধিক রোল থাকা স্বাভাবিক — যেমন কেউ একইসাথে editor ও একটি কাস্টম auditor রোলে থাকতে পারে। সঠিক নিয়ম হলো — তার সব রোলের পারমিশন-সেট একসাথে মিলিয়ে (ইউনিয়ন) নেওয়া হয়, তারপর দেখা হয় প্রয়োজনীয় অ্যাকশনটি সেই মিলিত সেটে আছে কি না।

Python
# রোল -> পারমিশন ম্যাপিং
role_permissions = {
    "admin":   {"read", "write", "delete"},
    "editor":  {"read", "write"},
    "viewer":  {"read"},
    "auditor": {"read", "export"},   # কাস্টম রোল -- ভিন্ন ধরনের পারমিশনও থাকতে পারে
}

# ইউজার -> রোল(গুলো) ম্যাপিং -- একজন ইউজারের একাধিক রোল থাকতে পারে
user_roles = {
    "sohel": {"admin"},
    "priya": {"viewer"},
    "rima":  {"editor", "auditor"},   # একাধিক রোল
}

def has_permission(username, action):
    """ইউজারের সব রোলের পারমিশন-সেট ইউনিয়ন করে action চেক করা হয় --
    যেকোনো একটি রোল অনুমতি দিলেই True"""
    roles = user_roles.get(username, set())
    granted = set()
    for role in roles:
        granted |= role_permissions.get(role, set())
    return action in granted

test_cases = [
    ("sohel", "delete"),   # admin -> delete অনুমোদিত
    ("priya", "write"),    # viewer -> write নিষিদ্ধ
    ("priya", "read"),     # viewer -> read অনুমোদিত
    ("rima",  "write"),    # editor অংশ থেকে write অনুমোদিত
    ("rima",  "export"),   # শুধু auditor রোল থেকে -- একক-রোল চেকে ধরা পড়ত না
    ("rima",  "delete"),   # editor+auditor কোনোটিতেই delete নেই -- নিষিদ্ধ
]

print(f"{'ইউজার':8s} | {'অ্যাকশন':8s} | ফলাফল")
print("-" * 40)
for username, action in test_cases:
    allowed = has_permission(username, action)
    result = "Allowed" if allowed else "Denied"
    print(f"{username:8s} | {action:8s} | {result}")

# --- একক-রোল চেক হলে কী হতো (একটি বাগ ধরিয়ে দেওয়ার জন্য) ---
def has_permission_single_role(username, action, role_to_check):
    """তুলনার জন্য -- ধরা যাক সিস্টেম ভুলভাবে ইউজারের শুধু ONE নির্দিষ্ট রোল চেক করে"""
    return action in role_permissions.get(role_to_check, set())

print("\n--- 'rima' + 'export' -- একক-রোল বনাম ইউনিয়ন-ভিত্তিক চেক ---")
single = has_permission_single_role("rima", "export", "editor")
union = has_permission("rima", "export")
print("শুধু 'editor' রোল চেক করলে (bug):", single)
print("সব রোলের ইউনিয়ন চেক করলে (সঠিক):", union)

    
rima-এর রোল {"editor", "auditor"}। শুধু "editor" রোল চেক করলে তার পারমিশন-সেট {"read", "write"} — এতে "export" নেই, তাই ভুলভাবে Denied দেখাবে। কিন্তু সঠিক has_permission() ফাংশনটি editor ও auditor দুটোরই পারমিশন একসাথে মিলিয়ে {"read", "write", "export"} সেট তৈরি করে — এতে "export" আছে, তাই সঠিকভাবে Allowed রিটার্ন করে। এটাই দেখায় একক-রোল চেক কেন একটি বাগ — এটি ইউজারের বাকি রোলগুলো থেকে পাওয়া বৈধ অনুমতি উপেক্ষা করে।
মূল কথা · Key takeaway

RBAC-এ পারমিশন সরাসরি ইউজারকে না দিয়ে রোলের মাধ্যমে পরোক্ষভাবে দেওয়া হয়, যা হাজারো ইউজার ব্যবস্থাপনাকে সহজ করে (একটি রোলের পারমিশন বদলালে সেই রোলের সব ইউজারের অ্যাক্সেস স্বয়ংক্রিয়ভাবে বদলে যায়)। একাধিক রোল থাকা ইউজারের ক্ষেত্রে সবসময় সব রোলের পারমিশনের ইউনিয়ন নিতে হবে — নাহলে বৈধ অনুমতিও ভুলভাবে Denied হয়ে যেতে পারে।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ RBAC-এ সরাসরি ইউজারকে পারমিশন না দিয়ে রোলের মাধ্যমে পরোক্ষভাবে দেওয়ার সুবিধা কী?

ধরুন একটি কোম্পানিতে ৫০০ জন "editor" আছে এবং সিদ্ধান্ত হলো এখন থেকে তারা সবাই export-ও করতে পারবে। যদি পারমিশন সরাসরি প্রতিটি ইউজারে সংরক্ষিত থাকত, তাহলে ৫০০টি আলাদা রেকর্ড বদলাতে হতো। RBAC-এ শুধু role_permissions["editor"] সেটে "export" যোগ করলেই ৫০০ জনের অ্যাক্সেস একসাথে বদলে যায় — কারণ তাদের পারমিশন রোলের রেফারেন্স থেকে গণনা হয়, প্রতিটি ইউজারে আলাদা করে সংরক্ষিত থাকে না।

প্র ০২ কেন has_permission()-এ পারমিশন গণনার জন্য Python-এর set ব্যবহার করা হয়েছে, list নয়?

set-এ |= অপারেটর দিয়ে দুটো সেট সরাসরি ইউনিয়ন করা যায় (গাণিতিক সেট-ইউনিয়নের মতোই), এবং একই পারমিশন একাধিক রোলে থাকলেও (যেমন editor ও auditor দুটোতেই "read") সেটে সদৃশ (duplicate) এন্ট্রি জমা হয় না। এছাড়া action in granted চেক সেটে গড়ে O(1) সময়ে হয়, তালিকায় (list) খুঁজলে প্রতিটি এন্ট্রি একে একে যাচাই করতে হতো — বড় সিস্টেমে এই পার্থক্য গুরুত্বপূর্ণ হয়ে ওঠে।

প্র ০৩ উপরের কোডে has_permission("priya", "write") কেন Denied রিটার্ন করে?

priya-র রোল শুধু {"viewer"}, এবং role_permissions["viewer"] হলো {"read"} — এতে "write" নেই। যেহেতু priya-র আর কোনো রোল নেই যা "write" দিতে পারে, ইউনিয়ন সেটও শুধু {"read"} থাকে, তাই "write" in granted মিথ্যা হয়ে যায় এবং ফাংশন False (Denied) রিটার্ন করে।

অনুশীলন

  1. চিন্তা করুন: RBAC-এ কখনো কখনো একটি ইউজারকে একটি নির্দিষ্ট রিসোর্সে অস্থায়ীভাবে আলাদা অ্যাক্সেস দেওয়ার দরকার হতে পারে (যেমন শুধুমাত্র একটি নির্দিষ্ট ডকুমেন্টে delete অনুমতি, যদিও তার রোল সাধারণত delete দেয় না) — এই প্রয়োজন উপরের রোল-শুধু ডিজাইনে কীভাবে ফিট হবে?

    এই ধরনের প্রয়োজনের জন্য সাধারণত RBAC-এর সাথে একটি "resource-level override" বা "exception" স্তর যোগ করা হয় — যেমন resource_permissions[("rima", "doc_42")] = {"delete"}-এর মতো একটি আলাদা ম্যাপিং, যা has_permission() চেক করার সময় রোল-ভিত্তিক ইউনিয়নের পাশাপাশি এই রিসোর্স-নির্দিষ্ট এন্ট্রিও চেক করে (আরেকটি ইউনিয়ন)। এই প্যাটার্নকে প্রায়ই ABAC (Attribute-Based Access Control) বলা হয়, যা RBAC-এর একটি সম্প্রসারণ।

  2. পরীক্ষা করুন: উপরের কোড সেলে user_roles-এ একটি নতুন ইউজার "karim": {"viewer", "editor"} যোগ করুন, তারপর test_cases-এ ("karim", "write") যোগ করে Run চেপে দেখুন ফলাফল কী আসে।

    karim-এর রোল {"viewer", "editor"}-এর ইউনিয়ন হলো {"read"} | {"read", "write"} = {"read", "write"} — এতে "write" আছে, তাই has_permission("karim", "write") True (Allowed) রিটার্ন করবে। লক্ষ্যণীয়, যদিও viewer রোল একা write দিতে পারত না, ইউনিয়নে editor-এর কারণে সেটি অনুমোদিত হয়ে যায়।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

  • কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৮টি পাঠ আর্কিটেকচার প্যাটার্ন, ফ্রন্ট-এন্ড/ব্যাক-এন্ড ফ্রেমওয়ার্ক ফান্ডামেন্টাল, স্টেট ম্যানেজমেন্ট, REST API, ORM, অথেন্টিকেশন, রেন্ডারিং স্ট্র্যাটেজি ও ডিপ্লয়মেন্ট।
  • Cybersecurity কোর্স সহোদর কোর্স প্রিন্সিপল অফ লিস্ট প্রিভিলেজ ও অ্যাক্সেস-কন্ট্রোল সম্পর্কিত গভীর নিরাপত্তা নীতিমালা সেই কোর্সে বিস্তারিত আলোচিত।
  • Python Programming কোর্স সহোদর কোর্স set-এর মতো ডেটা স্ট্রাকচার ও তাদের অপারেশনের ভিত্তি সেই কোর্সে তৈরি হয়েছে।
  • সব Courses দেখুন ABCL TECH C, C++, Python, Java, JavaScript, DSA, DBMS, Discrete Mathematics, System Design, Cybersecurity, Cloud Computing & DevOps, Computer Networks, Operating Systems, Computer Architecture, Programming Languages & Compiler Design, Software Engineering & Git, Theory of Computation, Engineering Economics ও Full-Stack Web Frameworks — সব এক জায়গায়।
আগের পাঠ
OAuth 2.0 ও থার্ড-পার্টি লগইন