Giới thiệu
Trong thời đại hiện nay, với việc ngày càng có nhiều hệ thống phần mềm lớn nhỏ được ra đời và phát triển, bài toán quản lý truy cập tài nguyên lại càng trở nên quan trọng, cần được lưu tâm. Trong bài viết sau đây, chúng tôi xin phép được chia sẻ đôi điều về bài toán “cũ” nhưng chưa bao giờ hết “mới” này và cách mà đội phát triển hệ thống MASH tại VinBigdata giải quyết nó.
Bài viết sẽ gồm 3 phần, phần đầu tiên sẽ giới thiệu hệ thống MASH và bài toán đặt ra, phần tiếp theo giới thiệu mô hình phân quyền ABAC, phần cuối cùng về Arborist – một open source policy engine của được viết bởi Đại học Chicago ứng dụng mô hình phân quyền trên. Cùng với đó là chúng tôi sẽ trình bày về việc ứng dụng Arborist vào giải quyết bài toán phân quyền của hệ thống MASH.
Bài toán cần giải của hệ thống MASH
Hệ thống MASH là một nền tảng quản lý, phân tích, chia sẻ và tổng hợp thông tin dữ liệu tin sinh được phát triển bởi phòng Tin y sinh ứng dụng tại VinBigdata. Hệ thống sử dụng các công nghệ mới nhất như Kubernetes, Docker, kiến trúc microservices, Kafka, Redis… để giúp cho những nhà nghiên cứu, bác sĩ, chuyên gia di truyền có thể truy xuất các thông tin biến dị từ nhiều dự án và nhiều nguồn thông tin khác nhau.
Hệ thống MASH hiện tại đang quản lý dữ liệu của dự án Xây dựng cơ sở dữ liệu biến dị di truyền cho 1000 người Việt khỏe mạnh, với hơn 1000 TB file dữ liệu, trên 60000 genes và trên 50 triệu biến dị. Ngoài ra hệ thống còn quản lý dữ liệu của gần 5000 mẫu dữ liệu của dự án Dự đoán tác dụng phụ của thuốc, dự án tiểu đường.
Mô hình dữ liệu của dự án với gần 100 bảng liên kết theo cấu trúc phân tầng. Dự án có sự tham gia của nhiều thành viên với các vai trò khác nhau như quản trị hệ thống, chuyên gia di truyền, tin sinh, chuyên gia phân tích, kỹ thuật viên phòng thí nghiệm. Lượng thông tin vô cùng phong phú của các dự án cần được lưu trữ đầy đủ, chính xác, dễ truy xuất nhưng vẫn đảm bảo quản lý, phân quyền tới từng đối tượng cụ thể, từng loại dữ liệu.
Với bài toán về bảo mật và phân quyền đặt ra, hệ thống MASH cần một mô hình quản lý quyền mạnh mẽ, linh hoạt, dễ sử dụng. Sau khi phân tích và so sánh các mô hình phân quyền như Access control list, Role-based access control và Attribute-based access control, nhóm phát triển đã lựa chọn được mô hình thỏa mãn các yêu cầu đó là Attribute-based access control. Phần tiếp theo sẽ trình bày về mô hình này.
Mô hình phân quyền ABAC
1) Mô hình ABAC là gì?
Mô hình phân quyền ABAC (Attribute-based Access Control), hay còn được biết đến với cái tên khác là Policy-based Access Control, là một mô hình quản lý truy cập mà ở đó quyền truy cập sẽ được cấp cho người dùng (users) thông qua việc sử dụng các “chính sách” (policies). Các “chính sách” này được cấu thành bởi một hoặc nhiều thuộc tính (attributes) khác nhau.
Thuộc tính trong ABAC được chia thành nhiều loại như: thuộc tính người dùng (user attributes), thuộc tính tài nguyên (resource attributes), thuộc tính môi trường (environment attributes),…
2) Đặc điểm của mô hình này
Điểm mạnh của mô hình này là việc sử dụng các giá trị thuộc tính đa dạng để tạo ra các “chính sách” linh động. Nhờ những chính sách linh động trên, mô hình ABAC cho phép thực hiện context-aware và risk-intelligent access control. Qua đó mô hình có thể quản lý việc truy cập tài nguyên chặt chẽ hơn các mô hình access control khác.
Ví dụ: thay vì phải sử dụng các roles với các quyền được định nghĩa sẵn từ đầu như trong mô hình Role-based Access Control (RBAC), ABAC cho phép tạo ra các chính sách linh động dựa trên các thuộc tính thuộc nhiều nhóm khác nhau để đưa ra quyết định phân quyền.
Tuy nhiên, cũng chính vì sự đa dạng của thuộc tính mà mô hình ABAC trở nên phức tạp hơn so với các mô hình quản lý truy cập tài nguyên khác.
Mô hình ABAC đã được áp dụng ở trong nhiều dự án công nghệ lớn, tiêu biểu là IAM của Amazon. Ở phần tiếp theo, chúng tôi cũng sẽ giới thiệu về Arborist, một project cũng sử dụng mô hình ABAC.
Arborist – một ABAC policy engine
Như đã nói ở trên, Arborist là một open-source policy engine áp dụng mô hình ABAC. Arborist quản lý các tài nguyên, các hành động mà một người dùng được phép thao tác trên một dữ liệu cụ thể. Trong phần này, chúng tôi sẽ giới thiệu các khái niệm chính của Arborist, cách Arborist sử dụng extension ltree trong PostgreSQL để hiện thực hóa việc quản lý tài nguyên theo phân cấp.
1) Giới thiệu về Arborist
Arborist là một policy engine được viết bằng Golang, sử dụng PostgreSQL để lưu trữ dữ liệu. Arborist đóng vai trò như một dịch vụ quản lý phân quyền cho hệ thống MASH. Điểm độc đáo của Arborist là việc nó quản lý các tài nguyên (resources) dưới dạng cây phân cấp theo đúng mô hình dữ liệu của hệ thống MASH. Ở phần này, chúng tôi sẽ giới thiệu về các khái niệm chính trong Arborist. Trong mục tiếp theo, chúng tôi sẽ nói rõ hơn về việc bằng cách nào mà Arborist có thể quản lý tài nguyên dưới dạng cây.
Arborist sử dụng mô hình quản lý truy cập tài nguyên ABAC. Trong đó, định nghĩa các khái niệm chính sau:
+ Action: là một hành vi được thực hiện của một service. Ví dụ:
+ Permission: là một sự kết hợp giữa action và một số các constrains (ràng buộc) đi kèm, các ràng buộc được biểu diễn dưới dạng key-value, dùng để hạn chế context sử dụng của action. Ví dụ:
+ Role: là một tập hợp các permissions. Ví dụ:
+ Resource: là dữ liệu cần được quản lý truy cập, được biểu diễn dưới dạng giống như đường dẫn trong hệ thống cây quản lý file. Mỗi resource sẽ có một ID riêng biệt (chính là dạng biểu diễn đường dẫn của nó). Mỗi resource có thể có các resource con. Nếu người dùng có quyền truy cập A vào resource cha, đồng nghĩa với việc là người dùng có thể có quyền truy cập A vào các resource con, cháu, chắt,… của nó. Ví dụ về resource path:
Từ ví dụ trên ta có thể thấy resource/projects
là resource cha của resource /projects/cancer
, resource /projects/cancer
lại là cha của resource /
projects/cancer/samples/sample_01
, bởi vậy nếu ta có quyền truy cập resource /projects
, ta sẽ có thêm quyền truy cập cả resource /projects/cancer
và /
projects/cancer/samples/sample_01
. Nhưng nếu ta chỉ có quyền truy cập resource /projects/cancer
thì ta sẽ chỉ có thêm quyền truy cập resource /projects/cancer/samples/sample_01
+ Policy: là một tập kết hợp giữa các roles và resources, với ý nghĩa là tác nhân với policy A sẽ được phép sử dụng bất cứ roles nào trong policy A lên tất cả các resources trong policy A. Các policies có thể được cấp cho các users hoặc các groups. Ví dụ:
+ Groups: là một tập các users.
2) Extension ltree và ứng dụng của nó trong Arborist:
2.1) Extension ltree
ltree là một data type của PostgreSQL, sử dụng để biểu diễn các nhãn (labels) của dữ liệu được lưu dưới cấu trúc dạng cây phân cấp (data type này được biểu diễn trực quan dưới dạng các label paths).
Nhãn (label) là 1 dãy các kí tự bao gồm ký tự chữ cái, chữ số và dấu gạch dưới, ví dụ là: 42
, Personal_Services
Một label path là một dãy gồm không hoặc nhiều labels ghép lại với nhau, các labels sẽ được ngăn cách bởi các dấu chấm (“.”). Như có đề cập ở trên, mỗi label path biểu diễn một đường đi từ 1 label cha bất kì đến một label con bất kì ở trong cây phân cấp. Ví dụ ta có cây phân cấp như sau:
Top.Countries.Europe.Russia
sẽ biểu diễn đường đi từ label Top đến label Russia
Top.Countries.Asia.Vietnam
sẽ biểu diễn đường đi từ label Top đến label VietNam
Top.Countries.Europe
sẽ biểu diễn đường đi từ label Top đến label Euroupe
– Module ltree có cung cấp một số kiểu dữ liệu sau:
+ ltree để lưu trữ label path.
+ lquery để query label path dưới dạng regular-expression, ví dụ như:
foo, *.foo.*, *.foo
+ ltxtquery để hỗ trợ query label path dưới dạng full-text-search, ví dụ như:
Europe & Russia*@ & !Transportation
Đồng thời, ltree cũng hỗ trợ vài loại index để tăng tốc tính toán, cụ thể là index kiểu B-tree hoặc GIST.
– Để hiểu thêm về các thông tin trên, các bạn có thể đọc thêm ở Document LTree của PostgreSQL.
2.2) Ứng dụng của ltree trong Arborist:
Cấu trúc dữ liệu ltree được sử dụng trong Arborist để lưu trữ thông tin đường dẫn của tài nguyên. Các tài nguyên được tổ chức theo mô hình phân cấp. Như hình bên dưới.
– Còn đây là bảng chi tiết về bảng resource trên:
– Như có thể thấy ở hình 5, trường path của resource được lưu dưới dạng ltree. Trên bảng cũng có 4 index, trong đó 2 index “resource_path_key” (dạng btree) và “resource_path_idx” (dạng GIST) được đánh trên trường path để tăng tốc tính toán. Ngoài ra bảng cũng có 1 loạt những triggers để đảm bảo logic quan hệ cha-con của cây phân cấp tài nguyên.
3) Ứng dụng Arborist trong hệ thống MASH
Tích hợp Arborist vào hệ thống MASH đã cho phép thực hiện những quản lý quyền trong hệ thống dễ dàng hơn.
Ví dụ cho phép một người dùng user1 có quyền cập nhật dữ liệu file phân tích của một sample_01 thuộc dự án phân tích Genome 1000 người Việt thì cần tạo một policy write_sample_01 có quyền write trên resource đường dẫn /projects/VN1000G/samples/sample_01/files. Sau đó gán policy này cho user1 thì người dùng sẽ có quyền chỉnh sửa files phân tích của sample_01 mà không có quyền trên các mẫu còn lại.
Ví dụ cho phép một người dùng user1 có quyền read các dữ liệu của tất cả các mẫu của dự án phân tích Genome người Việt thì chỉ cần tạo một policy read_samples có quyền read trên resource có đường dẫn /projects/VN1000G/samples. Sau đó gán policy này cho user1 thì người dùng sẽ có quyền đọc mọi thông tin mà không thể chỉnh sửa.
Ngoài ra để thuận tiện hơn, nhiều người dùng có thể được nhóm vào các group và thực hiện gán policy trên group. Người dùng sẽ có đầy đủ các quyền được gán theo cá nhân và các quyền được gán trên group mà người dùng thuộc vào.
Kết luận:
Trong bài trên, chúng tôi đã nêu ra bài toán phân quyền theo dạng cây phân cấp mà đội phát triển hệ thống MASH tại VinBigdata gặp phải và cách chúng tôi sử dụng Arborist – một open source policy được thiết kế dựa trên mô hình ABAC, để giải quyết bài toán trên. Tiếp đến, chúng tôi cũng có giới thiệu về project open-source này và cách mà nó sử dụng extension ltree của PostgreSQL để quản lý tài nguyên. Chúng tôi mong rằng đây sẽ là một case-study thú vị dành cho người đọc.
Tài liệu tham khảo
https://en.wikipedia.org/wiki/Attribute-based_access_control
https://www.axiomatics.com/attribute-based-access-control/
https://postgrespro.com/docs/postgresql/13/ltree
https://github.com/uc-cdis/arborist
Hướng dẫn: Đỗ Ngọc Tuấn
Tác giả: Nguyen Tung