From 23cf1edb8ef1c73d782ee2c3d7aad8d9ef9d466e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Aguiar?= Date: Mon, 22 Jan 2024 10:28:22 -0300 Subject: [PATCH] Added super admin example (#18) * feat: added superadmin example * Update stores/superadmin/store.fga.yaml * chore: mentioned best practices for super admins * chore(ci): run ci against superadmin-example --------- Co-authored-by: Raghd Hamzeh --- .github/workflows/main.yaml | 2 +- stores/github/tuples.yaml | 0 stores/superadmin/README.md | 26 ++++++ stores/superadmin/store.fga.yaml | 133 +++++++++++++++++++++++++++++++ 4 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 stores/github/tuples.yaml create mode 100644 stores/superadmin/README.md create mode 100644 stores/superadmin/store.fga.yaml diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 20a0f5e..662a532 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -19,7 +19,7 @@ jobs: strategy: matrix: - store-name: [advanced-entitlements, banking, groups-resource-attributes, ip-based-access, temporal-access, github, gdrive, expenses, iot, slack, entitlements, custom-roles] + store-name: [advanced-entitlements, banking, groups-resource-attributes, ip-based-access, temporal-access, github, gdrive, expenses, iot, slack, entitlements, custom-roles, superadmin] steps: - name: Checkout diff --git a/stores/github/tuples.yaml b/stores/github/tuples.yaml new file mode 100644 index 0000000..e69de29 diff --git a/stores/superadmin/README.md b/stores/superadmin/README.md new file mode 100644 index 0000000..ef73a1b --- /dev/null +++ b/stores/superadmin/README.md @@ -0,0 +1,26 @@ +# OpenFGA Super Admin Example + +## Use-Case + +In B2B SaaS applications, each customer usually has one or more admin users that have full permission over the account. + +It's also common that employees of the SaaS company can perform specific actions across different accounts, for configuration or help desk purposes. + +Let's assume we want to build a simple multi-tenant SaaS Project management system, with the following roles: + +- **System Administrator**: Can perform any action in the system. +- **Help-Desk User**: Can be granted permissions to view any resource for a specific customer, for 1 hour. Note that from a security best practices perspective, it would be optimal to only have temporal access for all super-admin users too. +- **Customer Administrator**: Can perform any action for any resource linked to a specific customer. +- **System Management Service App**: A service application that can perform any action in the system. + +The application will have two kinds of resources: +- **Project** +- **Tasks** + +See the model, tuples and tests in the [store.yaml](./store.fga.yaml) file. + +## Try It Out + +1. Make sure you have the [FGA CLI](https://github.com/openfga/cli/?tab=readme-ov-file#installation) + +2. In the `slack` directory, run `fga model test --tests store.yaml` diff --git a/stores/superadmin/store.fga.yaml b/stores/superadmin/store.fga.yaml new file mode 100644 index 0000000..43daefa --- /dev/null +++ b/stores/superadmin/store.fga.yaml @@ -0,0 +1,133 @@ +model: | + model + schema 1.1 + + # user = users from the customer's organization + type user + + # employee = employees of the SaaS vendor + type employee + + # application = internal applications that need to perform maintenance tasks + type application + + # top level type where we define system administrators, note that we are only defining + # superadmins but there could be other roles that would have restricted permissions + type system + relations + define admin : [employee, application] + + # organization represent the SaaS customer + type organization + relations + define system : [system] + + # system admins have the same permissions in the organization as + # customer admins + define admin : [user] or admin from system + define member : [user] + + # we could define helpdesk members at the system level too without + # a time expiration, but time bounding access help desk access + # for a specific customer is a better security practice + define helpdesk_member : [employee with non_expired_time_grant] + + define can_create_project : admin or member + + type project + relations + define organization : [organization] + define owner : [user] + + # admins from the organization have editor permission in all projects + define editor : [user] or owner or admin from organization + define viewer : [user] or editor or helpdesk_member from organization + + type task + relations + define project: [project] + define owner : [user] + + # tasks inherit the system admins + helpdesk member permissions from the project + define editor : [user] or editor from project + define viewer : [user] or editor or viewer from project + + condition non_expired_time_grant(current_time: timestamp, grant_time: timestamp, grant_duration: duration) { + current_time < grant_time + grant_duration + } + +tuples: + # we define a user and an application as 'super admins' + - user: employee:anne + relation : admin + object: system:global + - user: application:system-management-app + relation : admin + object: system:global + + # this tuple connects the global 'system' with each organization, and needs to be created + # for all organizations + - user: system:global + relation: system + object: organization:acme + + # we grant access to a help desk user for 1 hour + - user: employee:john + relation: helpdesk_member + object: organization:acme + condition: + name: non_expired_time_grant + context: + grant_time : "2024-01-01T00:00:00Z" + grant_duration : 1h + + # peter is the organization's admin + - user: user:peter + relation: admin + object: organization:acme + + # we add the tuples for the project and for a task in the project + - user: organization:acme + relation: organization + object: project:openfga + + - user: project:openfga + relation: project + object: task:create-example + +tests: + - check: + # anne is a super admin, has full access + - user: employee:anne + object: task:create-example + assertions: + viewer: true + editor: true + + # peter is an admin in the organization, has full access + - user: user:peter + object: task:create-example + assertions: + viewer: true + editor: true + + # the system application has full access + - user: application:system-management-app + object: task:create-example + assertions: + viewer: true + editor: true + + # john only has temporary access as viewer + - user: employee:john + object: task:create-example + context: + current_time: "2024-01-01T00:10:00Z" + assertions: + viewer: true + editor: false + + + + + \ No newline at end of file