diff --git a/identity-and-access-management/README.md b/identity-and-access-management/README.md index d4c1181..f3db8c1 100644 --- a/identity-and-access-management/README.md +++ b/identity-and-access-management/README.md @@ -1,15 +1,11 @@ # Identity and access management -## Compatibility note - -**This demo has not yet been updated to be compatible with TypeDB 3.0** - ## Introduction In this demo, you'll learn how to use TypeDB as the database for an identity and access management system. We'll cover some basic operations like listing the users in the system and see how queries can be simplified by taking advantage of TypeDB's in-built type-inference and polymorphism, then move on to some more advanced examples that take advantage of -rule-inference. We'll see how we can automate permission inheritance and enforce a dynamic segregation-of-duty policy at +TypeQL functions. We'll see how we can automate permission inheritance and enforce a dynamic segregation-of-duty policy at the schema level. ![Screenshot 2023-06-16 at 13 02 19](https://github.com/james-whiteside/typedb-examples/assets/117453030/f601ae73-1e43-455e-b7c1-226ce453967d) @@ -19,31 +15,31 @@ the schema level. This demo assumes knowledge of: - [General identity and access management concepts](https://en.wikipedia.org/wiki/Identity_management). -- [TypeDB's transaction system](https://typedb.com/docs/typedb/2.x/development/connect.html). -- [All basic TypeQL syntax elements](https://typedb.com/docs/typedb/2.x/dev/match.html). -- [TypeDB Studio's interface](https://typedb.com/docs/clients/2.x/studio.html). +- [TypeDB's transaction system](https://typedb.com/docs/manual/queries/transactions). +- [All basic TypeQL syntax elements](https://typedb.com/docs/typeql/pipelines/). +- [TypeDB Studio](https://studio.typedb.com). ## Getting started -Start your TypeDB server and open TypeDB Studio. Make sure you are on a `schema-write` transaction and run the following +Start your TypeDB server and open TypeDB Studio. Make sure you are on a `schema` transaction and run the following TypeQL file: -```define-schema.tql``` +```schema.tql``` -Then switch to a `data-write` transaction and run the following: +Then switch to a `write` transaction and run the following: -```insert-data.tql``` +```data.tql``` Remember to click on the green tick after running each of these scripts to commit the changes to the database. ## Running the examples To get started, try running the examples. They are intended to be run once each and in order, so be aware that running -them more than once or out of order might generate data errors. If anything goes wrong, you can run the -`insert-data.tql` script again to reset everything. All the examples use `data` sessions, but you'll have to switch -between `read` and `write` transactions depending on the queries in the example, and remember to commit after writes. +them more than once or out of order might generate data errors. If anything goes wrong, you can delete the dataabase & +run the `setup-script.tqls` script again to reset everything. For the examples, you'll have to switch between +`read` and `write` transactions depending on the queries in the example, and remember to commit after writes. Each example has an accompanying exercise. You can skip them out and all the examples will still run fine. Some are -much harder than others! All the solutions are in the `solutions.tql` file. +much harder than others! All the solutions are in the `exercise-solutions.tql` file. ## Next steps @@ -51,4 +47,4 @@ Once you've tried the pre-written examples out, have a go at editing them or wri has a lot of types that are not used in the example dataset, so try experimenting with those. Remember you can view the list of types in the Type Browser, or view the schema in the graph visualizer by running the query: -```match $t sub thing;``` +```match $t sub $s;``` diff --git a/identity-and-access-management/define-schema.tql b/identity-and-access-management/define-schema.tql deleted file mode 100644 index 3f299ee..0000000 --- a/identity-and-access-management/define-schema.tql +++ /dev/null @@ -1,364 +0,0 @@ -# -# Copyright (C) 2023 Vaticle -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -define - -#-------------------------------------------------- -# Core entity types: - -subject sub entity, - abstract, - owns credential; - -user sub subject, - abstract; - -user-group sub subject, - abstract; - -object sub entity, - abstract, - owns object-type; - -resource sub object, - abstract; - -resource-collection sub object, - abstract; - -action sub entity, - abstract, - owns name, - owns object-type; - -operation sub action; - -operation-set sub action; - -#-------------------------------------------------- -# Membership and ownership relation types: - -membership sub relation, - abstract, - relates parent, - relates member; - -group-membership sub membership, - relates user-group as parent, - relates group-member as member; - -inherited-group-membership sub group-membership; - -collection-membership sub membership, - relates resource-collection as parent, - relates collection-member as member; - -inherited-collection-membership sub collection-membership; - -set-membership sub membership, - relates operation-set as parent, - relates set-member as member; - -inherited-set-membership sub set-membership; - -user-group plays group-membership:user-group; -subject plays group-membership:group-member; -resource-collection plays collection-membership:resource-collection; -object plays collection-membership:collection-member; -operation-set plays set-membership:operation-set; -action plays set-membership:set-member; - -ownership sub relation, - abstract, - relates owned, - relates owner; - -group-ownership sub ownership, - relates owned-group as owned, - relates group-owner as owner, - owns ownership-type; - -object-ownership sub ownership, - relates owned-object as owned, - relates object-owner as owner, - owns ownership-type; - -user-group plays group-ownership:owned-group; -subject plays group-ownership:group-owner; -object plays object-ownership:owned-object; -subject plays object-ownership:object-owner; - -#-------------------------------------------------- -# Access and permission relation types: - -access sub relation, - relates accessed-object, - relates valid-action; - -object plays access:accessed-object; -action plays access:valid-action; - -permission sub relation, - relates permitted-subject, - relates permitted-access, - owns review-date, - owns validity; - -direct-permission sub permission; - -inherited-permission sub permission; - -subject plays permission:permitted-subject; -access plays permission:permitted-access; - -change-request sub relation, - relates requesting-subject, - relates requested-subject, - relates requested-change; - -subject plays change-request:requesting-subject; -subject plays change-request:requested-subject; -access plays change-request:requested-change; - -access-history sub relation, - relates accessing-subject, - relates exercised-access, - owns access-time; - -subject plays access-history:accessing-subject; -access plays access-history:exercised-access; - -#-------------------------------------------------- -# Policy and violation relation types: - -segregation-policy sub relation, - relates segregated-action, - owns name; - -static-segregation-policy sub segregation-policy; - -dynamic-segregation-policy sub segregation-policy; - -action plays segregation-policy:segregated-action; - -violation sub relation, - abstract; - -segregation-violation sub violation, - relates violating-subject, - relates violating-object, - relates violated-policy; - -subject plays segregation-violation:violating-subject; -object plays segregation-violation:violating-object; -segregation-policy plays segregation-violation:violated-policy; - -#-------------------------------------------------- -# Core entity subtypes: - -employee sub user, - owns full-name, - owns email; - -contractor sub user, - owns full-name, - owns email; - -business-unit sub user-group, - owns name; - -user-role sub user-group, - owns name; - -user-account sub user-group, - owns email; - -file sub resource, - owns path; - -purchase-order sub resource, - owns reference; - -customer-account sub resource, - owns email; - -record sub resource, - owns primary-key; - -pull-request sub resource, - owns hash; - -directory sub resource-collection, - owns path; - -application sub resource-collection, - owns name; - -database sub resource-collection, - owns name; - -table sub resource-collection, - owns name; - -branch sub resource-collection, - owns name; - -repository sub resource-collection, - owns name; - -#-------------------------------------------------- -# Attribute types: - -credential sub attribute, value string; -object-type sub attribute, value string; -id sub attribute, abstract, value string; -name sub id, value string; -ownership-type sub attribute, value string; -review-date sub attribute, value datetime; -validity sub attribute, value boolean; -email sub id, value string; -path sub id, value string; -reference sub id, value string; -primary-key sub id, value string; -hash sub id, value string; -full-name sub attribute, value string; -access-time sub attribute, value datetime; - -#-------------------------------------------------- -# Rules: - -# These rules contain a number of lines that are unnecessary for the rule to function, but add additional context useful -# for showing explanations in the graph visualiser during this demonstration. When adapting these rules for production, -# these lines can be safely removed from the rules. - -rule transitive-group-membership: - when { - (user-group: $g1, group-member: $g2) isa group-membership; - (user-group: $g2, group-member: $s) isa! group-membership; - $g1 has id $g1-id; # Unnecessary line, see note above. - $g2 has id $g2-id; # Unnecessary line, see note above. - $s has id $s-id; # Unnecessary line, see note above. - } then { - (user-group: $g1, group-member: $s) isa inherited-group-membership; - }; - -rule transitive-collection-membership: - when { - (resource-collection: $c1, collection-member: $c2) isa collection-membership; - (resource-collection: $c2, collection-member: $o) isa! collection-membership; - $c1 has id $c1-id; # Unnecessary line, see note above. - $c2 has id $c2-id; # Unnecessary line, see note above. - $o has id $o-id; # Unnecessary line, see note above. - } then { - (resource-collection: $c1, collection-member: $o) isa inherited-collection-membership; - }; - -rule transitive-set-membership: - when { - (operation-set: $s1, set-member: $s2) isa set-membership; - (operation-set: $s2, set-member: $a) isa! set-membership; - $s1 has id $s1-id; # Unnecessary line, see note above. - $s2 has id $s2-id; # Unnecessary line, see note above. - $a has id $a-id; # Unnecessary line, see note above. - } then { - (operation-set: $s1, set-member: $a) isa inherited-set-membership; - }; - -rule permission-inheritance: - when { - $s isa subject; - $ac (accessed-object: $o, valid-action: $a) isa access; - $ac2 (accessed-object: $o2, valid-action: $a2) isa access; - (permitted-subject: $s2, permitted-access: $ac2) isa direct-permission; - $s has id $s-id; # Unnecessary line, see note above. - $o has id $o-id; # Unnecessary line, see note above. - $a has id $a-id; # Unnecessary line, see note above. - $s2 has id $s2-id; # Unnecessary line, see note above. - $o2 has id $o2-id; # Unnecessary line, see note above. - $a2 has id $a2-id; # Unnecessary line, see note above. - { - (user-group: $s2, group-member: $s) isa group-membership; - } or { - $s2 is $s; - }; - { - (resource-collection: $o2, collection-member: $o) isa collection-membership; - } or { - $o2 is $o; - }; - { - (operation-set: $a2, set-member: $a) isa set-membership; - } or { - $a2 is $a; - }; - } then { - (permitted-subject: $s, permitted-access: $ac) isa inherited-permission; - }; - -rule static-segregation-violation-detection: - when { - $po (segregated-action: $a1, segregated-action: $a2) isa static-segregation-policy; - $ac1 (accessed-object: $o, valid-action: $a1) isa access; - $ac2 (accessed-object: $o, valid-action: $a2) isa access; - $p1 (permitted-subject: $s, permitted-access: $ac1) isa permission; - $p2 (permitted-subject: $s, permitted-access: $ac2) isa permission; - $a1 has id $a1-id; # Unnecessary line, see note above. - $a2 has id $a2-id; # Unnecessary line, see note above. - $po has id $po-id; # Unnecessary line, see note above. - $o has id $o-id; # Unnecessary line, see note above. - $s has id $s-id; # Unnecessary line, see note above. - } then { - (violating-subject: $s, violating-object: $o, violated-policy: $po) isa segregation-violation; - }; - -rule automatic-permission-invalidity: - when { - $ac1 (accessed-object: $o, valid-action: $a1) isa access; - $ac2 (accessed-object: $o, valid-action: $a2) isa access; - $p1 (permitted-subject: $s, permitted-access: $ac1) isa permission; - $o has id $o-id; # Unnecessary line, see note above. - $a1 has id $a1-id; # Unnecessary line, see note above. - $a2 has id $a2-id; # Unnecessary line, see note above. - $s has id $s-id; # Unnecessary line, see note above. - { - $po (segregated-action: $a1, segregated-action: $a2) isa static-segregation-policy; - $p2 (permitted-subject: $s, permitted-access: $ac2) isa permission; - $po has id $po-id; # Unnecessary line, see note above. - } or { - $po (segregated-action: $a1, segregated-action: $a2) isa dynamic-segregation-policy; - $ah (accessing-subject: $s, exercised-access: $ac2) isa access-history; - $po has id $po-id; # Unnecessary line, see note above. - }; - } then { - $p1 has validity false; - }; - -rule automatic-permission-validity: - when { - $p isa permission; - not { - $p has validity false; - }; - } then { - $p has validity true; - }; - -#-------------------------------------------------- diff --git a/identity-and-access-management/examples/02-list-user-groups.tql b/identity-and-access-management/examples/02-list-user-groups.tql index 1d174cc..f055357 100644 --- a/identity-and-access-management/examples/02-list-user-groups.tql +++ b/identity-and-access-management/examples/02-list-user-groups.tql @@ -13,28 +13,25 @@ $gm ($ug, $u) isa group-membership; # our group membership, we've declared the roleplayers but not the roles they play. This is because there is only one # logical way that the roleplayers can play these roles, so we let TypeDB's type inference firgure that out for us. # -# When we run this query, we get a few results, but let's try toggling the inference button at the top to switch on -# TypeDB's rule-inference. Now if we run the query again, we get many more results shown in a green outline. This is -# because of a rule encoded into the schema: +# When we run this query, we get a few results but these do not include the transitive memberships. +# Using the group_memberships function in the schema, we can get the groups that a user is transitively a member of. # -# rule transitive-group-membership: -# when { -# (group: $g1, group-member: $g2) isa group-membership; -# (group: $g2, group-member: $s) isa! group-membership; -# } then { -# (group: $g1, group-member: $s) isa inherited-group-membership; -# }; -# -# This rule makes membership of user groups transitive. Take Clarissa Mao for example. She is a member of the web admin -# user role, and that role is a member of the web editor user role. This is because all web admins are also web editors -# by default, and can do anything a web editor can (and more). We know that this means Clarissa is a web editor, but we -# haven't written this fact to the database. With rule-inference, we don't need to, because we can encapsulate the -# business logic of transitive membership in a high-level rule and let TypeDB do the legwork for us. +match +$u isa user, has full-name $fn; +$ug isa user-group, has id $id; +let $ug in group_memberships($u); + +# This function defines the transitive closure of user group memberships. Take Clarissa Mao for example. +# She is a member of the web admin user role, and that role is a member of the web editor user role. +# This is because all web admins are also web editors by default, and can do anything a web editor can (and more). +# We know that this means Clarissa is a web editor, but we haven't written this fact to the database. +# With functions, we don't need to, because we can encapsulate the business logic of transitive membership +# in a high-level function and let TypeDB do the legwork for us. #-------------------------------------------------- # Exercise 02: -# Edit this query to list the number of user groups each person is in by name. Try running it with inference off and on. -# Keyword hints: group, count +# Edit this query to list the number of user groups each person is in by name. +# Keyword hints: reduce, count, groupby #-------------------------------------------------- diff --git a/identity-and-access-management/examples/04-list-user-permissions.tql b/identity-and-access-management/examples/04-list-user-permissions.tql index 19a84b5..40027cd 100644 --- a/identity-and-access-management/examples/04-list-user-permissions.tql +++ b/identity-and-access-management/examples/04-list-user-permissions.tql @@ -6,45 +6,32 @@ match $e isa employee, has email "filip.inaros@vaticle.com"; $o isa object, has id $id; $a isa action, has name $n; -$ac ($o, $a) isa access; -$p ($e, $ac) isa permission; +$ac isa access, links ($o, $a); +$p isa direct-permission, links ($e, $ac); -# This won't return any results with rule-inference switched off as we haven't explicitly given him any permissions, but -# if we run it with rule-inference switched on, we see that Filip automatically inherits all the permissions he should -# as a member of the Cloud Team. This is thanks to a set of rules encoded into our schema that automate permission -# inheritance for us: -# -# rule permission-inheritance: -# when { -# $s isa subject; -# $ac (object: $o, action: $a) isa access; -# $ac2 (object: $o2, action: $a2) isa access; -# (subject: $s2, access: $ac2) isa direct-permission; -# { -# (group: $s2, group-member: $s) isa group-membership; -# } or { -# $s2 is $s; -# }; -# { -# (collection: $o2, collection-member: $o) isa collection-membership; -# } or { -# $o2 is $o; -# }; -# { -# (set: $a2, set-member: $a) isa set-membership; -# } or { -# $a2 is $a; -# }; -# } then { -# (subject: $s, access: $ac) isa inherited-permission; -# }; +# This won't return any results as we haven't explicitly granted him any permissions, but if we use +# the `list_permissions`function, we see that Filip automatically inherits all the permissions he should +# as a member of the Cloud Team. + +match +$e isa employee, has email "filip.inaros@vaticle.com"; +let $ac in list_permissions($e); +$ac isa access, links ($o, $a); +$o isa object, has id $id; +$a isa action, has name $n; #-------------------------------------------------- # Exercise 04: -# Edit this query to return only a list of operations that Filip can perform on the directory -# "root/engineering/typedb-cloud". -# Keyword hints: get -# Type hints: directory, path, operation +# Update this to query the operations that Filip can perform on the directory "root/engineering/typedb-cloud". +# Use the `has_permission` function to check if he has permission to perform the operation. +# Type hints: directory, path, operation, == #-------------------------------------------------- +match +$e isa employee, has email "filip.inaros@vaticle.com"; +$o isa directory, has path "root/engineering/typedb-cloud"; +$a isa operation, has name $n; +$ac isa access ($o, $a); +true == has_permission($e, $ac); +select $n; \ No newline at end of file diff --git a/identity-and-access-management/examples/05-grant-permission.tql b/identity-and-access-management/examples/05-grant-permission.tql index 3076fae..790ff84 100644 --- a/identity-and-access-management/examples/05-grant-permission.tql +++ b/identity-and-access-management/examples/05-grant-permission.tql @@ -7,7 +7,7 @@ match $u isa user, has email "filip.inaros@vaticle.com"; $a isa application, has name "Sage"; $os isa operation-set, has name "manage order"; -$ac ($a, $os) isa access; +$ac isa access, links ($a, $os); insert (permitted-subject: $u, permitted-access: $ac) isa direct-permission; @@ -17,8 +17,10 @@ insert #-------------------------------------------------- # Exercise 05: +# If a user has permission for an operation-set, they automatically have permission to perform all operations in the operation-set. # Write a new query that shows what individual permissions a user will get through the operation set "manage order". -# Keyword hints: match +# Keyword hints: match, let..in # Type hints: operation-set, operation, name +# Function hints: set_members(operation-set) #-------------------------------------------------- diff --git a/identity-and-access-management/examples/07-check-user-permission-1.tql b/identity-and-access-management/examples/07-check-user-permission-1.tql index 2a1aeb4..a610650 100644 --- a/identity-and-access-management/examples/07-check-user-permission-1.tql +++ b/identity-and-access-management/examples/07-check-user-permission-1.tql @@ -8,17 +8,15 @@ match $u isa user, has email "filip.inaros@vaticle.com"; $po isa purchase-order, has reference "MCRN-02"; $o isa operation, has name "submit order"; -$ac ($po, $o) isa access; -$p ($u, $ac) isa permission, has validity true; +$ac isa access ($po, $o) ; +true == has_permission($u, $ac); +false == violates_policies($u, $ac); + # This successfully returns a result, meaning that Filip has permission to submit the order. #-------------------------------------------------- # Exercise 07: - -# Use TypeDB Studio's explanations feature to find out how Filip inheritted this permission. To switch on -# explanations, toggle the "snapshot", "infer", and "explain" buttons to on. After executing the query, double-click on -# an inferred concept (one with a green outline) to find out how it was inferred from a rule. After using the -# explanations feature, remember to close the transaction with the "⨉" button. - +# (TODO: explanations are not yet implemented in studio) +# Use TypeDB Studio's explanations feature to find out how Filip inheritted this permission. #-------------------------------------------------- diff --git a/identity-and-access-management/examples/08-record-access-history.tql b/identity-and-access-management/examples/08-record-access-history.tql index 128104d..906caff 100644 --- a/identity-and-access-management/examples/08-record-access-history.tql +++ b/identity-and-access-management/examples/08-record-access-history.tql @@ -6,7 +6,7 @@ match $u isa user, has email "filip.inaros@vaticle.com"; $po isa purchase-order, has reference "MCRN-02"; $o isa operation, has name "submit order"; -$ac ($po, $o) isa access; +$ac isa access ($po, $o); insert (accessing-subject: $u, exercised-access: $ac) isa access-history, has access-time 2023-05-16T11:20:38; diff --git a/identity-and-access-management/examples/09-check-user-permission-2.tql b/identity-and-access-management/examples/09-check-user-permission-2.tql index a1e89d2..46a87c5 100644 --- a/identity-and-access-management/examples/09-check-user-permission-2.tql +++ b/identity-and-access-management/examples/09-check-user-permission-2.tql @@ -7,40 +7,46 @@ match $u isa user, has email "filip.inaros@vaticle.com"; $po isa purchase-order, has reference "MCRN-02"; $o isa operation, has name "approve order"; -$ac ($po, $o) isa access; -$p ($u, $ac) isa permission, has validity true; +$ac isa access ($po, $o); +true == has_permission($u, $ac); +false == violates_policies($u, $ac); # This time, we get no results returned. This is because the dynamic segregation policy we defined has automatically -# flagged this permission as being invalid because Filip was the one who submitted this purchase order. This logic is -# encoded in the schema with the following rule: -# -# rule automatic-permission-invalidity: -# when { -# $ac1(object: $o, action: $a1) isa access; -# $ac2(object: $o, action: $a2) isa access; -# $p1(subject: $s, access: $ac1) isa permission; -# { -# $po(action: $a1, action: $a2) isa static-segregation-policy; -# $p2(subject: $s, access: $ac2) isa permission; -# } or { -# $po(action: $a1, action: $a2) isa dynamic-segregation-policy; -# $p2(subject: $s, access: $ac2) isa access-history; -# }; -# } then { -# $p1 has validity false; +# flagged this permission as being invalid because Filip was the one who submitted this purchase order. +# The segregation policy functions encode the logic needed to determine whether a permission is valid or not. + + +# fun segregation_policies_violated($s: subject, $ac1: access) -> { segregation-policy }: +# match +# $ac1 isa access (accessed-object: $o, valid-action: $a1); +# { +# $po isa static-segregation-policy (segregated-action: $a1, segregated-action: $a2); +# $ac2 isa access (accessed-object: $o, valid-action: $a2); +# true == has_permission($s, $ac2); +# } or { +# $po isa dynamic-segregation-policy (segregated-action: $a1, segregated-action: $a2) ; +# $ac2 isa access (accessed-object: $o, valid-action: $a2); +# $ah isa access-history (accessing-subject: $s, exercised-access: $ac2); # }; +# return { $po }; + +# fun violates_policies($s: subject, $ac1: access) -> boolean: +# match +# let $po in segregation_policies_violated($s, $ac1); +# return check; # -# This rule flags permissions as invalid under one of two conditions: if a subject simultaneously holds two permissions -# defined under a static segregation policy; or if a subject has at any point held two permissions defined under a -# dynamic segregation policy and has exercised one of them. The permissions flagged by this rule are only flagged for -# the specific combination of subject and object that have violated the policy, in this case Filip and Order MCRN-02. +# A segregation policy violating blocks an access under one of the two conditions: +# 1. A subject simultaneously holds two permissions defined under a static segregation policy; or +# 2. A subject attempts to perform - on a certain object - an action defined under a dynamic segregation policy, +# having previously performed the other action defined in the same policy - on the same object. +# In this case Filip attempted to "approve" the Order MCRN-02 having previously "submitted" the same order. # This means that Filip is still free to approve other orders, and other users are still free to approve this one. #-------------------------------------------------- # Exercise 09: # Edit this query to only list the names of users that are able to approve this purchase order for Filip. -# Keyword hints: get +# Keyword hints: select # Type hints: full-name #-------------------------------------------------- diff --git a/identity-and-access-management/examples/10-check-user-permission-3.tql b/identity-and-access-management/examples/10-check-user-permission-3.tql index 996400e..26ae83a 100644 --- a/identity-and-access-management/examples/10-check-user-permission-3.tql +++ b/identity-and-access-management/examples/10-check-user-permission-3.tql @@ -7,8 +7,10 @@ match $u isa user, has email "amos.burton@vaticle.com"; $po isa purchase-order, has reference "MCRN-02"; $o isa operation, has name "approve order"; -$ac ($po, $o) isa access; -$p ($u, $ac) isa permission, has validity true; +$ac isa access ($po, $o); +true == has_permission($u, $ac); +false == violates_policies($u, $ac); + # This successfully returns a result, which allows Amos to approve Filip's permission. diff --git a/identity-and-access-management/examples/exercise-solutions.tql b/identity-and-access-management/examples/exercise-solutions.tql index 40c5a60..3f95e10 100644 --- a/identity-and-access-management/examples/exercise-solutions.tql +++ b/identity-and-access-management/examples/exercise-solutions.tql @@ -15,9 +15,8 @@ $u isa employee, has full-name $fn, has email $e; match $u isa user, has full-name $fn; $ug isa user-group, has id $id; -$gm ($ug, $u) isa group-membership; -group $fn; -count; +let $ug in group_memberships($u); +reduce $c = count($ug) groupby $fn; #-------------------------------------------------- # Exercise 03 solution: @@ -34,9 +33,9 @@ match $e isa employee, has email "filip.inaros@vaticle.com"; $o isa directory, has path "root/engineering/typedb-cloud"; $a isa operation, has name $n; -$ac ($o, $a) isa access; -$p ($e, $ac) isa permission; -get $n; +$ac isa access ($o, $a); +true == has_permission($e, $ac); +select $n; #-------------------------------------------------- # Exercise 05 solution: @@ -44,7 +43,7 @@ get $n; match $o isa operation, has name $n; $os isa operation-set, has name "manage order"; -$sm ($os, $o) isa set-membership; +let $o in set_members($os); #-------------------------------------------------- # Exercise 06 solution: @@ -53,8 +52,9 @@ $sm ($os, $o) isa set-membership; match $a isa action, has name $n; $o isa pull-request; -($a, $o) isa access; -get $n; +$_ isa access ($a, $o); +select $n; +distinct; # Query to insert policy: match @@ -80,8 +80,8 @@ $u isa user, has email $e; $o isa! $type, has id $id; $type sub object; $op isa operation, has name $n; -$ac ($o, $op) isa access; -$h ($u, $ac) isa access-history, has access-time $at; +$ac isa access ($o, $op); +$h isa access-history ($u, $ac), has access-time $at; #-------------------------------------------------- # Exercise 09 solution: @@ -90,9 +90,10 @@ match $u isa user, has full-name $n; $po isa purchase-order, has reference "MCRN-02"; $o isa operation, has name "approve order"; -$ac ($po, $o) isa access; -$p ($u, $ac) isa permission, has validity true; -get $n; +$ac isa access ($po, $o); +true == has_permission($u, $ac); +false == violates_policies($u, $ac); +select $n; #-------------------------------------------------- # Exercise 10 solution: @@ -101,7 +102,7 @@ match $u isa user, has email "amos.burton@vaticle.com"; $po isa purchase-order, has reference "MCRN-02"; $o isa operation, has name "approve order"; -$ac ($po, $o) isa access; +$ac isa access ($po, $o); insert (accessing-subject: $u, exercised-access: $ac) isa access-history, has access-time 2023-05-16T15:07:47; diff --git a/identity-and-access-management/insert-data.tql b/identity-and-access-management/sample-data.tql similarity index 69% rename from identity-and-access-management/insert-data.tql rename to identity-and-access-management/sample-data.tql index af8df41..958fc99 100644 --- a/identity-and-access-management/insert-data.tql +++ b/identity-and-access-management/sample-data.tql @@ -22,250 +22,250 @@ #-------------------------------------------------- # Clean old data: -match $t isa thing; delete $t isa thing; -match $t isa user; insert $t has full-name "Rocinante"; +match $t isa $_; delete $t; end; +match $t isa user; insert $t has full-name "Rocinante"; end; #-------------------------------------------------- # Users: -insert $s isa contractor, has full-name "James Holden", has email "james.holden@rocinante-consulting.com"; # consultant engineer -insert $s isa employee, has full-name "Naomi Nagata", has email "naomi.nagata@vaticle.com"; # engineer (core) -insert $s isa employee, has full-name "Amos Burton", has email "amos.burton@vaticle.com"; # accountant -insert $s isa employee, has full-name "Alex Kamal", has email "alex.kamal@vaticle.com"; # engineer (cloud) -insert $s isa employee, has full-name "Bobbie Draper", has email "bobbie.draper@vaticle.com"; # sales rep -insert $s isa employee, has full-name "Clarissa Mao", has email "clarissa.mao@vaticle.com"; # engineer (web) -insert $s isa employee, has full-name "Joe Miller", has email "joe.miller@vaticle.com"; # support agent +insert $s isa contractor, has full-name "James Holden", has email "james.holden@rocinante-consulting.com"; end; # consultant engineer +insert $s isa employee, has full-name "Naomi Nagata", has email "naomi.nagata@vaticle.com"; end; # engineer (core) +insert $s isa employee, has full-name "Amos Burton", has email "amos.burton@vaticle.com"; end; # accountant +insert $s isa employee, has full-name "Alex Kamal", has email "alex.kamal@vaticle.com"; end; # engineer (cloud) +insert $s isa employee, has full-name "Bobbie Draper", has email "bobbie.draper@vaticle.com"; end; # sales rep +insert $s isa employee, has full-name "Clarissa Mao", has email "clarissa.mao@vaticle.com"; end; # engineer (web) +insert $s isa employee, has full-name "Joe Miller", has email "joe.miller@vaticle.com"; end; # support agent #-------------------------------------------------- # User groups: -insert $s isa business-unit, has name "Engineering"; -insert $s isa business-unit, has name "Core"; -insert $s isa business-unit, has name "Cloud"; -insert $s isa business-unit, has name "Web"; -insert $s isa business-unit, has name "Finance"; -insert $s isa business-unit, has name "Customer Support"; -insert $s isa user-role, has name "web admin"; -insert $s isa user-role, has name "web editor"; -insert $s isa user-role, has name "engineer"; -insert $s isa user-account, has email "sales@vaticle.com"; +insert $s isa business-unit, has name "Engineering"; end; +insert $s isa business-unit, has name "Core"; end; +insert $s isa business-unit, has name "Cloud"; end; +insert $s isa business-unit, has name "Web"; end; +insert $s isa business-unit, has name "Finance"; end; +insert $s isa business-unit, has name "Customer Support"; end; +insert $s isa user-role, has name "web admin"; end; +insert $s isa user-role, has name "web editor"; end; +insert $s isa user-role, has name "engineer"; end; +insert $s isa user-account, has email "sales@vaticle.com"; end; #-------------------------------------------------- # Group memberships: -match $s isa subject, has id "Engineering"; $g isa user-group, has id "engineer"; insert (user-group: $g, group-member: $s) isa group-membership; -match $s isa subject, has id "Cloud"; $g isa user-group, has id "Engineering"; insert (user-group: $g, group-member: $s) isa group-membership; -match $s isa subject, has id "Core"; $g isa user-group, has id "Engineering"; insert (user-group: $g, group-member: $s) isa group-membership; -match $s isa subject, has id "Web"; $g isa user-group, has id "Engineering"; insert (user-group: $g, group-member: $s) isa group-membership; -match $s isa subject, has id "web admin"; $g isa user-group, has id "web editor"; insert (user-group: $g, group-member: $s) isa group-membership; -match $s isa subject, has id "james.holden@rocinante-consulting.com"; $g isa user-group, has id "engineer"; insert (user-group: $g, group-member: $s) isa group-membership; -match $s isa subject, has id "naomi.nagata@vaticle.com"; $g isa user-group, has id "Core"; insert (user-group: $g, group-member: $s) isa group-membership; -match $s isa subject, has id "amos.burton@vaticle.com"; $g isa user-group, has id "Finance"; insert (user-group: $g, group-member: $s) isa group-membership; -match $s isa subject, has id "alex.kamal@vaticle.com"; $g isa user-group, has id "Cloud"; insert (user-group: $g, group-member: $s) isa group-membership; -match $s isa subject, has id "bobbie.draper@vaticle.com"; $g isa user-group, has id "sales@vaticle.com"; insert (user-group: $g, group-member: $s) isa group-membership; -match $s isa subject, has id "clarissa.mao@vaticle.com"; $g isa user-group, has id "Web"; insert (user-group: $g, group-member: $s) isa group-membership; -match $s isa subject, has id "clarissa.mao@vaticle.com"; $g isa user-group, has id "web admin"; insert (user-group: $g, group-member: $s) isa group-membership; -match $s isa subject, has id "joe.miller@vaticle.com"; $g isa user-group, has id "Customer Support"; insert (user-group: $g, group-member: $s) isa group-membership; +match $s isa subject, has id "Engineering"; $g isa user-group, has id "engineer"; insert (user-group: $g, group-member: $s) isa group-membership; end; +match $s isa subject, has id "Cloud"; $g isa user-group, has id "Engineering"; insert (user-group: $g, group-member: $s) isa group-membership; end; +match $s isa subject, has id "Core"; $g isa user-group, has id "Engineering"; insert (user-group: $g, group-member: $s) isa group-membership; end; +match $s isa subject, has id "Web"; $g isa user-group, has id "Engineering"; insert (user-group: $g, group-member: $s) isa group-membership; end; +match $s isa subject, has id "web admin"; $g isa user-group, has id "web editor"; insert (user-group: $g, group-member: $s) isa group-membership; end; +match $s isa subject, has id "james.holden@rocinante-consulting.com"; $g isa user-group, has id "engineer"; insert (user-group: $g, group-member: $s) isa group-membership; end; +match $s isa subject, has id "naomi.nagata@vaticle.com"; $g isa user-group, has id "Core"; insert (user-group: $g, group-member: $s) isa group-membership; end; +match $s isa subject, has id "amos.burton@vaticle.com"; $g isa user-group, has id "Finance"; insert (user-group: $g, group-member: $s) isa group-membership; end; +match $s isa subject, has id "alex.kamal@vaticle.com"; $g isa user-group, has id "Cloud"; insert (user-group: $g, group-member: $s) isa group-membership; end; +match $s isa subject, has id "bobbie.draper@vaticle.com"; $g isa user-group, has id "sales@vaticle.com"; insert (user-group: $g, group-member: $s) isa group-membership; end; +match $s isa subject, has id "clarissa.mao@vaticle.com"; $g isa user-group, has id "Web"; insert (user-group: $g, group-member: $s) isa group-membership; end; +match $s isa subject, has id "clarissa.mao@vaticle.com"; $g isa user-group, has id "web admin"; insert (user-group: $g, group-member: $s) isa group-membership; end; +match $s isa subject, has id "joe.miller@vaticle.com"; $g isa user-group, has id "Customer Support"; insert (user-group: $g, group-member: $s) isa group-membership; end; #-------------------------------------------------- # Resources: -insert $o isa file, has path "root/engineering/typedb/feature_roadmap.docx", has object-type "file"; -insert $o isa file, has path "root/engineering/typedb-cloud/pentest_results_oct22.pdf", has object-type "file"; -insert $o isa file, has path "root/engineering/typedb-cloud/pentest_results_mar23.pdf", has object-type "file"; -insert $o isa purchase-order, has reference "MCRN-01", has object-type "order"; -insert $o isa purchase-order, has reference "MCRN-02", has object-type "order"; -insert $o isa purchase-order, has reference "MCRN-03", has object-type "order"; -insert $o isa customer-account, has email "chrisjen.avasarala@google.com", has object-type "account"; -insert $o isa customer-account, has email "camina.drummer@ibm.com", has object-type "account"; -insert $o isa customer-account, has email "klaes.ashford@nestle.com", has object-type "account"; -insert $o isa record, has primary-key "google", has object-type "record"; -insert $o isa record, has primary-key "ibm", has object-type "record"; -insert $o isa record, has primary-key "nestle", has object-type "record"; -insert $o isa record, has primary-key "ibm-nov-21", has object-type "record"; -insert $o isa record, has primary-key "ibm-nov-22", has object-type "record"; -insert $o isa record, has primary-key "nestle-aug-22", has object-type "record"; -insert $o isa record, has primary-key "google-feb-23", has object-type "record"; -insert $o isa pull-request, has hash "0c1022dbb07f427e40f900fc6209134dd4c58a0a", has object-type "pull request"; -insert $o isa pull-request, has hash "03bb369cda4bc10f32bf39283e5f6cf68da7d7ce", has object-type "pull request"; -insert $o isa pull-request, has hash "1aa95605877265544fc432004be6449bdec7cf56", has object-type "pull request"; -insert $o isa pull-request, has hash "1aa95605877265544fc432004be6449bdec7cf56", has object-type "pull request"; -insert $o isa pull-request, has hash "4003ab4cf4f5776a72280e599f39553bd0c01528", has object-type "pull request"; -insert $o isa pull-request, has hash "b00a22929bd997dfbb9294f6716645b71f8150ad", has object-type "pull request"; -insert $o isa pull-request, has hash "949106635c7fae57ec11b77e7e86c7a9aaa0e57d", has object-type "pull request"; -insert $o isa pull-request, has hash "5ca615182e6e2a324f92660629e240b56dc0a8f3", has object-type "pull request"; -insert $o isa pull-request, has hash "2c82e01378ba5ccf54b42b9038f132d43ece650c", has object-type "pull request"; +insert $o isa file, has path "root/engineering/typedb/feature_roadmap.docx", has object-type "file"; end; +insert $o isa file, has path "root/engineering/typedb-cloud/pentest_results_oct22.pdf", has object-type "file"; end; +insert $o isa file, has path "root/engineering/typedb-cloud/pentest_results_mar23.pdf", has object-type "file"; end; +insert $o isa purchase-order, has reference "MCRN-01", has object-type "order"; end; +insert $o isa purchase-order, has reference "MCRN-02", has object-type "order"; end; +insert $o isa purchase-order, has reference "MCRN-03", has object-type "order"; end; +insert $o isa customer-account, has email "chrisjen.avasarala@google.com", has object-type "account"; end; +insert $o isa customer-account, has email "camina.drummer@ibm.com", has object-type "account"; end; +insert $o isa customer-account, has email "klaes.ashford@nestle.com", has object-type "account"; end; +insert $o isa record, has primary-key "google", has object-type "record"; end; +insert $o isa record, has primary-key "ibm", has object-type "record"; end; +insert $o isa record, has primary-key "nestle", has object-type "record"; end; +insert $o isa record, has primary-key "ibm-nov-21", has object-type "record"; end; +insert $o isa record, has primary-key "ibm-nov-22", has object-type "record"; end; +insert $o isa record, has primary-key "nestle-aug-22", has object-type "record"; end; +insert $o isa record, has primary-key "google-feb-23", has object-type "record"; end; +insert $o isa pull-request, has hash "0c1022dbb07f427e40f900fc6209134dd4c58a0a", has object-type "pull request"; end; +insert $o isa pull-request, has hash "03bb369cda4bc10f32bf39283e5f6cf68da7d7ce", has object-type "pull request"; end; +insert $o isa pull-request, has hash "1aa95605877265544fc432004be6449bdec7cf56", has object-type "pull request"; end; +insert $o isa pull-request, has hash "1aa95605877265544fc432004be6449bdec7cf56", has object-type "pull request"; end; +insert $o isa pull-request, has hash "4003ab4cf4f5776a72280e599f39553bd0c01528", has object-type "pull request"; end; +insert $o isa pull-request, has hash "b00a22929bd997dfbb9294f6716645b71f8150ad", has object-type "pull request"; end; +insert $o isa pull-request, has hash "949106635c7fae57ec11b77e7e86c7a9aaa0e57d", has object-type "pull request"; end; +insert $o isa pull-request, has hash "5ca615182e6e2a324f92660629e240b56dc0a8f3", has object-type "pull request"; end; +insert $o isa pull-request, has hash "2c82e01378ba5ccf54b42b9038f132d43ece650c", has object-type "pull request"; end; #-------------------------------------------------- # Resource collections: -insert $o isa directory, has path "root", has object-type "directory"; -insert $o isa directory, has path "root/engineering", has object-type "directory"; -insert $o isa directory, has path "root/engineering/typedb", has object-type "directory"; -insert $o isa directory, has path "root/engineering/typedb-cloud", has object-type "directory"; -insert $o isa application, has name "Sage", has object-type "erp application"; -insert $o isa application, has name "Salesforce", has object-type "crm application"; -insert $o isa application, has name "PostgreSQL", has object-type "dbm application"; -insert $o isa application, has name "GitHub", has object-type "vcs application"; -insert $o isa database, has name "customer_accounts", has object-type "database"; -insert $o isa table, has name "customer", has object-type "table"; -insert $o isa table, has name "order", has object-type "table"; -insert $o isa branch, has name "core/master", has object-type "branch"; -insert $o isa branch, has name "cloud/master", has object-type "branch"; -insert $o isa branch, has name "web/master", has object-type "branch"; -insert $o isa repository, has name "core", has object-type "repository"; -insert $o isa repository, has name "cloud", has object-type "repository"; -insert $o isa repository, has name "web", has object-type "repository"; +insert $o isa directory, has path "root", has object-type "directory"; end; +insert $o isa directory, has path "root/engineering", has object-type "directory"; end; +insert $o isa directory, has path "root/engineering/typedb", has object-type "directory"; end; +insert $o isa directory, has path "root/engineering/typedb-cloud", has object-type "directory"; end; +insert $o isa application, has name "Sage", has object-type "erp application"; end; +insert $o isa application, has name "Salesforce", has object-type "crm application"; end; +insert $o isa application, has name "PostgreSQL", has object-type "dbm application"; end; +insert $o isa application, has name "GitHub", has object-type "vcs application"; end; +insert $o isa database, has name "customer_accounts", has object-type "database"; end; +insert $o isa table, has name "customer", has object-type "table"; end; +insert $o isa table, has name "order", has object-type "table"; end; +insert $o isa branch, has name "core/master", has object-type "branch"; end; +insert $o isa branch, has name "cloud/master", has object-type "branch"; end; +insert $o isa branch, has name "web/master", has object-type "branch"; end; +insert $o isa repository, has name "core", has object-type "repository"; end; +insert $o isa repository, has name "cloud", has object-type "repository"; end; +insert $o isa repository, has name "web", has object-type "repository"; end; #-------------------------------------------------- # Collection memberships: -match $o isa object, has id "root/engineering"; $c isa resource-collection, has id "root"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "root/engineering/typedb"; $c isa resource-collection, has id "root/engineering"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "root/engineering/typedb-cloud"; $c isa resource-collection, has id "root/engineering"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "customer"; $c isa resource-collection, has id "customer_accounts"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "order"; $c isa resource-collection, has id "customer_accounts"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "root/engineering/typedb/feature_roadmap.docx"; $c isa resource-collection, has id "root/engineering/typedb"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "root/engineering/typedb-cloud/pentest_results_oct22.pdf"; $c isa resource-collection, has id "root/engineering/typedb-cloud"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "root/engineering/typedb-cloud/pentest_results_mar23.pdf"; $c isa resource-collection, has id "root/engineering/typedb-cloud"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "MCRN-01"; $c isa resource-collection, has id "Sage"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "MCRN-02"; $c isa resource-collection, has id "Sage"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "MCRN-03"; $c isa resource-collection, has id "Sage"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "chrisjen.avasarala@google.com"; $c isa resource-collection, has id "Salesforce"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "camina.drummer@ibm.com"; $c isa resource-collection, has id "Salesforce"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "klaes.ashford@nestle.com"; $c isa resource-collection, has id "Salesforce"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "google"; $c isa resource-collection, has id "customer"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "ibm"; $c isa resource-collection, has id "customer"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "nestle"; $c isa resource-collection, has id "customer"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "ibm-nov-21"; $c isa resource-collection, has id "order"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "nestle-aug-22"; $c isa resource-collection, has id "order"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "ibm-nov-22"; $c isa resource-collection, has id "order"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "google-feb-23"; $c isa resource-collection, has id "order"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "order"; $c isa resource-collection, has id "customer_accounts"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "customer"; $c isa resource-collection, has id "customer_accounts"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "customer_accounts"; $c isa resource-collection, has id "PostgreSQL"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "0c1022dbb07f427e40f900fc6209134dd4c58a0a"; $c isa resource-collection, has id "core/master"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "03bb369cda4bc10f32bf39283e5f6cf68da7d7ce"; $c isa resource-collection, has id "core/master"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "1aa95605877265544fc432004be6449bdec7cf56"; $c isa resource-collection, has id "core/master"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "4003ab4cf4f5776a72280e599f39553bd0c01528"; $c isa resource-collection, has id "cloud/master"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "b00a22929bd997dfbb9294f6716645b71f8150ad"; $c isa resource-collection, has id "cloud/master"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "949106635c7fae57ec11b77e7e86c7a9aaa0e57d"; $c isa resource-collection, has id "cloud/master"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "5ca615182e6e2a324f92660629e240b56dc0a8f3"; $c isa resource-collection, has id "web/master"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "2c82e01378ba5ccf54b42b9038f132d43ece650c"; $c isa resource-collection, has id "web/master"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "core/master"; $c isa resource-collection, has id "core"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "cloud/master"; $c isa resource-collection, has id "cloud"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "web/master"; $c isa resource-collection, has id "web"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "core"; $c isa resource-collection, has id "GitHub"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "cloud"; $c isa resource-collection, has id "GitHub"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; -match $o isa object, has id "web"; $c isa resource-collection, has id "GitHub"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; +match $o isa object, has id "root/engineering"; $c isa resource-collection, has id "root"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "root/engineering/typedb"; $c isa resource-collection, has id "root/engineering"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "root/engineering/typedb-cloud"; $c isa resource-collection, has id "root/engineering"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "customer"; $c isa resource-collection, has id "customer_accounts"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "order"; $c isa resource-collection, has id "customer_accounts"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "root/engineering/typedb/feature_roadmap.docx"; $c isa resource-collection, has id "root/engineering/typedb"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "root/engineering/typedb-cloud/pentest_results_oct22.pdf"; $c isa resource-collection, has id "root/engineering/typedb-cloud"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "root/engineering/typedb-cloud/pentest_results_mar23.pdf"; $c isa resource-collection, has id "root/engineering/typedb-cloud"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "MCRN-01"; $c isa resource-collection, has id "Sage"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "MCRN-02"; $c isa resource-collection, has id "Sage"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "MCRN-03"; $c isa resource-collection, has id "Sage"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "chrisjen.avasarala@google.com"; $c isa resource-collection, has id "Salesforce"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "camina.drummer@ibm.com"; $c isa resource-collection, has id "Salesforce"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "klaes.ashford@nestle.com"; $c isa resource-collection, has id "Salesforce"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "google"; $c isa resource-collection, has id "customer"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "ibm"; $c isa resource-collection, has id "customer"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "nestle"; $c isa resource-collection, has id "customer"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "ibm-nov-21"; $c isa resource-collection, has id "order"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "nestle-aug-22"; $c isa resource-collection, has id "order"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "ibm-nov-22"; $c isa resource-collection, has id "order"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "google-feb-23"; $c isa resource-collection, has id "order"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "order"; $c isa resource-collection, has id "customer_accounts"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "customer"; $c isa resource-collection, has id "customer_accounts"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "customer_accounts"; $c isa resource-collection, has id "PostgreSQL"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "0c1022dbb07f427e40f900fc6209134dd4c58a0a"; $c isa resource-collection, has id "core/master"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "03bb369cda4bc10f32bf39283e5f6cf68da7d7ce"; $c isa resource-collection, has id "core/master"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "1aa95605877265544fc432004be6449bdec7cf56"; $c isa resource-collection, has id "core/master"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "4003ab4cf4f5776a72280e599f39553bd0c01528"; $c isa resource-collection, has id "cloud/master"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "b00a22929bd997dfbb9294f6716645b71f8150ad"; $c isa resource-collection, has id "cloud/master"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "949106635c7fae57ec11b77e7e86c7a9aaa0e57d"; $c isa resource-collection, has id "cloud/master"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "5ca615182e6e2a324f92660629e240b56dc0a8f3"; $c isa resource-collection, has id "web/master"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "2c82e01378ba5ccf54b42b9038f132d43ece650c"; $c isa resource-collection, has id "web/master"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "core/master"; $c isa resource-collection, has id "core"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "cloud/master"; $c isa resource-collection, has id "cloud"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "web/master"; $c isa resource-collection, has id "web"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "core"; $c isa resource-collection, has id "GitHub"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "cloud"; $c isa resource-collection, has id "GitHub"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; +match $o isa object, has id "web"; $c isa resource-collection, has id "GitHub"; insert (resource-collection: $c, collection-member: $o) isa collection-membership; end; #-------------------------------------------------- # Operations: -insert $a isa operation, has name "create file", has object-type "directory"; -insert $a isa operation, has name "view file", has object-type "file", has object-type "directory"; -insert $a isa operation, has name "move file", has object-type "directory"; -insert $a isa operation, has name "edit file", has object-type "file", has object-type "directory"; -insert $a isa operation, has name "delete file", has object-type "file", has object-type "directory"; -insert $a isa operation, has name "create subdirectory", has object-type "directory"; -insert $a isa operation, has name "move subdirectory", has object-type "directory"; -insert $a isa operation, has name "delete subdirectory", has object-type "directory"; -insert $a isa operation, has name "create order", has object-type "erp application"; -insert $a isa operation, has name "submit order", has object-type "order", has object-type "erp application"; -insert $a isa operation, has name "approve order", has object-type "order", has object-type "erp application"; -insert $a isa operation, has name "create account", has object-type "crm application"; -insert $a isa operation, has name "view account", has object-type "account", has object-type "crm application"; -insert $a isa operation, has name "modify account", has object-type "account", has object-type "crm application"; -insert $a isa operation, has name "delete account", has object-type "account", has object-type "crm application"; -insert $a isa operation, has name "insert record", has object-type "table", has object-type "database", has object-type "dbm application"; -insert $a isa operation, has name "select record", has object-type "record", has object-type "table", has object-type "database", has object-type "dbm application"; -insert $a isa operation, has name "update record", has object-type "record", has object-type "table", has object-type "database", has object-type "dbm application"; -insert $a isa operation, has name "delete record", has object-type "record", has object-type "table", has object-type "database", has object-type "dbm application"; -insert $a isa operation, has name "create table", has object-type "database", has object-type "dbm application"; -insert $a isa operation, has name "alter table", has object-type "table", has object-type "database", has object-type "dbm application"; -insert $a isa operation, has name "drop table", has object-type "table", has object-type "database", has object-type "dbm application"; -insert $a isa operation, has name "create database", has object-type "dbm application"; -insert $a isa operation, has name "drop database", has object-type "database", has object-type "dbm application"; -insert $a isa operation, has name "push commit", has object-type "branch", has object-type "repository", has object-type "vcs application"; -insert $a isa operation, has name "open pull request", has object-type "branch", has object-type "repository", has object-type "vcs application"; -insert $a isa operation, has name "approve pull request", has object-type "pull request", has object-type "branch", has object-type "repository", has object-type "vcs application"; -insert $a isa operation, has name "merge pull request", has object-type "pull request", has object-type "branch", has object-type "repository", has object-type "vcs application"; -insert $a isa operation, has name "create branch", has object-type "repository", has object-type "vcs application"; -insert $a isa operation, has name "rename branch", has object-type "branch", has object-type "repository", has object-type "vcs application"; -insert $a isa operation, has name "delete branch", has object-type "branch", has object-type "repository", has object-type "vcs application"; -insert $a isa operation, has name "create repository", has object-type "vcs application"; -insert $a isa operation, has name "rename repository", has object-type "vcs application"; -insert $a isa operation, has name "delete repository", has object-type "repository", has object-type "vcs application"; -insert $a isa operation, has name "grant permission", has object-type "object"; -insert $a isa operation, has name "revoke permission", has object-type "object"; -insert $a isa operation, has name "grant ownership", has object-type "object"; -insert $a isa operation, has name "revoke ownership", has object-type "object"; +insert $a isa operation, has name "create file", has object-type "directory"; end; +insert $a isa operation, has name "view file", has object-type "file", has object-type "directory"; end; +insert $a isa operation, has name "move file", has object-type "directory"; end; +insert $a isa operation, has name "edit file", has object-type "file", has object-type "directory"; end; +insert $a isa operation, has name "delete file", has object-type "file", has object-type "directory"; end; +insert $a isa operation, has name "create subdirectory", has object-type "directory"; end; +insert $a isa operation, has name "move subdirectory", has object-type "directory"; end; +insert $a isa operation, has name "delete subdirectory", has object-type "directory"; end; +insert $a isa operation, has name "create order", has object-type "erp application"; end; +insert $a isa operation, has name "submit order", has object-type "order", has object-type "erp application"; end; +insert $a isa operation, has name "approve order", has object-type "order", has object-type "erp application"; end; +insert $a isa operation, has name "create account", has object-type "crm application"; end; +insert $a isa operation, has name "view account", has object-type "account", has object-type "crm application"; end; +insert $a isa operation, has name "modify account", has object-type "account", has object-type "crm application"; end; +insert $a isa operation, has name "delete account", has object-type "account", has object-type "crm application"; end; +insert $a isa operation, has name "insert record", has object-type "table", has object-type "database", has object-type "dbm application"; end; +insert $a isa operation, has name "select record", has object-type "record", has object-type "table", has object-type "database", has object-type "dbm application"; end; +insert $a isa operation, has name "update record", has object-type "record", has object-type "table", has object-type "database", has object-type "dbm application"; end; +insert $a isa operation, has name "delete record", has object-type "record", has object-type "table", has object-type "database", has object-type "dbm application"; end; +insert $a isa operation, has name "create table", has object-type "database", has object-type "dbm application"; end; +insert $a isa operation, has name "alter table", has object-type "table", has object-type "database", has object-type "dbm application"; end; +insert $a isa operation, has name "drop table", has object-type "table", has object-type "database", has object-type "dbm application"; end; +insert $a isa operation, has name "create database", has object-type "dbm application"; end; +insert $a isa operation, has name "drop database", has object-type "database", has object-type "dbm application"; end; +insert $a isa operation, has name "push commit", has object-type "branch", has object-type "repository", has object-type "vcs application"; end; +insert $a isa operation, has name "open pull request", has object-type "branch", has object-type "repository", has object-type "vcs application"; end; +insert $a isa operation, has name "approve pull request", has object-type "pull request", has object-type "branch", has object-type "repository", has object-type "vcs application"; end; +insert $a isa operation, has name "merge pull request", has object-type "pull request", has object-type "branch", has object-type "repository", has object-type "vcs application"; end; +insert $a isa operation, has name "create branch", has object-type "repository", has object-type "vcs application"; end; +insert $a isa operation, has name "rename branch", has object-type "branch", has object-type "repository", has object-type "vcs application"; end; +insert $a isa operation, has name "delete branch", has object-type "branch", has object-type "repository", has object-type "vcs application"; end; +insert $a isa operation, has name "create repository", has object-type "vcs application"; end; +insert $a isa operation, has name "rename repository", has object-type "vcs application"; end; +insert $a isa operation, has name "delete repository", has object-type "repository", has object-type "vcs application"; end; +insert $a isa operation, has name "grant permission", has object-type "object"; end; +insert $a isa operation, has name "revoke permission", has object-type "object"; end; +insert $a isa operation, has name "grant ownership", has object-type "object"; end; +insert $a isa operation, has name "revoke ownership", has object-type "object"; end; #-------------------------------------------------- # Operation sets: -insert $a isa operation-set, has name "write file", has object-type "file", has object-type "directory"; -insert $a isa operation-set, has name "manage subdirectory", has object-type "directory"; -insert $a isa operation-set, has name "manage directory", has object-type "directory"; -insert $a isa operation-set, has name "manage order", has object-type "order", has object-type "erp application"; -insert $a isa operation-set, has name "manage account", has object-type "account", has object-type "crm application"; -insert $a isa operation-set, has name "write record", has object-type "record", has object-type "table", has object-type "database", has object-type "dbm application"; -insert $a isa operation-set, has name "manage table", has object-type "table", has object-type "database", has object-type "dbm application"; -insert $a isa operation-set, has name "manage database", has object-type "database", has object-type "dbm application"; -insert $a isa operation-set, has name "manage pull request", has object-type "pull request", has object-type "branch", has object-type "repository", has object-type "vcs application"; -insert $a isa operation-set, has name "manage branch", has object-type "branch", has object-type "repository", has object-type "vcs application"; -insert $a isa operation-set, has name "manage repository", has object-type "repository", has object-type "vcs application"; -insert $a isa operation-set, has name "manage permissions", has object-type "object"; -insert $a isa operation-set, has name "manage ownership", has object-type "object"; +insert $a isa operation-set, has name "write file", has object-type "file", has object-type "directory"; end; +insert $a isa operation-set, has name "manage subdirectory", has object-type "directory"; end; +insert $a isa operation-set, has name "manage directory", has object-type "directory"; end; +insert $a isa operation-set, has name "manage order", has object-type "order", has object-type "erp application"; end; +insert $a isa operation-set, has name "manage account", has object-type "account", has object-type "crm application"; end; +insert $a isa operation-set, has name "write record", has object-type "record", has object-type "table", has object-type "database", has object-type "dbm application"; end; +insert $a isa operation-set, has name "manage table", has object-type "table", has object-type "database", has object-type "dbm application"; end; +insert $a isa operation-set, has name "manage database", has object-type "database", has object-type "dbm application"; end; +insert $a isa operation-set, has name "manage pull request", has object-type "pull request", has object-type "branch", has object-type "repository", has object-type "vcs application"; end; +insert $a isa operation-set, has name "manage branch", has object-type "branch", has object-type "repository", has object-type "vcs application"; end; +insert $a isa operation-set, has name "manage repository", has object-type "repository", has object-type "vcs application"; end; +insert $a isa operation-set, has name "manage permissions", has object-type "object"; end; +insert $a isa operation-set, has name "manage ownership", has object-type "object"; end; #-------------------------------------------------- # Set memberships: -match $a isa action, has name "create file"; $s isa operation-set, has name "write file"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "view file"; $s isa operation-set, has name "write file"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "edit file"; $s isa operation-set, has name "write file"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "delete file"; $s isa operation-set, has name "write file"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "create subdirectory"; $s isa operation-set, has name "manage subdirectory"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "move subdirectory"; $s isa operation-set, has name "manage subdirectory"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "delete subdirectory"; $s isa operation-set, has name "manage subdirectory"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "move file"; $s isa operation-set, has name "manage subdirectory"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "write file"; $s isa operation-set, has name "manage directory"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "manage subdirectory"; $s isa operation-set, has name "manage directory"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "create order"; $s isa operation-set, has name "manage order"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "submit order"; $s isa operation-set, has name "manage order"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "approve order"; $s isa operation-set, has name "manage order"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "create account"; $s isa operation-set, has name "manage account"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "view account"; $s isa operation-set, has name "manage account"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "modify account"; $s isa operation-set, has name "manage account"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "delete account"; $s isa operation-set, has name "manage account"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "insert record"; $s isa operation-set, has name "write record"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "select record"; $s isa operation-set, has name "write record"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "update record"; $s isa operation-set, has name "write record"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "delete record"; $s isa operation-set, has name "write record"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "create table"; $s isa operation-set, has name "manage table"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "alter table"; $s isa operation-set, has name "manage table"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "drop table"; $s isa operation-set, has name "manage table"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "write record"; $s isa operation-set, has name "manage table"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "create database"; $s isa operation-set, has name "manage database"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "drop database"; $s isa operation-set, has name "manage database"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "manage table"; $s isa operation-set, has name "manage database"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "open pull request"; $s isa operation-set, has name "manage pull request"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "approve pull request"; $s isa operation-set, has name "manage pull request"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "merge pull request"; $s isa operation-set, has name "manage pull request"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "push commit"; $s isa operation-set, has name "manage branch"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "create branch"; $s isa operation-set, has name "manage branch"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "rename branch"; $s isa operation-set, has name "manage branch"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "delete branch"; $s isa operation-set, has name "manage branch"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "manage pull request"; $s isa operation-set, has name "manage branch"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "create repository"; $s isa operation-set, has name "manage repository"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "rename repository"; $s isa operation-set, has name "manage repository"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "delete repository"; $s isa operation-set, has name "manage repository"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "manage branch"; $s isa operation-set, has name "manage repository"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "grant permission"; $s isa operation-set, has name "manage permissions"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "revoke permission"; $s isa operation-set, has name "manage permissions"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "grant ownership"; $s isa operation-set, has name "manage ownership"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "revoke ownership"; $s isa operation-set, has name "manage ownership"; insert (operation-set: $s, set-member: $a) isa set-membership; -match $a isa action, has name "manage permissions"; $s isa operation-set, has name "manage ownership"; insert (operation-set: $s, set-member: $a) isa set-membership; +match $a isa action, has name "create file"; $s isa operation-set, has name "write file"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "view file"; $s isa operation-set, has name "write file"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "edit file"; $s isa operation-set, has name "write file"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "delete file"; $s isa operation-set, has name "write file"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "create subdirectory"; $s isa operation-set, has name "manage subdirectory"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "move subdirectory"; $s isa operation-set, has name "manage subdirectory"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "delete subdirectory"; $s isa operation-set, has name "manage subdirectory"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "move file"; $s isa operation-set, has name "manage subdirectory"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "write file"; $s isa operation-set, has name "manage directory"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "manage subdirectory"; $s isa operation-set, has name "manage directory"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "create order"; $s isa operation-set, has name "manage order"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "submit order"; $s isa operation-set, has name "manage order"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "approve order"; $s isa operation-set, has name "manage order"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "create account"; $s isa operation-set, has name "manage account"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "view account"; $s isa operation-set, has name "manage account"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "modify account"; $s isa operation-set, has name "manage account"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "delete account"; $s isa operation-set, has name "manage account"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "insert record"; $s isa operation-set, has name "write record"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "select record"; $s isa operation-set, has name "write record"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "update record"; $s isa operation-set, has name "write record"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "delete record"; $s isa operation-set, has name "write record"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "create table"; $s isa operation-set, has name "manage table"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "alter table"; $s isa operation-set, has name "manage table"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "drop table"; $s isa operation-set, has name "manage table"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "write record"; $s isa operation-set, has name "manage table"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "create database"; $s isa operation-set, has name "manage database"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "drop database"; $s isa operation-set, has name "manage database"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "manage table"; $s isa operation-set, has name "manage database"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "open pull request"; $s isa operation-set, has name "manage pull request"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "approve pull request"; $s isa operation-set, has name "manage pull request"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "merge pull request"; $s isa operation-set, has name "manage pull request"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "push commit"; $s isa operation-set, has name "manage branch"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "create branch"; $s isa operation-set, has name "manage branch"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "rename branch"; $s isa operation-set, has name "manage branch"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "delete branch"; $s isa operation-set, has name "manage branch"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "manage pull request"; $s isa operation-set, has name "manage branch"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "create repository"; $s isa operation-set, has name "manage repository"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "rename repository"; $s isa operation-set, has name "manage repository"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "delete repository"; $s isa operation-set, has name "manage repository"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "manage branch"; $s isa operation-set, has name "manage repository"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "grant permission"; $s isa operation-set, has name "manage permissions"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "revoke permission"; $s isa operation-set, has name "manage permissions"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "grant ownership"; $s isa operation-set, has name "manage ownership"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "revoke ownership"; $s isa operation-set, has name "manage ownership"; insert (operation-set: $s, set-member: $a) isa set-membership; end; +match $a isa action, has name "manage permissions"; $s isa operation-set, has name "manage ownership"; insert (operation-set: $s, set-member: $a) isa set-membership; end; #-------------------------------------------------- # Accesses: @@ -275,6 +275,7 @@ $o isa object; not { $o has object-type "object"; }; insert $o has object-type "object"; +end; match $o isa object, has object-type $type; @@ -287,29 +288,29 @@ not { }; insert (accessed-object: $o, valid-action: $a) isa access; +end; #-------------------------------------------------- # Permissions: -match $s isa subject, has id "engineer"; $o isa object, has id "root/engineering"; $a isa action, has id "view file"; $ac (accessed-object: $o, valid-action: $a) isa access; insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; -match $s isa subject, has id "Core"; $o isa object, has id "root/engineering/typedb"; $a isa action, has id "manage directory"; $ac (accessed-object: $o, valid-action: $a) isa access; insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; -match $s isa subject, has id "Cloud"; $o isa object, has id "root/engineering/typedb-cloud"; $a isa action, has id "manage directory"; $ac (accessed-object: $o, valid-action: $a) isa access; insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; -match $s isa subject, has id "Finance"; $o isa object, has id "Sage"; $a isa action, has id "manage order"; $ac (accessed-object: $o, valid-action: $a) isa access; insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; -match $s isa subject, has id "sales@vaticle.com"; $o isa object, has id "Salesforce"; $a isa action, has id "manage account"; $ac (accessed-object: $o, valid-action: $a) isa access; insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; -match $s isa subject, has id "sales@vaticle.com"; $o isa object, has id "customer_accounts"; $a isa action, has id "write record"; $ac (accessed-object: $o, valid-action: $a) isa access; insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; -match $s isa subject, has id "Customer Support"; $o isa object, has id "customer_accounts"; $a isa action, has id "write record"; $ac (accessed-object: $o, valid-action: $a) isa access; insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; -match $s isa subject, has id "Core"; $o isa object, has id "core"; $a isa action, has id "manage pull request"; $ac (accessed-object: $o, valid-action: $a) isa access; insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; -match $s isa subject, has id "Cloud"; $o isa object, has id "cloud"; $a isa action, has id "manage pull request"; $ac (accessed-object: $o, valid-action: $a) isa access; insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; -match $s isa subject, has id "Web"; $o isa object, has id "web"; $a isa action, has id "manage pull request"; $ac (accessed-object: $o, valid-action: $a) isa access; insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; -match $s isa subject, has id "web editor"; $o isa object, has id "web"; $a isa action, has id "manage branch"; $ac (accessed-object: $o, valid-action: $a) isa access; insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; -match $s isa subject, has id "web admin"; $o isa object, has id "web"; $a isa action, has id "manage repository"; $ac (accessed-object: $o, valid-action: $a) isa access; insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; +match $s isa subject, has id "engineer"; $o isa object, has id "root/engineering"; $a isa action, has id "view file"; $ac isa access, links (accessed-object: $o, valid-action: $a); insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; end; +match $s isa subject, has id "Core"; $o isa object, has id "root/engineering/typedb"; $a isa action, has id "manage directory"; $ac isa access, links (accessed-object: $o, valid-action: $a); insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; end; +match $s isa subject, has id "Cloud"; $o isa object, has id "root/engineering/typedb-cloud"; $a isa action, has id "manage directory"; $ac isa access, links (accessed-object: $o, valid-action: $a); insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; end; +match $s isa subject, has id "Finance"; $o isa object, has id "Sage"; $a isa action, has id "manage order"; $ac isa access, links (accessed-object: $o, valid-action: $a); insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; end; +match $s isa subject, has id "sales@vaticle.com"; $o isa object, has id "Salesforce"; $a isa action, has id "manage account"; $ac isa access, links (accessed-object: $o, valid-action: $a); insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; end; +match $s isa subject, has id "sales@vaticle.com"; $o isa object, has id "customer_accounts"; $a isa action, has id "write record"; $ac isa access, links (accessed-object: $o, valid-action: $a); insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; end; +match $s isa subject, has id "Customer Support"; $o isa object, has id "customer_accounts"; $a isa action, has id "write record"; $ac isa access, links (accessed-object: $o, valid-action: $a); insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; end; +match $s isa subject, has id "Core"; $o isa object, has id "core"; $a isa action, has id "manage pull request"; $ac isa access, links (accessed-object: $o, valid-action: $a); insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; end; +match $s isa subject, has id "Cloud"; $o isa object, has id "cloud"; $a isa action, has id "manage pull request"; $ac isa access, links (accessed-object: $o, valid-action: $a); insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; end; +match $s isa subject, has id "Web"; $o isa object, has id "web"; $a isa action, has id "manage pull request"; $ac isa access, links (accessed-object: $o, valid-action: $a); insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; end; +match $s isa subject, has id "web editor"; $o isa object, has id "web"; $a isa action, has id "manage branch"; $ac isa access, links (accessed-object: $o, valid-action: $a); insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; end; +match $s isa subject, has id "web admin"; $o isa object, has id "web"; $a isa action, has id "manage repository"; $ac isa access, links (accessed-object: $o, valid-action: $a); insert (permitted-subject: $s, permitted-access: $ac) isa direct-permission; end; #-------------------------------------------------- # Access histories: -match $s isa subject, has id "bobbie.draper@vaticle.com"; $o isa object, has id "camina.drummer@ibm.com"; $a isa action, has id "view account"; $ac (accessed-object: $o, valid-action: $a) isa access; insert (accessing-subject: $s, exercised-access: $ac) isa access-history, has access-time 2023-05-05T09:19:17; -match $s isa subject, has id "joe.miller@vaticle.com"; $o isa object, has id "customer"; $a isa action, has id "insert record"; $ac (accessed-object: $o, valid-action: $a) isa access; insert (accessing-subject: $s, exercised-access: $ac) isa access-history, has access-time 2023-05-07T13:11:26; -match $s isa subject, has id "alex.kamal@vaticle.com"; $o isa object, has id "4003ab4cf4f5776a72280e599f39553bd0c01528"; $a isa action, has id "merge pull request"; $ac (accessed-object: $o, valid-action: $a) isa access; insert (accessing-subject: $s, exercised-access: $ac) isa access-history, has access-time 2023-05-10T09:12:21; -match $s isa subject, has id "naomi.nagata@vaticle.com"; $o isa object, has id "root/engineering/typedb/feature_roadmap.docx"; $a isa action, has id "edit file"; $ac (accessed-object: $o, valid-action: $a) isa access; insert (accessing-subject: $s, exercised-access: $ac) isa access-history, has access-time 2023-05-12T11:47:34; +match $s isa subject, has id "bobbie.draper@vaticle.com"; $o isa object, has id "camina.drummer@ibm.com"; $a isa action, has id "view account"; $ac isa access, links (accessed-object: $o, valid-action: $a); insert (accessing-subject: $s, exercised-access: $ac) isa access-history, has access-time 2023-05-05T09:19:17; end; +match $s isa subject, has id "joe.miller@vaticle.com"; $o isa object, has id "customer"; $a isa action, has id "insert record"; $ac isa access, links (accessed-object: $o, valid-action: $a); insert (accessing-subject: $s, exercised-access: $ac) isa access-history, has access-time 2023-05-07T13:11:26; end; +match $s isa subject, has id "alex.kamal@vaticle.com"; $o isa object, has id "4003ab4cf4f5776a72280e599f39553bd0c01528"; $a isa action, has id "merge pull request"; $ac isa access, links (accessed-object: $o, valid-action: $a); insert (accessing-subject: $s, exercised-access: $ac) isa access-history, has access-time 2023-05-10T09:12:21; end; +match $s isa subject, has id "naomi.nagata@vaticle.com"; $o isa object, has id "root/engineering/typedb/feature_roadmap.docx"; $a isa action, has id "edit file"; $ac isa access, links (accessed-object: $o, valid-action: $a); insert (accessing-subject: $s, exercised-access: $ac) isa access-history, has access-time 2023-05-12T11:47:34; end; -#-------------------------------------------------- diff --git a/identity-and-access-management/schema.tql b/identity-and-access-management/schema.tql new file mode 100644 index 0000000..58f3aa3 --- /dev/null +++ b/identity-and-access-management/schema.tql @@ -0,0 +1,403 @@ +# +# Copyright (C) 2023 Vaticle +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +define + +#-------------------------------------------------- +# Core entity types: + +entity subject @abstract, + owns credential; + +entity user @abstract, sub subject; + +entity user-group @abstract, sub subject; + +entity object @abstract, + owns object-type @card(0..); + +entity resource @abstract, sub object; + +entity resource-collection @abstract, sub object; + +entity action @abstract, + owns name, + owns object-type @card(0..); + +entity operation sub action; + +entity operation-set sub action; + +#-------------------------------------------------- +# Membership and ownership relation types: + +relation membership @abstract, + relates parent, + relates member; + +relation group-membership sub membership, + relates user-group as parent, + relates group-member as member; + + +relation collection-membership sub membership, + relates resource-collection as parent, + relates collection-member as member; + +relation set-membership sub membership, + relates operation-set as parent, + relates set-member as member; + +user-group plays group-membership:user-group; +subject plays group-membership:group-member; +resource-collection plays collection-membership:resource-collection; +object plays collection-membership:collection-member; +operation-set plays set-membership:operation-set; +action plays set-membership:set-member; + +relation ownership @abstract, + relates owned, + relates owner; + +relation group-ownership sub ownership, + relates owned-group as owned, + relates group-owner as owner, + owns ownership-type; + +relation object-ownership sub ownership, + relates owned-object as owned, + relates object-owner as owner, + owns ownership-type; + +user-group plays group-ownership:owned-group; +subject plays group-ownership:group-owner; +object plays object-ownership:owned-object; +subject plays object-ownership:object-owner; + +#-------------------------------------------------- +# Access and permission relation types: + +relation access, + relates accessed-object, + relates valid-action; + +object plays access:accessed-object; +action plays access:valid-action; + +relation direct-permission, + relates permitted-subject, + relates permitted-access, + owns review-date, + owns validity; + +subject plays direct-permission:permitted-subject; +access plays direct-permission:permitted-access; + +relation change-request, + relates requesting-subject, + relates requested-subject, + relates requested-change; + +subject plays change-request:requesting-subject; +subject plays change-request:requested-subject; +access plays change-request:requested-change; + +relation access-history, + relates accessing-subject, + relates exercised-access, + owns access-time; + +subject plays access-history:accessing-subject; +access plays access-history:exercised-access; + +#-------------------------------------------------- +# Policy and violation relation types: + +relation segregation-policy, + relates segregated-action @card(2), + owns name; + +relation static-segregation-policy sub segregation-policy; + +relation dynamic-segregation-policy sub segregation-policy; + +action plays segregation-policy:segregated-action; + +relation violation @abstract; + +relation segregation-violation sub violation, + relates violating-subject, + relates violating-object, + relates violated-policy; + +subject plays segregation-violation:violating-subject; +object plays segregation-violation:violating-object; +segregation-policy plays segregation-violation:violated-policy; + +#-------------------------------------------------- +# Core entity subtypes: + +entity employee sub user, + owns full-name, + owns email @card(1..2); + +entity contractor sub user, + owns full-name, + owns email @card(1..2); + +entity business-unit sub user-group, + owns name; + +entity user-role sub user-group, + owns name; + +entity user-account sub user-group, + owns email; + +entity file sub resource, + owns path; + +entity purchase-order sub resource, + owns reference; + +entity customer-account sub resource, + owns email; + +entity record sub resource, + owns primary-key; + +entity pull-request sub resource, + owns hash; + +entity directory sub resource-collection, + owns path; + +entity application sub resource-collection, + owns name; + +entity database sub resource-collection, + owns name; + +entity table sub resource-collection, + owns name; + +entity branch sub resource-collection, + owns name; + +entity repository sub resource-collection, + owns name; + +#-------------------------------------------------- +# Attribute types: + +attribute credential, value string; +attribute object-type, value string; +attribute id, @abstract; +attribute name sub id, value string; +attribute ownership-type, value string; +attribute review-date, value datetime; +attribute validity, value boolean; +attribute email sub id, value string; +attribute path sub id, value string; +attribute reference sub id, value string; +attribute primary-key sub id, value string; +attribute hash sub id, value string; +attribute full-name, value string; +attribute access-time, value datetime; + +#-------------------------------------------------- +# Functions: +#-------------------------------------------------- +# memberships of a given instance +fun group_memberships($member: subject) -> { user-group }: +match + $group isa user-group; + { + $m isa group-membership, links (user-group: $group, group-member: $member); + } or { + $m1 isa group-membership, links (user-group: $group, group-member: $intermediate); + let $intermediate in group_memberships($member); + }; +return { $group }; + + +fun collection_memberships($member: object) -> { resource-collection }: +match + $collection isa resource-collection; + { + $m isa collection-membership, links (resource-collection: $collection, collection-member: $member); + } or { + $m1 isa collection-membership, links (resource-collection: $collection, collection-member: $intermediate); + let $intermediate in collection_memberships($member); + }; +return { $collection }; + +fun set_memberships($member: action) -> { operation-set }: +match + $set isa operation-set; + { + $m isa set-membership, links (operation-set: $set, set-member: $member); + } or { + $m1 isa set-membership, links (operation-set: $set, set-member: $intermediate); + let $intermediate in set_memberships($member); + }; +return { $set }; + +#-------------------------------------------------- +# members of a given collection +fun group_members($group: user-group) -> { subject }: +match +# $group isa user-group; + $member isa subject; + { + $m isa group-membership, links (user-group: $group, group-member: $member); + } or { + let $intermediate in group_members($group); + $m1 isa group-membership, links (user-group: $intermediate, group-member: $member); + }; +return { $member }; + +fun set_members($set: operation-set) -> { action }: +match + $member isa action; + { + $m isa set-membership, links (operation-set: $set, set-member: $member); + } or { + let $intermediate in set_members($set); + $m1 isa set-membership, links (operation-set: $intermediate, set-member: $member); + }; +return { $member }; + +fun collection_members($collection: resource-collection) -> { object }: +match + $member isa object; + { + $m isa collection-membership, links (resource-collection: $collection, collection-member: $member); + } or { + let $intermediate in collection_members($collection); + $m1 isa collection-membership, links (resource-collection: $intermediate, collection-member: $member); + }; +return { $member }; + + +#-------------------------------------------------- +# Functions for permissions +fun list_permissions($subject: subject) -> { access }: +match + $granting-subject isa subject; + { let $granting-subject in group_memberships($subject); } or { $granting-subject is $subject; }; + + $granting-permission isa direct-permission, links (permitted-subject: $granting-subject, permitted-access: $granting-access); + $granting-access isa access, links (accessed-object: $granting-object, valid-action: $granting-action); + + $action isa action; + $object isa object; + { let $action in set_members($granting-action); } or { $action is $granting-action; }; + { let $object in collection_members($granting-object); } or { $object is $granting-object ; }; + + $access isa access, links (accessed-object: $object, valid-action: $action); +return { $access }; + +fun has_permission_through($subject: subject, $access: access) -> { direct-permission }: +match + $subject isa subject; + $object isa object; + $action isa action; + $granting-subject isa subject; + $granting-object isa object; + $granting-action isa action; + $access isa access, links (accessed-object: $object, valid-action: $action); + { let $granting-subject in group_memberships($subject); } or { $granting-subject is $subject; }; + { let $granting-action in set_memberships($action); } or { $granting-action is $action; }; + { let $granting-object in collection_memberships($object); } or { $granting-object is $object; }; + $granting-access isa access (accessed-object: $granting-object, valid-action: $granting-action); + $granting-permission isa direct-permission, links (permitted-subject: $granting-subject, permitted-access: $granting-access); +return { $granting-permission }; + +fun has_permission($subject: subject, $access: access) -> boolean: +match + let $_ in has_permission_through($subject, $access); +return check; + +# Segregation policy functions +fun segregation_policies_violated($s: subject, $ac1: access) -> { segregation-policy }: +match + $ac1 isa access (accessed-object: $o, valid-action: $a1); + { + $po isa static-segregation-policy (segregated-action: $a1, segregated-action: $a2); + $ac2 isa access (accessed-object: $o, valid-action: $a2); + true == has_permission($s, $ac2); + } or { + $po isa dynamic-segregation-policy (segregated-action: $a1, segregated-action: $a2) ; + $ac2 isa access (accessed-object: $o, valid-action: $a2); + $ah isa access-history (accessing-subject: $s, exercised-access: $ac2); + }; +return { $po }; + +fun violates_policies($s: subject, $ac1: access) -> boolean: +match + let $po in segregation_policies_violated($s, $ac1); +return check; + +# rule static-segregation-violation-detection: +# when { +# $po (segregated-action: $a1, segregated-action: $a2) isa static-segregation-policy; +# $ac1 (accessed-object: $o, valid-action: $a1) isa access; +# $ac2 (accessed-object: $o, valid-action: $a2) isa access; +# $p1 (permitted-subject: $s, permitted-access: $ac1) isa permission; +# $p2 (permitted-subject: $s, permitted-access: $ac2) isa permission; +# } then { +# (violating-subject: $s, violating-object: $o, violated-policy: $po) isa segregation-violation; +# }; + +# rule automatic-permission-invalidity: +# when { +# $ac1 (accessed-object: $o, valid-action: $a1) isa access; +# $ac2 (accessed-object: $o, valid-action: $a2) isa access; +# $p1 (permitted-subject: $s, permitted-access: $ac1) isa permission; +# $o has id $o-id; # Unnecessary line, see note above. +# $a1 has id $a1-id; # Unnecessary line, see note above. +# $a2 has id $a2-id; # Unnecessary line, see note above. +# $s has id $s-id; # Unnecessary line, see note above. +# { +# $po (segregated-action: $a1, segregated-action: $a2) isa static-segregation-policy; +# $p2 (permitted-subject: $s, permitted-access: $ac2) isa permission; +# $po has id $po-id; # Unnecessary line, see note above. +# } or { +# $po (segregated-action: $a1, segregated-action: $a2) isa dynamic-segregation-policy; +# $ah (accessing-subject: $s, exercised-access: $ac2) isa access-history; +# $po has id $po-id; # Unnecessary line, see note above. +# }; +# } then { +# $p1 has validity false; +# }; + +# rule automatic-permission-validity: +# when { +# $p isa permission; +# not { +# $p has validity false; +# }; +# } then { +# $p has validity true; +# }; + +# #-------------------------------------------------- diff --git a/identity-and-access-management/setup-script.tqls b/identity-and-access-management/setup-script.tqls new file mode 100644 index 0000000..a5bb7fb --- /dev/null +++ b/identity-and-access-management/setup-script.tqls @@ -0,0 +1,7 @@ +database create iam +transaction schema iam +source schema.tql +commit +transaction write iam +source sample-data.tql +commit