[{"data":1,"prerenderedAt":806},["ShallowReactive",2],{"navigation_docs":3,"-reference-abac-expression-language":196,"-reference-abac-expression-language-surround":801},[4,127,166],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":36},"Kinotic Apps","i-lucide-rocket","\u002Fapps","1.apps",[10,14,18,37,58,91,106,122],{"title":11,"path":12,"stem":13},"Introduction","\u002Fapps\u002Fintroduction","1.apps\u002F1.introduction",{"title":15,"path":16,"stem":17},"Quick Start","\u002Fapps\u002Fquick-start","1.apps\u002F2.quick-start",{"title":19,"icon":20,"path":21,"stem":22,"children":23,"page":36},"Application Structure","i-lucide-folder-tree","\u002Fapps\u002Fapplication-structure","1.apps\u002F3.application-structure",[24,28,32],{"title":25,"path":26,"stem":27},"Overview","\u002Fapps\u002Fapplication-structure\u002Foverview","1.apps\u002F3.application-structure\u002F1.overview",{"title":29,"path":30,"stem":31},"Applications and Projects","\u002Fapps\u002Fapplication-structure\u002Fapplications-and-projects","1.apps\u002F3.application-structure\u002F2.applications-and-projects",{"title":33,"path":34,"stem":35},"Artifact Types","\u002Fapps\u002Fapplication-structure\u002Fartifact-types","1.apps\u002F3.application-structure\u002F3.artifact-types",false,{"title":38,"icon":39,"path":40,"stem":41,"children":42,"page":36},"Services","i-lucide-network","\u002Fapps\u002Fservices","1.apps\u002F4.services",[43,46,50,54],{"title":25,"path":44,"stem":45},"\u002Fapps\u002Fservices\u002Foverview","1.apps\u002F4.services\u002F1.overview",{"title":47,"path":48,"stem":49},"Publishing Services","\u002Fapps\u002Fservices\u002Fpublishing-services","1.apps\u002F4.services\u002F2.publishing-services",{"title":51,"path":52,"stem":53},"Service Proxies","\u002Fapps\u002Fservices\u002Fservice-proxies","1.apps\u002F4.services\u002F3.service-proxies",{"title":55,"path":56,"stem":57},"Streaming","\u002Fapps\u002Fservices\u002Fstreaming","1.apps\u002F4.services\u002F4.streaming",{"title":59,"icon":60,"path":61,"stem":62,"children":63,"page":36},"Persistence","i-lucide-database","\u002Fapps\u002Fpersistence","1.apps\u002F5.persistence",[64,67,71,75,79,83,87],{"title":25,"path":65,"stem":66},"\u002Fapps\u002Fpersistence\u002Foverview","1.apps\u002F5.persistence\u002F1.overview",{"title":68,"path":69,"stem":70},"Defining Entities","\u002Fapps\u002Fpersistence\u002Fdefining-entities","1.apps\u002F5.persistence\u002F2.defining-entities",{"title":72,"path":73,"stem":74},"Entity Decorators","\u002Fapps\u002Fpersistence\u002Fentity-decorators","1.apps\u002F5.persistence\u002F3.entity-decorators",{"title":76,"path":77,"stem":78},"CRUD Operations","\u002Fapps\u002Fpersistence\u002Fcrud-operations","1.apps\u002F5.persistence\u002F4.crud-operations",{"title":80,"path":81,"stem":82},"Named Queries","\u002Fapps\u002Fpersistence\u002Fnamed-queries","1.apps\u002F5.persistence\u002F5.named-queries",{"title":84,"path":85,"stem":86},"Multi-Tenancy","\u002Fapps\u002Fpersistence\u002Fmulti-tenancy","1.apps\u002F5.persistence\u002F6.multi-tenancy",{"title":88,"path":89,"stem":90},"Migrations","\u002Fapps\u002Fpersistence\u002Fmigrations","1.apps\u002F5.persistence\u002F7.migrations",{"title":92,"icon":93,"path":94,"stem":95,"children":96,"page":36},"Security","i-lucide-shield-check","\u002Fapps\u002Fsecurity","1.apps\u002F6.security",[97,101],{"title":98,"path":99,"stem":100,"icon":93},"Access Control","\u002Fapps\u002Fsecurity\u002Faccess-control","1.apps\u002F6.security\u002F1.access-control",{"title":102,"path":103,"stem":104,"icon":105},"Authentication","\u002Fapps\u002Fsecurity\u002Fauthentication","1.apps\u002F6.security\u002F2.authentication","i-lucide-key-round",{"title":107,"icon":108,"path":109,"stem":110,"children":111,"page":36},"Deployment","i-lucide-cloud-upload","\u002Fapps\u002Fdeployment","1.apps\u002F7.deployment",[112,117],{"title":113,"path":114,"stem":115,"icon":116},"Deployment Workflow","\u002Fapps\u002Fdeployment\u002Fworkflow","1.apps\u002F7.deployment\u002F1.workflow","i-lucide-git-branch",{"title":118,"path":119,"stem":120,"icon":121},"Environments","\u002Fapps\u002Fdeployment\u002Fenvironments","1.apps\u002F7.deployment\u002F2.environments","i-lucide-server",{"title":123,"path":124,"stem":125,"icon":126},"CLI Reference","\u002Fapps\u002Fcli-reference","1.apps\u002F8.cli-reference","i-lucide-terminal",{"title":128,"icon":121,"path":129,"stem":130,"children":131,"page":36},"Kinotic OS","\u002Fplatform","2.platform",[132,137,141,146,151,156,161],{"title":133,"path":134,"stem":135,"icon":136},"System Architecture","\u002Fplatform\u002Farchitecture","2.platform\u002F1.architecture","i-lucide-boxes",{"title":138,"path":139,"stem":140,"icon":6},"Deployment Guide","\u002Fplatform\u002Fdeployment-guide","2.platform\u002F2.deployment-guide",{"title":142,"path":143,"stem":144,"icon":145},"Configuration","\u002Fplatform\u002Fconfiguration","2.platform\u002F3.configuration","i-lucide-settings",{"title":147,"path":148,"stem":149,"icon":150},"Organization Management","\u002Fplatform\u002Forganization-management","2.platform\u002F4.organization-management","i-lucide-building-2",{"title":152,"path":153,"stem":154,"icon":155},"System Security","\u002Fplatform\u002Fsystem-security","2.platform\u002F5.system-security","i-lucide-shield",{"title":157,"path":158,"stem":159,"icon":160},"Observability","\u002Fplatform\u002Fobservability","2.platform\u002F6.observability","i-lucide-activity",{"title":162,"path":163,"stem":164,"icon":165},"Contributing","\u002Fplatform\u002Fcontributing","2.platform\u002F7.contributing","i-lucide-git-pull-request",{"title":167,"icon":168,"path":169,"stem":170,"children":171,"page":36},"Reference","i-lucide-book-open","\u002Freference","3.reference",[172,177,181,186,191],{"title":173,"path":174,"stem":175,"icon":176},"Decorators Reference","\u002Freference\u002Fdecorators","3.reference\u002F1.decorators","i-lucide-at-sign",{"title":178,"path":179,"stem":180,"icon":60},"Migration SQL Grammar","\u002Freference\u002Fmigration-sql-grammar","3.reference\u002F2.migration-sql-grammar",{"title":182,"path":183,"stem":184,"icon":185},"ABAC Expression Language","\u002Freference\u002Fabac-expression-language","3.reference\u002F3.abac-expression-language","i-lucide-file-code",{"title":187,"path":188,"stem":189,"icon":190},"CRI Format","\u002Freference\u002Fcri-format","3.reference\u002F4.cri-format","i-lucide-link",{"title":192,"path":193,"stem":194,"icon":195},"SDK Packages","\u002Freference\u002Fsdk-packages","3.reference\u002F5.sdk-packages","i-lucide-package",{"id":197,"title":182,"body":198,"description":794,"extension":795,"links":796,"meta":797,"navigation":798,"path":183,"seo":799,"stem":184,"__hash__":800},"docs\u002F3.reference\u002F3.abac-expression-language.md",{"type":199,"value":200,"toc":768},"minimark",[201,205,218,222,225,230,270,274,283,312,316,326,330,496,500,507,514,521,540,544,559,563,566,605,608,614,618,704,708,712,718,722,728,732,738,742,748,752,758,762],[202,203,25],"h2",{"id":204},"overview",[206,207,208,209,213,214,217],"p",{},"The ABAC (Attribute-Based Access Control) expression language is used to write policy expressions for both service method authorization and entity data filtering. The same syntax works in both ",[210,211,212],"code",{},"@AbacPolicy"," (service methods) and ",[210,215,216],{},"$AbacPolicy"," (entity decorators).",[202,219,221],{"id":220},"attribute-paths","Attribute Paths",[206,223,224],{},"Expressions reference attributes using dotted notation. The root identifier determines what the path resolves against.",[226,227,229],"h3",{"id":228},"reserved-roots","Reserved Roots",[231,232,233,246],"table",{},[234,235,236],"thead",{},[237,238,239,243],"tr",{},[240,241,242],"th",{},"Root",[240,244,245],{},"Description",[247,248,249,260],"tbody",{},[237,250,251,257],{},[252,253,254],"td",{},[210,255,256],{},"participant",[252,258,259],{},"The authenticated caller. Access roles, department, limits, and other identity attributes.",[237,261,262,267],{},[252,263,264],{},[210,265,266],{},"context",[252,268,269],{},"The request environment. Access time, IP address, and other contextual data.",[226,271,273],{"id":272},"dynamic-roots","Dynamic Roots",[206,275,276,277,279,280,282],{},"Any root identifier that is not ",[210,278,256],{}," or ",[210,281,266],{}," is resolved based on the policy context:",[284,285,286,302],"ul",{},[287,288,289,293,294,297,298,301],"li",{},[290,291,292],"strong",{},"Service method policies"," — Resolved against method parameter names. For ",[210,295,296],{},"placeOrder(order: Order)",", the root ",[210,299,300],{},"order"," refers to the first argument.",[287,303,304,307,308,311],{},[290,305,306],{},"Entity policies"," — The root ",[210,309,310],{},"entity"," refers to the entity being accessed.",[226,313,315],{"id":314},"examples","Examples",[317,318,323],"pre",{"className":319,"code":321,"language":322},[320],"language-text","participant.roles                  -- caller's roles array\nparticipant.department             -- caller's department\nparticipant.transferLimit          -- caller's transfer limit\ncontext.time                       -- request timestamp\nentity.ownerId                     -- entity's ownerId field\nentity.sharedWith                  -- entity's sharedWith array\norder.amount                       -- method parameter's amount field\ntransfer.fromAccount               -- method parameter's fromAccount field\n","text",[210,324,321],{"__ignoreMap":325},"",[202,327,329],{"id":328},"operators","Operators",[231,331,332,344],{},[234,333,334],{},[237,335,336,339,341],{},[240,337,338],{},"Operator",[240,340,245],{},[240,342,343],{},"Example",[247,345,346,361,376,391,406,421,436,451,466,481],{},[237,347,348,353,356],{},[252,349,350],{},[210,351,352],{},"==",[252,354,355],{},"Equals",[252,357,358],{},[210,359,360],{},"participant.department == 'engineering'",[237,362,363,368,371],{},[252,364,365],{},[210,366,367],{},"!=",[252,369,370],{},"Not equals",[252,372,373],{},[210,374,375],{},"entity.status != 'archived'",[237,377,378,383,386],{},[252,379,380],{},[210,381,382],{},"\u003C",[252,384,385],{},"Less than",[252,387,388],{},[210,389,390],{},"order.amount \u003C 50000",[237,392,393,398,401],{},[252,394,395],{},[210,396,397],{},">",[252,399,400],{},"Greater than",[252,402,403],{},[210,404,405],{},"entity.priority > 3",[237,407,408,413,416],{},[252,409,410],{},[210,411,412],{},"\u003C=",[252,414,415],{},"Less than or equal",[252,417,418],{},[210,419,420],{},"transfer.amount \u003C= participant.transferLimit",[237,422,423,428,431],{},[252,424,425],{},[210,426,427],{},">=",[252,429,430],{},"Greater than or equal",[252,432,433],{},[210,434,435],{},"entity.score >= 80",[237,437,438,443,446],{},[252,439,440],{},[210,441,442],{},"contains",[252,444,445],{},"Collection membership",[252,447,448],{},[210,449,450],{},"participant.roles contains 'admin'",[237,452,453,458,461],{},[252,454,455],{},[210,456,457],{},"in",[252,459,460],{},"Value in set",[252,462,463],{},[210,464,465],{},"entity.status in ['active', 'pending']",[237,467,468,473,476],{},[252,469,470],{},[210,471,472],{},"exists",[252,474,475],{},"Field presence",[252,477,478],{},[210,479,480],{},"entity.approvedBy exists",[237,482,483,488,491],{},[252,484,485],{},[210,486,487],{},"like",[252,489,490],{},"Pattern match (wildcards)",[252,492,493],{},[210,494,495],{},"entity.email like '*@kinotic.ai'",[226,497,499],{"id":498},"operator-details","Operator Details",[206,501,502,506],{},[290,503,504],{},[210,505,442],{}," — Tests whether a collection (array) includes a value. The left side must be a collection attribute.",[206,508,509,513],{},[290,510,511],{},[210,512,457],{}," — Tests whether a value is present in a literal set. The right side must be a bracketed list of literals.",[206,515,516,520],{},[290,517,518],{},[210,519,472],{}," — Tests whether a field is present and non-null. No right-hand value is needed.",[206,522,523,527,528,531,532,535,536,539],{},[290,524,525],{},[210,526,487],{}," — Pattern matching with ",[210,529,530],{},"*"," as a wildcard. ",[210,533,534],{},"*@kinotic.ai"," matches any string ending with ",[210,537,538],{},"@kinotic.ai",".",[202,541,543],{"id":542},"boolean-logic","Boolean Logic",[206,545,546,547,550,551,554,555,558],{},"Combine conditions with ",[210,548,549],{},"and",", ",[210,552,553],{},"or",", and ",[210,556,557],{},"not",". Parentheses override default precedence. All keywords are case-insensitive.",[226,560,562],{"id":561},"precedence","Precedence",[206,564,565],{},"From highest to lowest:",[567,568,569,593,597,601],"ol",{},[287,570,571,572,550,574,550,576,550,578,550,580,550,582,550,584,550,586,550,588,550,590,592],{},"Comparisons (",[210,573,352],{},[210,575,367],{},[210,577,382],{},[210,579,397],{},[210,581,412],{},[210,583,427],{},[210,585,442],{},[210,587,457],{},[210,589,472],{},[210,591,487],{},")",[287,594,595],{},[210,596,557],{},[287,598,599],{},[210,600,549],{},[287,602,603],{},[210,604,553],{},[226,606,315],{"id":607},"examples-1",[317,609,612],{"className":610,"code":611,"language":322},[320],"-- AND: both conditions must be true\nparticipant.roles contains 'finance' and order.amount \u003C 50000\n\n-- OR: either condition must be true\nentity.status in ['active', 'pending'] or participant.department == entity.department\n\n-- NOT: negates the condition\nnot entity.deleted == true\n\n-- Parentheses: override precedence\n(participant.roles contains 'admin' or participant.roles contains 'manager')\n    and entity.classification != 'top-secret'\n",[210,613,611],{"__ignoreMap":325},[202,615,617],{"id":616},"literals","Literals",[231,619,620,632],{},[234,621,622],{},[237,623,624,627,630],{},[240,625,626],{},"Type",[240,628,629],{},"Syntax",[240,631,343],{},[247,633,634,647,660,673,691],{},[237,635,636,639,642],{},[252,637,638],{},"String",[252,640,641],{},"Single quotes",[252,643,644],{},[210,645,646],{},"'finance'",[237,648,649,652,655],{},[252,650,651],{},"Integer",[252,653,654],{},"Digits",[252,656,657],{},[210,658,659],{},"50000",[237,661,662,665,668],{},[252,663,664],{},"Decimal",[252,666,667],{},"Digits with dot",[252,669,670],{},[210,671,672],{},"3.14",[237,674,675,678,687],{},[252,676,677],{},"Boolean",[252,679,680,683,684],{},[210,681,682],{},"true"," \u002F ",[210,685,686],{},"false",[252,688,689],{},[210,690,682],{},[237,692,693,696,699],{},[252,694,695],{},"Set",[252,697,698],{},"Brackets with literals",[252,700,701],{},[210,702,703],{},"['active', 'pending']",[202,705,707],{"id":706},"common-patterns","Common Patterns",[226,709,711],{"id":710},"role-checks","Role Checks",[317,713,716],{"className":714,"code":715,"language":322},[320],"-- Single role\nparticipant.roles contains 'admin'\n\n-- Any of multiple roles (OR)\nparticipant.roles contains 'admin' or participant.roles contains 'manager'\n\n-- All of multiple roles (AND)\nparticipant.roles contains 'finance' and participant.roles contains 'approver'\n",[210,717,715],{"__ignoreMap":325},[226,719,721],{"id":720},"ownership","Ownership",[317,723,726],{"className":724,"code":725,"language":322},[320],"-- Entity owner\nentity.ownerId == participant.id\n\n-- Owner or shared\nentity.ownerId == participant.id or entity.sharedWith contains participant.id\n",[210,727,725],{"__ignoreMap":325},[226,729,731],{"id":730},"department-based","Department-Based",[317,733,736],{"className":734,"code":735,"language":322},[320],"-- Same department\nentity.department == participant.department\n\n-- Specific department\nparticipant.department == 'engineering'\n",[210,737,735],{"__ignoreMap":325},[226,739,741],{"id":740},"amount-limits","Amount Limits",[317,743,746],{"className":744,"code":745,"language":322},[320],"-- Under a fixed limit\norder.amount \u003C 50000\n\n-- Under caller's personal limit\ntransfer.amount \u003C= participant.transferLimit\n",[210,747,745],{"__ignoreMap":325},[226,749,751],{"id":750},"status-filtering","Status Filtering",[317,753,756],{"className":754,"code":755,"language":322},[320],"-- Specific statuses\nentity.status in ['active', 'pending']\n\n-- Exclude archived\nentity.status != 'archived'\n\n-- Exclude soft-deleted\nnot entity.deleted == true\n",[210,757,755],{"__ignoreMap":325},[226,759,761],{"id":760},"combined-policies","Combined Policies",[317,763,766],{"className":764,"code":765,"language":322},[320],"-- Finance role with amount cap\nparticipant.roles contains 'finance' and order.amount \u003C 50000\n\n-- Admin or owner\nparticipant.roles contains 'admin' or entity.ownerId == participant.id\n\n-- Department match with classification restriction\nparticipant.department == entity.department\n    and entity.classification != 'top-secret'\n",[210,767,765],{"__ignoreMap":325},{"title":325,"searchDepth":769,"depth":769,"links":770},2,[771,772,778,781,785,786],{"id":204,"depth":769,"text":25},{"id":220,"depth":769,"text":221,"children":773},[774,776,777],{"id":228,"depth":775,"text":229},3,{"id":272,"depth":775,"text":273},{"id":314,"depth":775,"text":315},{"id":328,"depth":769,"text":329,"children":779},[780],{"id":498,"depth":775,"text":499},{"id":542,"depth":769,"text":543,"children":782},[783,784],{"id":561,"depth":775,"text":562},{"id":607,"depth":775,"text":315},{"id":616,"depth":769,"text":617},{"id":706,"depth":769,"text":707,"children":787},[788,789,790,791,792,793],{"id":710,"depth":775,"text":711},{"id":720,"depth":775,"text":721},{"id":730,"depth":775,"text":731},{"id":740,"depth":775,"text":741},{"id":750,"depth":775,"text":751},{"id":760,"depth":775,"text":761},"Complete reference for the ABAC policy expression language.","md",null,{},{"icon":185},{"title":182,"description":794},"2QwZ57SS9lwgYVQRj0ISWwpnr2TrNUW4y6C_dV4JVUY",[802,804],{"title":178,"path":179,"stem":180,"description":803,"icon":60,"children":-1},"Complete SQL grammar reference for migration scripts.",{"title":187,"path":188,"stem":189,"description":805,"icon":190,"children":-1},"Kinotic Resource Identifier specification.",1775187762911]