From c33c5f72b4aeba02057f24cb0693f361ba12dd77 Mon Sep 17 00:00:00 2001 From: Jonas Juselius Date: Fri, 30 Aug 2024 15:57:12 +0200 Subject: [PATCH] feat: updated model and tests. working v1.0 --- README.md | 6 ++ fga.mod | 50 +----------- model.fga | 60 ++++++++++++++ scripts/clean_tuples.sh | 1 + shell.nix | 2 +- test.fga.yaml | 172 ++++++++++++++++++++++++++++++++++++++++ tuples.fga.csv | 33 ++++++++ tuples.json | 58 -------------- 8 files changed, 276 insertions(+), 106 deletions(-) create mode 100644 README.md create mode 100644 model.fga create mode 100644 scripts/clean_tuples.sh create mode 100644 test.fga.yaml create mode 100644 tuples.fga.csv delete mode 100644 tuples.json diff --git a/README.md b/README.md new file mode 100644 index 0000000..4c76de8 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# Atlantis FGA model + +To test the model run: +``` +fga model test --tests test.fga.model +``` diff --git a/fga.mod b/fga.mod index c39ac44..22e5172 100644 --- a/fga.mod +++ b/fga.mod @@ -1,48 +1,4 @@ -model - schema 1.1 - -type system - relations - define can_create_organization: [ user, group#member ] or superuser - define superuser: [ user, group#member ] - -type organization - relations - define can_create_group: admin or superuser from system - define member: [ group#member ] - define admin: [ user ] or superuser from system - define system: [ system ] - -type group - relations - define member: [ user, group#member ] - define admin: [ user ] or admin from org - define can_impersonate: admin - define org: [ organization ] - -type user - relations - define can_edit_profile: [ user ] - define can_view_profile: [ user ] or admin from group - define group: [ group ] - -tyoe license - relations - define view: [ user with valid_time, group#member with valid_time ] - define run: [ user with valid_time, group#member with valid_time ] and view - -type archive - relations - define edit: [ user ] or admin - define view: view from license - define run: run from license - define run_any: [ user, group#member ] and view and run - define run_transport: ([ user, group#member ] or run_any) and view and run - define run_sedimentation: ([ user, group#member ] or run_any) and view and run - define run_wc: ([ user, group#member ] or run_any) and view and run - define admin: [ user ] or admin from group - define group: [ group ] - define license: [ license ] - -condition valid_time(now: timestamp, start_time: timestamp, end_time: timestamp) { now >= start_time && now <= end_time } +schema: "1.2" +contents: + - model.fga diff --git a/model.fga b/model.fga new file mode 100644 index 0000000..64e28b5 --- /dev/null +++ b/model.fga @@ -0,0 +1,60 @@ +module model + +type system + relations + define can_create_organization: [ user, group#member ] or superuser + define superuser: [ user, group#member ] + +type organization + relations + define can_create_group: admin or superuser from parent + define member: [ group#member ] + define admin: [ user ] or superuser from parent + define parent: [ system ] + +type group + relations + define member: [ user, group#member ] + define admin: [ user ] or admin from parent + define can_impersonate: admin + define parent: [ organization ] + +type user + relations + define can_edit_profile: [ user ] + define can_view_profile: [ user ] or admin from group + define group: [ group ] + +type grant + relations + define read: [ + user with valid_period, + user:* with valid_period, + group#member with valid_period + ] or execute + define execute: [ user with valid_allocation, group#member with valid_allocation ] + +type archive + relations + define can_edit: owner or admin + define can_view: owner or admin or read from has_grant or execute from has_grant + define can_share: owner or admin + define can_run: execute from has_grant + define run_any: [ user, group#member ] and can_view and can_run + define run_transport: ([ user, group#member ] or run_any) and can_run + define run_sedimentation: ([ user, group#member ] or run_any) and can_run + define run_wc: ([ user, group#member ] or run_any) and can_run + define owner: [ user ] + define admin: [ user ] or admin from parent + define parent: [ group ] + define has_grant: [ grant ] + +condition valid_period(time: timestamp, start_time: timestamp, end_time: timestamp) { + start_time == end_time || // no time restriction + (time >= start_time && time <= end_time) + } + +condition valid_allocation(usage: double, quota: double, time: timestamp, start_time: timestamp, end_time: timestamp) { + (start_time == end_time || time >= start_time && time <= end_time) && + (quota < 0.0 || usage < quota) + } \ No newline at end of file diff --git a/scripts/clean_tuples.sh b/scripts/clean_tuples.sh new file mode 100644 index 0000000..86f1138 --- /dev/null +++ b/scripts/clean_tuples.sh @@ -0,0 +1 @@ +fga tuple read | jq '[ .tuples[] | .key ]' diff --git a/shell.nix b/shell.nix index 268d0f6..d7d286f 100644 --- a/shell.nix +++ b/shell.nix @@ -6,6 +6,6 @@ pkgs.mkShell { FGA_API_URL = "https://openfga.dev.oceanbox.io"; FGA_STORE_ID = "01J6C1NBX36E1B928HFSB123XQ"; - FGA_MODEL_ID = "01J6FK82QP8TER7MXD8F4AVJJK"; + # FGA_MODEL_ID = ""; # FGA_API_TOKEN = ""; } diff --git a/test.fga.yaml b/test.fga.yaml new file mode 100644 index 0000000..716fd4c --- /dev/null +++ b/test.fga.yaml @@ -0,0 +1,172 @@ +name: Model tests +model_file: fga.mod +tuple_file: tuples.fga.csv +tests: +- name: Organization membership + check: + - user: user:a + object: organization:acme + assertions: + member: true + admin: false + + - user: user:b + object: organization:acme + assertions: + member: true + admin: true + + - user: user:root + object: organization:acme + assertions: + member: false + admin: true + +- name: list objects + list_objects: + - user: user:a + type: archive + context: + time: "2024-01-01T00:10:00Z" + usage: 10.0 + assertions: + can_view: + - archive:a + can_run: + - archive:a + + - user: user:b + type: archive + context: + time: "2024-01-01T00:10:00Z" + usage: 10.0 + assertions: + can_view: + - archive:a + - archive:b + can_run: + - archive:b + + - user: user:b + type: archive + context: + time: "2025-01-01T00:10:00Z" + usage: 101.0 + assertions: + can_view: + - archive:a # as admin + can_run: [] + + - user: user:c + type: archive + context: + time: "2024-01-01T00:10:00Z" + usage: 0.0 + assertions: + can_view: + - archive:b + can_run: [] + + - user: user:d + type: archive + context: + time: "2025-01-01T00:10:00Z" + usage: 101.0 + assertions: + can_view: + - archive:a + can_run: + - archive:a + +- name: list grants + list_users: + - object: grant:a + user_filter: + - type: user + context: + time: "2024-01-01T00:10:00Z" + usage: 0.0 + assertions: + read: + users: + - user:a + - user:b + - user:d + execute: + users: + - user:a + - user:d + + - object: grant:a + user_filter: + - type: user + context: + time: "2025-01-01T00:10:00Z" + usage: 101.0 + assertions: + read: + users: + - user:d + execute: + users: + - user:d + + - object: grant:b + user_filter: + - type: user + context: + time: "2024-01-01T00:10:00Z" + usage: 1.0 + assertions: + read: + users: + - user:b + - user:c + execute: + users: + - user:b + + - object: grant:b + user_filter: + - type: user + context: + time: "2025-01-01T00:10:00Z" + usage: 101.0 + assertions: + read: + users: [] + execute: + users: [] + +- name: list archives + list_users: + - object: archive:a + user_filter: + - type: user + context: + time: "2024-01-01T00:10:00Z" + usage: 99.0 + assertions: + can_view: + users: + - user:a + - user:b + - user:d + - user:root + can_run: + users: + - user:a + - user:d + + - object: archive:b + user_filter: + - type: user + context: + time: "2025-01-01T00:10:00Z" + usage: 999.0 + assertions: + can_view: + users: + - user:root + can_run: + users: [] \ No newline at end of file diff --git a/tuples.fga.csv b/tuples.fga.csv new file mode 100644 index 0000000..c30d0fc --- /dev/null +++ b/tuples.fga.csv @@ -0,0 +1,33 @@ +user_type,user_id,relation,object_type,object_id,condition_name,condition_context + +user,root,superuser,system,atlantis,, + +system,atlantis,parent,organization,acme,, +system,atlantis,parent,organization,newco,, + +organization,acme,parent,group,a,, +organization,acme,parent,group,b,, +organization,newco,parent,group,c,, + +group,a#member,member,organization,acme,, +group,b#member,member,organization,acme,, +group,c#member,member,organization,newco,, + +user,a,member,group,a,, +user,b,member,group,b,, +user,c,member,group,c,, + +user,b,admin,organization,acme,, + +group,a,parent,archive,a,, +group,b,parent,archive,a,, +group,c,parent,archive,b,, + +group,a#member,execute,grant,a,valid_allocation,"{""quota"": ""100.0"", ""start_time"": ""2024-01-01T00:00:00Z"", ""end_time"": ""2025-01-01T00:00:00Z""}" +group,b#member,read,grant,a,valid_period,"{""start_time"": ""2024-01-01T00:00:00Z"", ""end_time"": ""2025-01-01T00:00:00Z""}" +group,b#member,execute,grant,b,valid_allocation,"{""quota"": ""100.0"", ""start_time"": ""2024-01-01T00:00:00Z"", ""end_time"": ""2025-01-01T00:00:00Z""}" +group,c#member,read,grant,b,valid_period,"{""start_time"": ""2024-01-01T00:00:00Z"", ""end_time"": ""2025-01-01T00:00:00Z""}" +user,d,execute,grant,a,valid_allocation,"{""quota"": ""-1.0"", ""start_time"": ""2024-01-01T00:00:00Z"", ""end_time"": ""2024-01-01T00:00:00Z""}" + +grant,a,has_grant,archive,a,, +grant,b,has_grant,archive,b,, diff --git a/tuples.json b/tuples.json deleted file mode 100644 index b09b67f..0000000 --- a/tuples.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "continuation_token":"", - "tuples": [ - { - "key": { - "condition": { - "context": { - "start_time":"2024-08-01T00:00:00Z" - }, - "name":"valid_time" - }, - "object":"archive:a", - "relation":"view", - "user":"group:a#member" - }, - "timestamp":"2024-08-29T16:37:55.474797Z" - }, - { - "key": { - "object":"group:a", - "relation":"member", - "user":"user:a" - }, - "timestamp":"2024-08-29T16:45:07.056316Z" - }, - { - "key": { - "object":"archive:a", - "relation":"run_transport", - "user":"group:a#member" - }, - "timestamp":"2024-08-29T17:04:35.100234Z" - }, - { - "key": { - "condition": { - "context": { - "end_time":"2024-09-01T00:00:00Z", - "start_time":"2024-08-01T00:00:00Z" - }, - "name":"valid_time" - }, - "object":"archive:a", - "relation":"run", - "user":"group:a#member" - }, - "timestamp":"2024-08-29T17:41:35.007293Z" - }, - { - "key": { - "object":"archive:a", - "relation":"run_any", - "user":"group:a#member" - }, - "timestamp":"2024-08-29T17:42:54.720477Z" - } - ] -}