silly-musician-15276
12/02/2025, 8:39 AMimport { Namespace, Context } from "@ory/keto-namespace-types";
class User implements Namespace {}
class School implements Namespace {
related: {
// Users with read-only access (Students, regular Staff)
members: User[];
// Users with write access (Admins, maybe Teachers depending on logic)
admins: User[];
};
permits = {
// Write allows Create, Update, Delete
write: (ctx: Context): boolean => this.related.admins.includes(ctx.subject),
// Read allows View. Note: Admins can also read.
read: (ctx: Context): boolean =>
this.related.admins.includes(ctx.subject) ||
this.related.members.includes(ctx.subject),
};
}
// --- Level 1 Resources (Direct children of School) ---
class Building implements Namespace {
related: {
parentSchool: School[];
};
permits = {
write: (ctx: Context): boolean =>
this.related.parentSchool.traverse(s => s.permits.write(ctx)),
read: (ctx: Context): boolean =>
this.related.parentSchool.traverse(s => s.permits.read(ctx)),
};
}
class Subject implements Namespace {
related: {
parentSchool: School[];
};
permits = {
write: (ctx: Context): boolean =>
this.related.parentSchool.traverse(s => s.permits.write(ctx)),
read: (ctx: Context): boolean =>
this.related.parentSchool.traverse(s => s.permits.read(ctx)),
};
}
class Class implements Namespace {
related: {
parentSchool: School[];
};
permits = {
write: (ctx: Context): boolean =>
this.related.parentSchool.traverse(s => s.permits.write(ctx)),
read: (ctx: Context): boolean =>
this.related.parentSchool.traverse(s => s.permits.read(ctx)),
};
}
// --- Level 2 Resources (Grandchildren of School) ---
class Floor implements Namespace {
related: {
parentBuilding: Building[];
};
permits = {
write: (ctx: Context): boolean =>
this.related.parentBuilding.traverse(b => b.permits.write(ctx)),
read: (ctx: Context): boolean =>
this.related.parentBuilding.traverse(b => b.permits.read(ctx)),
};
}
class DailySchedule implements Namespace {
related: {
parentClass: Class[];
};
permits = {
write: (ctx: Context): boolean =>
this.related.parentClass.traverse(c => c.permits.write(ctx)),
read: (ctx: Context): boolean =>
this.related.parentClass.traverse(c => c.permits.read(ctx)),
};
}
// --- Level 3 Resources (Great-grandchildren) ---
class Room implements Namespace {
related: {
parentFloor: Floor[];
};
permits = {
write: (ctx: Context): boolean =>
this.related.parentFloor.traverse(f => f.permits.write(ctx)),
read: (ctx: Context): boolean =>
this.related.parentFloor.traverse(f => f.permits.read(ctx)),
};
}
class Lesson implements Namespace {
related: {
// Lesson is linked to Room, Teacher, Subject, and Schedule.
// For general access control, inheriting from Schedule (and thus Class)
// is the most logical path for "School-based isolation".
parentSchedule: DailySchedule[];
};
permits = {
write: (ctx: Context): boolean =>
this.related.parentSchedule.traverse(s => s.permits.write(ctx)),
read: (ctx: Context): boolean =>
this.related.parentSchedule.traverse(s => s.permits.read(ctx)),
};
}
{
"id": "protected-resources",
"description": "Strictly protects all known API resources. Requires valid Cookie.",
"upstream": {
"url": "<http://server:8393/>"
},
"match": {
"url": "<https://api.example.org/><(users|schools|teachers|students|classes|subjects|daily-schedules|lessons|buildings|floors|rooms|roles)(/.*)?>",
"methods": [
"GET",
"POST",
"PUT",
"PATCH",
"DELETE",
"OPTIONS"
]
},
"authenticators": [
{
"handler": "oauth2_introspection"
}
],
"authorizer": {
"handler": "allow"
},
"mutators": [
{
"handler": "id_token"
}
]
}