Skip to content

Commit 230ad2a

Browse files
committed
Add comprehensive KSL tutorial system with 4-file learning path
- Add complete basic syntax tutorial (01_complete_basic_syntax.ksl/.zed) - Add advanced relations and cross-namespace tutorial (02_*.ksl -> 02_*.zed) - Add extension system tutorial with template variables (03_*.ksl -> 03_*.zed) - Add real-world enterprise example using all KSL features (04_*.ksl/.zed) - Add detailed compiler behavior documentation (ksl_compiler_behavior.md) - Add cardinality constraints explanation with practical examples - Add minimal learning guide (README.md) covering all syntax in 30 minutes - Add demo schema.zed for quick reference Tutorials cover: cardinalities, visibility, relations, extensions, cross-namespace imports, template variables, reserved keywords, and real-world authorization modeling patterns. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> Signed-off-by: zhujian <[email protected]>
1 parent bd09668 commit 230ad2a

16 files changed

+1022
-0
lines changed

demo/schema.zed

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
definition rbac/principal {}
2+
3+
definition rbac/role {}
4+
5+
definition rbac/role_binding {
6+
permission granted = t_granted
7+
relation t_granted: rbac/role
8+
permission subject = t_subject
9+
relation t_subject: rbac/principal
10+
}
11+
12+
definition rbac/workspace {
13+
permission parent = t_parent
14+
relation t_parent: rbac/workspace
15+
permission user_grant = t_user_grant
16+
relation t_user_grant: rbac/role_binding
17+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
version 0.1
2+
namespace learning
3+
4+
// Basic type with no relations
5+
public type user {
6+
7+
}
8+
9+
// Type demonstrating ALL cardinality constraints
10+
public type document {
11+
// ExactlyOne - must have exactly one
12+
relation owner: [ExactlyOne user]
13+
14+
// Any - can have zero, one, or unlimited
15+
relation editor: [Any user]
16+
17+
// AtMostOne - can have zero or one
18+
relation reviewer: [AtMostOne user]
19+
20+
// AtLeastOne - must have one or more
21+
relation approver: [AtLeastOne user]
22+
23+
// Basic permission - direct reference
24+
relation can_read: owner
25+
26+
// Union (OR) - multiple ways to get permission
27+
relation can_edit: owner or editor
28+
29+
// Complex union - three ways to get permission
30+
relation can_view: owner or editor or reviewer
31+
32+
// Intersection (AND) - must satisfy both conditions
33+
relation can_approve: approver and owner
34+
35+
// Exclusion (UNLESS) - first condition unless second is true
36+
relation can_delete: owner unless reviewer
37+
38+
// Grouping with parentheses for complex logic
39+
relation can_publish: (owner or editor) and approver
40+
}
41+
42+
// Demonstrating ALL visibility modifiers
43+
public type project {
44+
// Public - accessible from other namespaces
45+
public relation owner: [ExactlyOne user]
46+
47+
// Internal - accessible within this namespace only
48+
internal relation team_member: [Any user]
49+
50+
// Private - accessible within this type only
51+
private relation secret_info: [Any user]
52+
53+
// Default visibility (public if not specified)
54+
relation contributor: [Any user]
55+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
definition learning/document {
2+
permission approver = t_approver
3+
relation t_approver: learning/user
4+
permission can_approve = (approver & owner)
5+
permission can_delete = (owner - reviewer)
6+
permission can_edit = owner + editor
7+
permission can_publish = (owner + editor & approver)
8+
permission can_read = owner
9+
permission can_view = owner + editor + reviewer
10+
permission editor = t_editor
11+
relation t_editor: learning/user
12+
permission owner = t_owner
13+
relation t_owner: learning/user
14+
permission reviewer = t_reviewer
15+
relation t_reviewer: learning/user
16+
}
17+
18+
definition learning/project {
19+
permission contributor = t_contributor
20+
relation t_contributor: learning/user
21+
permission owner = t_owner
22+
relation t_owner: learning/user
23+
permission secret_info = t_secret_info
24+
relation t_secret_info: learning/user
25+
permission team_member = t_team_member
26+
relation t_team_member: learning/user
27+
}
28+
29+
definition learning/user {}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
definition files/document {
2+
permission author = t_author
3+
relation t_author: organization/user
4+
permission can_read = author + t_folder->can_read
5+
permission can_write = author + t_folder->can_manage
6+
permission folder = t_folder
7+
relation t_folder: files/folder
8+
permission shared_with = t_shared_with
9+
relation t_shared_with: organization/team#member
10+
}
11+
12+
definition files/folder {
13+
permission can_manage = owner + t_project->can_manage
14+
permission can_read = owner + t_project->team_members + t_parent->can_read
15+
permission owner = t_owner
16+
relation t_owner: organization/user
17+
permission parent = t_parent
18+
relation t_parent: files/folder
19+
permission project = t_project
20+
relation t_project: organization/project
21+
}
22+
23+
definition organization/project {
24+
permission can_manage = t_owner_team->can_manage + t_owner_team->member
25+
permission collaborator_teams = t_collaborator_teams
26+
relation t_collaborator_teams: organization/team
27+
permission managers = t_owner_team->manager
28+
permission owner_team = t_owner_team
29+
relation t_owner_team: organization/team
30+
permission team_members = t_owner_team->member + t_collaborator_teams->member
31+
}
32+
33+
definition organization/team {
34+
permission can_manage = manager
35+
permission manager = t_manager
36+
relation t_manager: organization/user
37+
permission member = t_member
38+
relation t_member: organization/user
39+
}
40+
41+
definition organization/user {}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
version 0.1
2+
namespace organization
3+
4+
public type user {
5+
6+
}
7+
8+
public type team {
9+
relation member: [Any user]
10+
relation manager: [ExactlyOne user]
11+
12+
// Permission derived from relations
13+
relation can_manage: manager
14+
}
15+
16+
public type project {
17+
relation owner_team: [ExactlyOne team]
18+
relation collaborator_teams: [Any team]
19+
20+
// Nested relation access - access team's members through the relation
21+
relation team_members: owner_team.member or collaborator_teams.member
22+
23+
// Nested relation with specific sub-relation
24+
relation managers: owner_team.manager
25+
26+
// Complex nested permissions
27+
relation can_manage: owner_team.can_manage or owner_team.member
28+
}

tutorials/02_cross_namespace.ksl

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
version 0.1
2+
namespace files
3+
import organization
4+
5+
public type folder {
6+
// Cross-namespace type reference
7+
relation owner: [ExactlyOne organization.user]
8+
relation parent: [AtMostOne folder]
9+
relation project: [AtMostOne organization.project]
10+
11+
// Cross-namespace nested relations
12+
relation can_read: owner or project.team_members or parent.can_read
13+
14+
// Complex cross-namespace permissions
15+
relation can_manage: owner or project.can_manage
16+
}
17+
18+
public type document {
19+
relation folder: [ExactlyOne folder]
20+
relation author: [ExactlyOne organization.user]
21+
22+
// Inherit permissions from folder
23+
relation can_read: author or folder.can_read
24+
relation can_write: author or folder.can_manage
25+
26+
// Self-referencing with cross-namespace
27+
relation shared_with: [Any organization.team.member]
28+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
definition inventory/server {
2+
permission can_delete = t_workspace->servers_delete
3+
permission can_read = t_workspace->servers_read
4+
permission can_write = t_workspace->servers_write
5+
permission workspace = t_workspace
6+
relation t_workspace: rbac/workspace
7+
}
8+
9+
definition rbac/principal {}
10+
11+
definition rbac/role {
12+
permission global_all_permissions = t_global_all_permissions
13+
relation t_global_all_permissions: rbac/principal:*
14+
permission mod_inventory_all_rel_can_delete = t_mod_inventory_all_rel_can_delete
15+
relation t_mod_inventory_all_rel_can_delete: rbac/principal:*
16+
permission mod_inventory_all_rel_can_read = t_mod_inventory_all_rel_can_read
17+
relation t_mod_inventory_all_rel_can_read: rbac/principal:*
18+
permission mod_inventory_all_rel_can_write = t_mod_inventory_all_rel_can_write
19+
relation t_mod_inventory_all_rel_can_write: rbac/principal:*
20+
permission mod_inventory_type_server_all = t_mod_inventory_type_server_all
21+
relation t_mod_inventory_type_server_all: rbac/principal:*
22+
permission servers_delete = t_servers_delete
23+
relation t_servers_delete: rbac/principal:*
24+
permission servers_read = t_servers_read
25+
relation t_servers_read: rbac/principal:*
26+
permission servers_write = t_servers_write
27+
relation t_servers_write: rbac/principal:*
28+
}
29+
30+
definition rbac/role_binding {
31+
permission granted = t_granted
32+
relation t_granted: rbac/role
33+
permission servers_delete = (subject & t_granted->servers_delete + t_granted->global_all_permissions + t_granted->mod_inventory_type_server_all + t_granted->mod_inventory_all_rel_can_delete)
34+
permission servers_read = (subject & t_granted->servers_read + t_granted->global_all_permissions + t_granted->mod_inventory_type_server_all + t_granted->mod_inventory_all_rel_can_read)
35+
permission servers_write = (subject & t_granted->servers_write + t_granted->global_all_permissions + t_granted->mod_inventory_type_server_all + t_granted->mod_inventory_all_rel_can_write)
36+
permission subject = t_subject
37+
relation t_subject: rbac/user
38+
}
39+
40+
definition rbac/user {}
41+
42+
definition rbac/workspace {
43+
permission parent = t_parent
44+
relation t_parent: rbac/workspace
45+
permission servers_delete = t_user_grant->servers_delete + t_parent->servers_delete
46+
permission servers_read = t_user_grant->servers_read + t_parent->servers_read
47+
permission servers_write = t_user_grant->servers_write + t_parent->servers_write
48+
permission user_grant = t_user_grant
49+
relation t_user_grant: rbac/role_binding
50+
}

tutorials/03_extension_system.ksl

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
version 0.1
2+
namespace rbac
3+
4+
// Required for [bool] type
5+
public type principal {
6+
7+
}
8+
9+
public type user {
10+
11+
}
12+
13+
public type role {
14+
15+
}
16+
17+
public type role_binding {
18+
relation subject: [ExactlyOne user]
19+
relation granted: [AtLeastOne role]
20+
}
21+
22+
public type workspace {
23+
relation parent: [AtMostOne workspace]
24+
relation user_grant: [Any role_binding]
25+
}
26+
27+
// Extension with parameters - the most powerful KSL feature
28+
public extension workspace_permission(permission_name) {
29+
// Template variable: ${permission_name} gets replaced with parameter value
30+
type role {
31+
// Dynamic relation name using parameter
32+
relation ${permission_name}: [bool]
33+
34+
// Template with built-in variables: MODULE, TYPE, RELATION
35+
allow_duplicates relation global_all_permissions: [bool]
36+
allow_duplicates relation `mod_${NAMESPACE}_type_${TYPE}_all`: [bool]
37+
allow_duplicates relation `mod_${NAMESPACE}_all_rel_${RELATION}`: [bool]
38+
}
39+
40+
// Complex templated logic
41+
type role_binding {
42+
relation ${permission_name}: subject and (
43+
granted.${permission_name} or
44+
granted.global_all_permissions or
45+
granted.`mod_${NAMESPACE}_type_${TYPE}_all` or
46+
granted.`mod_${NAMESPACE}_all_rel_${RELATION}`
47+
)
48+
}
49+
50+
// Inheritance through workspace hierarchy
51+
type workspace {
52+
public relation ${permission_name}: user_grant.${permission_name} or parent.${permission_name}
53+
}
54+
}

tutorials/03_extension_usage.ksl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
version 0.1
2+
namespace inventory
3+
import rbac
4+
5+
public type server {
6+
private relation workspace: [ExactlyOne rbac.workspace]
7+
8+
// Using the extension with @ syntax
9+
@rbac.workspace_permission(permission_name:'servers_read')
10+
public relation can_read: workspace.servers_read
11+
12+
@rbac.workspace_permission(permission_name:'servers_write')
13+
public relation can_write: workspace.servers_write
14+
15+
@rbac.workspace_permission(permission_name:'servers_delete')
16+
public relation can_delete: workspace.servers_delete
17+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
version 0.1
2+
namespace enterprise
3+
import rbac
4+
5+
// Complete real-world example using EVERY KSL feature
6+
public type application {
7+
// Cross-namespace import
8+
private relation workspace: [ExactlyOne rbac.workspace]
9+
10+
// All cardinality types
11+
relation owner: [ExactlyOne rbac.user] // ExactlyOne
12+
relation developers: [Any rbac.user] // Any
13+
relation tech_lead: [AtMostOne rbac.user] // AtMostOne
14+
relation stakeholders: [AtLeastOne rbac.user] // AtLeastOne
15+
16+
// All visibility types
17+
public relation can_deploy: owner or tech_lead
18+
internal relation can_debug: developers or tech_lead
19+
private relation admin_access: owner
20+
21+
// Complex relation expressions
22+
relation can_read: owner or developers or stakeholders
23+
relation can_write: (owner or tech_lead) and developers
24+
relation can_manage: owner unless tech_lead
25+
relation emergency_access: (owner or tech_lead) and stakeholders
26+
27+
// Cross-namespace nested relations
28+
relation workspace_access: workspace.user_grant
29+
30+
// Extensions usage
31+
@rbac.workspace_permission(permission_name:'app_deploy')
32+
public relation deploy_permission: workspace.app_deploy
33+
34+
@rbac.workspace_permission(permission_name:'app_monitor')
35+
public relation monitor_permission: workspace.app_monitor
36+
}
37+
38+
// Demonstrating complex hierarchies
39+
public type environment {
40+
relation application: [ExactlyOne application]
41+
relation environment_manager: [ExactlyOne rbac.user]
42+
43+
// Inherit from application with additional restrictions
44+
relation can_deploy: environment_manager and application.can_deploy
45+
relation can_read: environment_manager or application.can_read
46+
47+
// Self-referencing hierarchy
48+
relation parent_env: [AtMostOne environment]
49+
relation inherited_access: parent_env.can_read or parent_env.can_deploy
50+
}
51+
52+
// Using reserved keyword with escape
53+
public type database {
54+
relation #version: [ExactlyOne rbac.user] // Using # to escape reserved word
55+
relation backup_access: [Any rbac.user]
56+
}

0 commit comments

Comments
 (0)