From b9d0bd8a5c336f3fbb46607eb5afd751cbc6af3c Mon Sep 17 00:00:00 2001 From: aaguiarz Date: Mon, 6 May 2024 19:29:05 +0000 Subject: [PATCH] =?UTF-8?q?Deploy=20preview=20for=20PR=20728=20?= =?UTF-8?q?=F0=9F=9B=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pr-preview/pr-728/search-index.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pr-preview/pr-728/search-index.json b/pr-preview/pr-728/search-index.json index 787924f8b..1eb25f15e 100644 --- a/pr-preview/pr-728/search-index.json +++ b/pr-preview/pr-728/search-index.json @@ -1 +1 @@ -[{"documents":[{"i":1,"t":"","u":"/pr-preview/pr-728/blog/archive","b":["Home"]},{"i":2,"t":"Conditional Relationship Tuples for OpenFGA","u":"/pr-preview/pr-728/blog/conditional-tuples-announcement","b":["Home"]},{"i":12,"t":"Fine Grained News - December 2023","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","b":["Home"]},{"i":36,"t":"Fine Grained News - February 2024","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-02","b":["Home"]},{"i":54,"t":"Fine Grained News - March 2024","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-03","b":["Home"]},{"i":70,"t":"Fine Grained News - January 2024","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","b":["Home"]},{"i":96,"t":"List Users API","u":"/pr-preview/pr-728/blog/list-users-announcement","b":["Home"]},{"i":104,"t":"Fine Grained News - April 2024","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-04","b":["Home"]},{"i":118,"t":"OpenFGA Community","u":"/pr-preview/pr-728/docs/community","b":["Home"]},{"i":131,"t":"Join the OpenFGA team at KubeCon NA 2023","u":"/pr-preview/pr-728/blog/kubecon-na-2023","b":["Home"]},{"i":133,"t":"Authorization Concepts","u":"/pr-preview/pr-728/docs/authorization-concepts","b":["Home"]},{"i":148,"t":"Modular Models","u":"/pr-preview/pr-728/blog/modular-models-announcement","b":["Home"]},{"i":156,"t":"Content","u":"/pr-preview/pr-728/docs/getting-started","b":["Home","Getting Started"]},{"i":158,"t":"Introduction to OpenFGA","u":"/pr-preview/pr-728/docs/fga","b":["Home"]},{"i":166,"t":"Use the FGA CLI","u":"/pr-preview/pr-728/docs/getting-started/cli","b":["Home","Getting Started"]},{"i":188,"t":"Create a Store","u":"/pr-preview/pr-728/docs/getting-started/create-store","b":["Home","Getting Started"]},{"i":192,"t":"Integrate Within a Framework","u":"/pr-preview/pr-728/docs/getting-started/framework","b":["Home","Getting Started"]},{"i":206,"t":"Install SDK Client","u":"/pr-preview/pr-728/docs/getting-started/install-sdk","b":["Home","Getting Started"]},{"i":220,"t":"Immutable Authorization Models","u":"/pr-preview/pr-728/docs/getting-started/immutable-models","b":["Home","Getting Started"]},{"i":232,"t":"Perform a Check","u":"/pr-preview/pr-728/docs/getting-started/perform-check","b":["Home","Getting Started"]},{"i":244,"t":"Perform a List Objects call","u":"/pr-preview/pr-728/docs/getting-started/perform-list-objects","b":["Home","Getting Started"]},{"i":256,"t":"Running OpenFGA in Production","u":"/pr-preview/pr-728/docs/getting-started/running-in-production","b":["Home","Getting Started"]},{"i":264,"t":"Configuring OpenFGA","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","b":["Home","Getting Started","Setup OpenFGA"]},{"i":300,"t":"🐳 Setup OpenFGA with Docker","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/docker","b":["Home","Getting Started","Setup OpenFGA"]},{"i":316,"t":"Configure Authorization Model for a Store","u":"/pr-preview/pr-728/docs/getting-started/configure-model","b":["Home","Getting Started"]},{"i":324,"t":"☸️ Setup OpenFGA with Kubernetes","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/kubernetes","b":["Home","Getting Started","Setup OpenFGA"]},{"i":326,"t":"Setup OpenFGA","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/overview","b":["Home","Getting Started","Setup OpenFGA"]},{"i":328,"t":"Best Practices of Managing Tuples and Invoking APIs","u":"/pr-preview/pr-728/docs/getting-started/tuples-api-best-practices","b":["Home","Getting Started"]},{"i":336,"t":"Using the OpenFGA Playground","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/playground","b":["Home","Getting Started","Setup OpenFGA"]},{"i":342,"t":"Update Relationship Tuples","u":"/pr-preview/pr-728/docs/getting-started/update-tuples","b":["Home","Getting Started"]},{"i":356,"t":"Content","u":"/pr-preview/pr-728/docs/interacting","b":["Home","Interacting with the API"]},{"i":358,"t":"Configuration Language","u":"/pr-preview/pr-728/docs/configuration-language","b":["Home"]},{"i":378,"t":"Concepts","u":"/pr-preview/pr-728/docs/concepts","b":["Home"]},{"i":418,"t":"Setup SDK Client for Store","u":"/pr-preview/pr-728/docs/getting-started/setup-sdk-client","b":["Home","Getting Started"]},{"i":426,"t":"Managing User Access","u":"/pr-preview/pr-728/docs/interacting/managing-user-access","b":["Home","Interacting with the API"]},{"i":441,"t":"How to get tuple changes","u":"/pr-preview/pr-728/docs/interacting/read-tuple-changes","b":["Home","Interacting with the API"]},{"i":453,"t":"Managing Group Access","u":"/pr-preview/pr-728/docs/interacting/managing-group-access","b":["Home","Interacting with the API"]},{"i":470,"t":"Search With Permissions","u":"/pr-preview/pr-728/docs/interacting/search-with-permissions","b":["Home","Interacting with the API"]},{"i":484,"t":"Content","u":"/pr-preview/pr-728/docs/modeling","b":["Home","Modeling Guides"]},{"i":486,"t":"Advanced Use-Cases","u":"/pr-preview/pr-728/docs/modeling/advanced","b":["Home","Modeling Guides","Advanced Use-Cases"]},{"i":492,"t":"Transactional Writes","u":"/pr-preview/pr-728/docs/interacting/transactional-writes","b":["Home","Interacting with the API"]},{"i":509,"t":"Content","u":"/pr-preview/pr-728/docs/modeling/building-blocks","b":["Home","Modeling Guides","Building Blocks"]},{"i":511,"t":"Concentric Relationships","u":"/pr-preview/pr-728/docs/modeling/building-blocks/concentric-relationships","b":["Home","Modeling Guides","Building Blocks"]},{"i":527,"t":"Conditions","u":"/pr-preview/pr-728/docs/modeling/conditions","b":["Home","Modeling Guides"]},{"i":542,"t":"Usersets","u":"/pr-preview/pr-728/docs/modeling/building-blocks/usersets","b":["Home","Modeling Guides","Building Blocks"]},{"i":553,"t":"Direct Access","u":"/pr-preview/pr-728/docs/modeling/direct-access","b":["Home","Modeling Guides"]},{"i":567,"t":"Content","u":"/pr-preview/pr-728/docs/modeling/migrating","b":["Home","Modeling Guides","Migrations"]},{"i":569,"t":"Custom Roles","u":"/pr-preview/pr-728/docs/modeling/custom-roles","b":["Home","Modeling Guides"]},{"i":593,"t":"Get Started with Modeling","u":"/pr-preview/pr-728/docs/modeling/getting-started","b":["Home","Modeling Guides"]},{"i":613,"t":"Multiple Restrictions","u":"/pr-preview/pr-728/docs/modeling/multiple-restrictions","b":["Home","Modeling Guides"]},{"i":631,"t":"Modular Models","u":"/pr-preview/pr-728/docs/modeling/modular-models","b":["Home","Modeling Guides"]},{"i":654,"t":"Parent-Child Objects","u":"/pr-preview/pr-728/docs/modeling/parent-child","b":["Home","Modeling Guides"]},{"i":676,"t":"Testing Models","u":"/pr-preview/pr-728/docs/modeling/testing","b":["Home","Modeling Guides"]},{"i":692,"t":"Use Token Claims As Contextual Tuples","u":"/pr-preview/pr-728/docs/modeling/token-claims-contextual-tuples","b":["Home","Modeling Guides"]},{"i":702,"t":"Public Access","u":"/pr-preview/pr-728/docs/modeling/public-access","b":["Home","Modeling Guides"]},{"i":718,"t":"User Groups","u":"/pr-preview/pr-728/docs/modeling/user-groups","b":["Home","Modeling Guides"]},{"i":738,"t":"Managing Relationships Between Objects","u":"/pr-preview/pr-728/docs/interacting/managing-relationships-between-objects","b":["Home","Interacting with the API"]},{"i":760,"t":"Managing Group Membership","u":"/pr-preview/pr-728/docs/interacting/managing-group-membership","b":["Home","Interacting with the API"]},{"i":777,"t":"Blocklists","u":"/pr-preview/pr-728/docs/modeling/blocklists","b":["Home","Modeling Guides"]},{"i":795,"t":"Relationship Queries: Check, Read, Expand, and ListObjects","u":"/pr-preview/pr-728/docs/interacting/relationship-queries","b":["Home","Interacting with the API"]},{"i":833,"t":"Object to Object Relationships","u":"/pr-preview/pr-728/docs/modeling/building-blocks/object-to-object-relationships","b":["Home","Modeling Guides","Building Blocks"]},{"i":860,"t":"Roles and Permissions","u":"/pr-preview/pr-728/docs/modeling/roles-and-permissions","b":["Home","Modeling Guides"]},{"i":878,"t":"Direct Relationships","u":"/pr-preview/pr-728/docs/modeling/building-blocks/direct-relationships","b":["Home","Modeling Guides","Building Blocks"]},{"i":898,"t":"Migrating Relations","u":"/pr-preview/pr-728/docs/modeling/migrating/migrating-relations","b":["Home","Modeling Guides","Migrations"]},{"i":914,"t":"Authorization Through Organization Context","u":"/pr-preview/pr-728/docs/modeling/organization-context-authorization","b":["Home","Modeling Guides"]},{"i":936,"t":"Modeling Authorization for an IoT Security System with OpenFGA","u":"/pr-preview/pr-728/docs/modeling/advanced/iot","b":["Home","Modeling Guides","Advanced Use-Cases"]},{"i":964,"t":"Modeling Entitlements for a System with OpenFGA","u":"/pr-preview/pr-728/docs/modeling/advanced/entitlements","b":["Home","Modeling Guides","Advanced Use-Cases"]},{"i":985,"t":"Modeling GitHub permissions with OpenFGA","u":"/pr-preview/pr-728/docs/modeling/advanced/github","b":["Home","Modeling Guides","Advanced Use-Cases"]},{"i":1008,"t":"Contextual and Time-Based Authorization","u":"/pr-preview/pr-728/docs/modeling/contextual-time-based-authorization","b":["Home","Modeling Guides"]},{"i":1032,"t":"Modeling Google Drive permissions with OpenFGA","u":"/pr-preview/pr-728/docs/modeling/advanced/gdrive","b":["Home","Modeling Guides","Advanced Use-Cases"]},{"i":1055,"t":"Modeling Authorization for Slack with OpenFGA","u":"/pr-preview/pr-728/docs/modeling/advanced/slack","b":["Home","Modeling Guides","Advanced Use-Cases"]}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/1",[]],["t/2",[0,2.91,1,1.958,2,2.227,3,1.33]],["t/12",[4,1.985,5,1.985,6,1.985,7,2.987,8,2.593]],["t/36",[4,1.985,5,1.985,6,1.985,9,2.987,10,2.14]],["t/54",[4,1.985,5,1.985,6,1.985,10,2.14,11,2.987]],["t/70",[4,1.985,5,1.985,6,1.985,10,2.14,12,2.987]],["t/96",[13,3.314,14,2.982,15,3.314]],["t/104",[4,1.985,5,1.985,6,1.985,10,2.14,16,2.987]],["t/118",[3,1.759,17,4.435]],["t/131",[3,1.069,8,2.339,18,2.694,19,2.694,20,2.694,21,2.694]],["t/133",[22,2.591,23,3.85]],["t/148",[24,3.85,25,2.101]],["t/156",[26,3.514]],["t/158",[3,1.759,27,4.435]],["t/166",[28,2.735,29,3.818,30,3.818]],["t/188",[31,4.435,32,3.464]],["t/192",[33,3.818,34,3.818,35,3.818]],["t/206",[36,3.818,37,3.314,38,3.314]],["t/220",[22,2.231,25,1.809,39,3.818]],["t/232",[40,3.85,41,3.85]],["t/244",[13,2.91,40,2.91,42,2.401,43,3.352]],["t/256",[3,1.515,44,3.818,45,3.818]],["t/264",[3,1.759,46,3.464]],["t/300",[3,1.33,47,2.91,48,2.401,49,3.352]],["t/316",[22,1.958,25,1.588,32,2.618,46,2.618]],["t/324",[3,1.33,47,2.91,48,2.401,50,3.352]],["t/326",[3,1.759,48,3.176]],["t/328",[2,1.79,15,2.339,51,2.694,52,2.694,53,1.79,54,2.694]],["t/336",[3,1.515,28,2.735,55,3.818]],["t/342",[1,2.231,2,2.537,56,3.818]],["t/356",[26,3.514]],["t/358",[46,3.464,57,4.435]],["t/378",[23,4.591]],["t/418",[32,2.618,37,2.91,38,2.91,48,2.401]],["t/426",[14,2.982,53,2.537,58,2.735]],["t/441",[2,2.946,59,4.435]],["t/453",[53,2.537,58,2.735,60,2.982]],["t/470",[61,4.435,62,3.176]],["t/484",[26,3.514]],["t/486",[28,2.735,63,3.818,64,3.818]],["t/492",[65,4.435,66,4.435]],["t/509",[26,3.514]],["t/511",[1,2.591,67,4.435]],["t/527",[0,4.591]],["t/542",[68,5.289]],["t/553",[58,3.176,69,3.85]],["t/567",[26,3.514]],["t/569",[70,4.435,71,3.85]],["t/593",[25,2.101,72,4.435]],["t/613",[73,4.435,74,4.435]],["t/631",[24,3.85,25,2.101]],["t/654",[42,2.735,75,3.818,76,3.818]],["t/676",[25,2.101,77,4.435]],["t/692",[2,1.985,28,2.14,78,2.987,79,2.987,80,2.593]],["t/702",[58,3.176,81,4.435]],["t/718",[14,3.464,60,3.464]],["t/738",[1,1.958,42,2.401,53,2.227,82,3.352]],["t/760",[53,2.537,60,2.982,83,3.818]],["t/777",[84,5.289]],["t/795",[1,1.574,41,2.339,85,2.694,86,2.694,87,2.694,88,2.694]],["t/833",[1,2.231,42,3.776]],["t/860",[62,3.176,71,3.85]],["t/878",[1,2.591,69,3.85]],["t/898",[89,4.435,90,4.435]],["t/914",[22,1.958,91,3.352,92,3.352,93,3.352]],["t/936",[3,1.069,22,1.574,25,1.277,94,2.694,95,2.694,96,2.339]],["t/964",[3,1.33,25,1.588,96,2.91,97,3.352]],["t/985",[3,1.33,25,1.588,62,2.401,98,3.352]],["t/1008",[22,1.958,80,2.91,99,3.352,100,3.352]],["t/1032",[3,1.185,25,1.415,62,2.14,101,2.987,102,2.987]],["t/1055",[3,1.33,22,1.958,25,1.588,103,3.352]]],"invertedIndex":[["",{"_index":47,"t":{"300":{"position":[[0,2]]},"324":{"position":[[0,2]]}}}],["2023",{"_index":8,"t":{"12":{"position":[[29,4]]},"131":{"position":[[36,4]]}}}],["2024",{"_index":10,"t":{"36":{"position":[[29,4]]},"54":{"position":[[26,4]]},"70":{"position":[[28,4]]},"104":{"position":[[26,4]]}}}],["access",{"_index":58,"t":{"426":{"position":[[14,6]]},"453":{"position":[[15,6]]},"553":{"position":[[7,6]]},"702":{"position":[[7,6]]}}}],["advanc",{"_index":63,"t":{"486":{"position":[[0,8]]}}}],["api",{"_index":15,"t":{"96":{"position":[[11,3]]},"328":{"position":[[47,4]]}}}],["april",{"_index":16,"t":{"104":{"position":[[20,5]]}}}],["author",{"_index":22,"t":{"133":{"position":[[0,13]]},"220":{"position":[[10,13]]},"316":{"position":[[10,13]]},"914":{"position":[[0,13]]},"936":{"position":[[9,13]]},"1008":{"position":[[26,13]]},"1055":{"position":[[9,13]]}}}],["base",{"_index":100,"t":{"1008":{"position":[[20,5]]}}}],["best",{"_index":51,"t":{"328":{"position":[[0,4]]}}}],["between",{"_index":82,"t":{"738":{"position":[[23,7]]}}}],["blocklist",{"_index":84,"t":{"777":{"position":[[0,10]]}}}],["call",{"_index":43,"t":{"244":{"position":[[23,4]]}}}],["case",{"_index":64,"t":{"486":{"position":[[13,5]]}}}],["chang",{"_index":59,"t":{"441":{"position":[[17,7]]}}}],["check",{"_index":41,"t":{"232":{"position":[[10,5]]},"795":{"position":[[22,6]]}}}],["child",{"_index":76,"t":{"654":{"position":[[7,5]]}}}],["claim",{"_index":79,"t":{"692":{"position":[[10,6]]}}}],["cli",{"_index":30,"t":{"166":{"position":[[12,3]]}}}],["client",{"_index":38,"t":{"206":{"position":[[12,6]]},"418":{"position":[[10,6]]}}}],["commun",{"_index":17,"t":{"118":{"position":[[8,9]]}}}],["concentr",{"_index":67,"t":{"511":{"position":[[0,10]]}}}],["concept",{"_index":23,"t":{"133":{"position":[[14,8]]},"378":{"position":[[0,8]]}}}],["condit",{"_index":0,"t":{"2":{"position":[[0,11]]},"527":{"position":[[0,10]]}}}],["configur",{"_index":46,"t":{"264":{"position":[[0,11]]},"316":{"position":[[0,9]]},"358":{"position":[[0,13]]}}}],["content",{"_index":26,"t":{"156":{"position":[[0,7]]},"356":{"position":[[0,7]]},"484":{"position":[[0,7]]},"509":{"position":[[0,7]]},"567":{"position":[[0,7]]}}}],["context",{"_index":93,"t":{"914":{"position":[[35,7]]}}}],["contextu",{"_index":80,"t":{"692":{"position":[[20,10]]},"1008":{"position":[[0,10]]}}}],["creat",{"_index":31,"t":{"188":{"position":[[0,6]]}}}],["custom",{"_index":70,"t":{"569":{"position":[[0,6]]}}}],["decemb",{"_index":7,"t":{"12":{"position":[[20,8]]}}}],["direct",{"_index":69,"t":{"553":{"position":[[0,6]]},"878":{"position":[[0,6]]}}}],["docker",{"_index":49,"t":{"300":{"position":[[22,6]]}}}],["drive",{"_index":102,"t":{"1032":{"position":[[16,5]]}}}],["entitl",{"_index":97,"t":{"964":{"position":[[9,12]]}}}],["expand",{"_index":87,"t":{"795":{"position":[[35,7]]}}}],["februari",{"_index":9,"t":{"36":{"position":[[20,8]]}}}],["fga",{"_index":29,"t":{"166":{"position":[[8,3]]}}}],["fine",{"_index":4,"t":{"12":{"position":[[0,4]]},"36":{"position":[[0,4]]},"54":{"position":[[0,4]]},"70":{"position":[[0,4]]},"104":{"position":[[0,4]]}}}],["framework",{"_index":35,"t":{"192":{"position":[[19,9]]}}}],["github",{"_index":98,"t":{"985":{"position":[[9,6]]}}}],["googl",{"_index":101,"t":{"1032":{"position":[[9,6]]}}}],["grain",{"_index":5,"t":{"12":{"position":[[5,7]]},"36":{"position":[[5,7]]},"54":{"position":[[5,7]]},"70":{"position":[[5,7]]},"104":{"position":[[5,7]]}}}],["group",{"_index":60,"t":{"453":{"position":[[9,5]]},"718":{"position":[[5,6]]},"760":{"position":[[9,5]]}}}],["immut",{"_index":39,"t":{"220":{"position":[[0,9]]}}}],["instal",{"_index":36,"t":{"206":{"position":[[0,7]]}}}],["integr",{"_index":33,"t":{"192":{"position":[[0,9]]}}}],["introduct",{"_index":27,"t":{"158":{"position":[[0,12]]}}}],["invok",{"_index":54,"t":{"328":{"position":[[38,8]]}}}],["iot",{"_index":94,"t":{"936":{"position":[[30,3]]}}}],["januari",{"_index":12,"t":{"70":{"position":[[20,7]]}}}],["join",{"_index":18,"t":{"131":{"position":[[0,4]]}}}],["kubecon",{"_index":20,"t":{"131":{"position":[[25,7]]}}}],["kubernet",{"_index":50,"t":{"324":{"position":[[22,10]]}}}],["languag",{"_index":57,"t":{"358":{"position":[[14,8]]}}}],["list",{"_index":13,"t":{"96":{"position":[[0,4]]},"244":{"position":[[10,4]]}}}],["listobject",{"_index":88,"t":{"795":{"position":[[47,11]]}}}],["manag",{"_index":53,"t":{"328":{"position":[[18,8]]},"426":{"position":[[0,8]]},"453":{"position":[[0,8]]},"738":{"position":[[0,8]]},"760":{"position":[[0,8]]}}}],["march",{"_index":11,"t":{"54":{"position":[[20,5]]}}}],["membership",{"_index":83,"t":{"760":{"position":[[15,10]]}}}],["migrat",{"_index":89,"t":{"898":{"position":[[0,9]]}}}],["model",{"_index":25,"t":{"148":{"position":[[8,6]]},"220":{"position":[[24,6]]},"316":{"position":[[24,5]]},"593":{"position":[[17,8]]},"631":{"position":[[8,6]]},"676":{"position":[[8,6]]},"936":{"position":[[0,8]]},"964":{"position":[[0,8]]},"985":{"position":[[0,8]]},"1032":{"position":[[0,8]]},"1055":{"position":[[0,8]]}}}],["modular",{"_index":24,"t":{"148":{"position":[[0,7]]},"631":{"position":[[0,7]]}}}],["multipl",{"_index":73,"t":{"613":{"position":[[0,8]]}}}],["na",{"_index":21,"t":{"131":{"position":[[33,2]]}}}],["new",{"_index":6,"t":{"12":{"position":[[13,4]]},"36":{"position":[[13,4]]},"54":{"position":[[13,4]]},"70":{"position":[[13,4]]},"104":{"position":[[13,4]]}}}],["object",{"_index":42,"t":{"244":{"position":[[15,7]]},"654":{"position":[[13,7]]},"738":{"position":[[31,7]]},"833":{"position":[[0,6],[10,6]]}}}],["openfga",{"_index":3,"t":{"2":{"position":[[36,7]]},"118":{"position":[[0,7]]},"131":{"position":[[9,7]]},"158":{"position":[[16,7]]},"256":{"position":[[8,7]]},"264":{"position":[[12,7]]},"300":{"position":[[9,7]]},"324":{"position":[[9,7]]},"326":{"position":[[6,7]]},"336":{"position":[[10,7]]},"936":{"position":[[55,7]]},"964":{"position":[[40,7]]},"985":{"position":[[33,7]]},"1032":{"position":[[39,7]]},"1055":{"position":[[38,7]]}}}],["organ",{"_index":92,"t":{"914":{"position":[[22,12]]}}}],["parent",{"_index":75,"t":{"654":{"position":[[0,6]]}}}],["perform",{"_index":40,"t":{"232":{"position":[[0,7]]},"244":{"position":[[0,7]]}}}],["permiss",{"_index":62,"t":{"470":{"position":[[12,11]]},"860":{"position":[[10,11]]},"985":{"position":[[16,11]]},"1032":{"position":[[22,11]]}}}],["playground",{"_index":55,"t":{"336":{"position":[[18,10]]}}}],["practic",{"_index":52,"t":{"328":{"position":[[5,9]]}}}],["product",{"_index":45,"t":{"256":{"position":[[19,10]]}}}],["public",{"_index":81,"t":{"702":{"position":[[0,6]]}}}],["queri",{"_index":85,"t":{"795":{"position":[[13,8]]}}}],["read",{"_index":86,"t":{"795":{"position":[[29,5]]}}}],["relat",{"_index":90,"t":{"898":{"position":[[10,9]]}}}],["relationship",{"_index":1,"t":{"2":{"position":[[12,12]]},"342":{"position":[[7,12]]},"511":{"position":[[11,13]]},"738":{"position":[[9,13]]},"795":{"position":[[0,12]]},"833":{"position":[[17,13]]},"878":{"position":[[7,13]]}}}],["restrict",{"_index":74,"t":{"613":{"position":[[9,12]]}}}],["role",{"_index":71,"t":{"569":{"position":[[7,5]]},"860":{"position":[[0,5]]}}}],["run",{"_index":44,"t":{"256":{"position":[[0,7]]}}}],["sdk",{"_index":37,"t":{"206":{"position":[[8,3]]},"418":{"position":[[6,3]]}}}],["search",{"_index":61,"t":{"470":{"position":[[0,6]]}}}],["secur",{"_index":95,"t":{"936":{"position":[[34,8]]}}}],["setup",{"_index":48,"t":{"300":{"position":[[3,5]]},"324":{"position":[[3,5]]},"326":{"position":[[0,5]]},"418":{"position":[[0,5]]}}}],["slack",{"_index":103,"t":{"1055":{"position":[[27,5]]}}}],["start",{"_index":72,"t":{"593":{"position":[[4,7]]}}}],["store",{"_index":32,"t":{"188":{"position":[[9,5]]},"316":{"position":[[36,5]]},"418":{"position":[[21,5]]}}}],["system",{"_index":96,"t":{"936":{"position":[[43,6]]},"964":{"position":[[28,6]]}}}],["team",{"_index":19,"t":{"131":{"position":[[17,4]]}}}],["test",{"_index":77,"t":{"676":{"position":[[0,7]]}}}],["through",{"_index":91,"t":{"914":{"position":[[14,7]]}}}],["time",{"_index":99,"t":{"1008":{"position":[[15,4]]}}}],["token",{"_index":78,"t":{"692":{"position":[[4,5]]}}}],["transact",{"_index":65,"t":{"492":{"position":[[0,13]]}}}],["tupl",{"_index":2,"t":{"2":{"position":[[25,6]]},"328":{"position":[[27,6]]},"342":{"position":[[20,6]]},"441":{"position":[[11,5]]},"692":{"position":[[31,6]]}}}],["updat",{"_index":56,"t":{"342":{"position":[[0,6]]}}}],["us",{"_index":28,"t":{"166":{"position":[[0,3]]},"336":{"position":[[0,5]]},"486":{"position":[[9,3]]},"692":{"position":[[0,3]]}}}],["user",{"_index":14,"t":{"96":{"position":[[5,5]]},"426":{"position":[[9,4]]},"718":{"position":[[0,4]]}}}],["userset",{"_index":68,"t":{"542":{"position":[[0,8]]}}}],["within",{"_index":34,"t":{"192":{"position":[[10,6]]}}}],["write",{"_index":66,"t":{"492":{"position":[[14,6]]}}}]],"pipeline":["stemmer"]}},{"documents":[{"i":4,"t":"Use Cases","u":"/pr-preview/pr-728/blog/conditional-tuples-announcement","h":"#use-cases","p":2},{"i":6,"t":"How to use it?","u":"/pr-preview/pr-728/blog/conditional-tuples-announcement","h":"#how-to-use-it","p":2},{"i":8,"t":"What’s Next?","u":"/pr-preview/pr-728/blog/conditional-tuples-announcement","h":"#whats-next","p":2},{"i":10,"t":"Reach out!","u":"/pr-preview/pr-728/blog/conditional-tuples-announcement","h":"#reach-out","p":2},{"i":14,"t":"Team News","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"#team-news","p":12},{"i":16,"t":"Behavior Driven Development with OpenFGA","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"#behavior-driven-development-with-openfga","p":12},{"i":18,"t":"GoDaddy & OpenFGA","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"#godaddy--openfga","p":12},{"i":20,"t":"Canonical & OpenFGA","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"#canonical--openfga","p":12},{"i":22,"t":"OpenFGA v1.4!","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"#openfga-v14","p":12},{"i":24,"t":"SDK Improvements","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"#sdk-improvements","p":12},{"i":26,"t":"Language Improvements","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"#language-improvements","p":12},{"i":28,"t":"VS Code Extension Improvements","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"#vs-code-extension-improvements","p":12},{"i":30,"t":"KubeCon EU 2024","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"#kubecon-eu-2024","p":12},{"i":32,"t":"OpenFGA Community","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"#openfga-community","p":12},{"i":34,"t":"See you next month!","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"#see-you-next-month","p":12},{"i":38,"t":"KubeCon Europe 2024 is getting closer!","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-02","h":"#kubecon-europe-2024-is-getting-closer","p":36},{"i":40,"t":"Documentation Improvements","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-02","h":"#documentation-improvements","p":36},{"i":42,"t":"OpenFGA in the Java Ecosystem","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-02","h":"#openfga-in-the-java-ecosystem","p":36},{"i":44,"t":"SDK Improvements","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-02","h":"#sdk-improvements","p":36},{"i":46,"t":"Modular Models","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-02","h":"#modular-models","p":36},{"i":48,"t":"Community News","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-02","h":"#community-news","p":36},{"i":50,"t":"Transitioning from Discord to CNCF's Slack","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-02","h":"#transitioning-from-discord-to-cncfs-slack","p":36},{"i":52,"t":"See you next month!","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-02","h":"#see-you-next-month","p":36},{"i":56,"t":"KubeCon Europe 2024 was super-busy!","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-03","h":"#kubecon-europe-2024-was-super-busy","p":54},{"i":58,"t":"CNCF incubation","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-03","h":"#cncf-incubation","p":54},{"i":60,"t":"New Adopters","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-03","h":"#new-adopters","p":54},{"i":62,"t":"Community News","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-03","h":"#community-news","p":54},{"i":64,"t":"New Releases","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-03","h":"#new-releases","p":54},{"i":66,"t":"Transitioning from Discord to CNCF's Slack","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-03","h":"#transitioning-from-discord-to-cncfs-slack","p":54},{"i":68,"t":"See you next month!","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-03","h":"#see-you-next-month","p":54},{"i":72,"t":"Team News","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#team-news","p":70},{"i":74,"t":"KubeCon Europe 2024!","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#kubecon-europe-2024","p":70},{"i":76,"t":"OpenFGA ⚡️Enlightning Session!","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#openfga-️enlightning-session","p":70},{"i":78,"t":"Visual Studio Code Integration Enhancements","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#visual-studio-code-integration-enhancements","p":70},{"i":80,"t":"CLI improvements","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#cli-improvements","p":70},{"i":82,"t":"OpenFGA v1.4.3","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#openfga-v143","p":70},{"i":84,"t":"SDK Improvements","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#sdk-improvements","p":70},{"i":86,"t":"Language Improvements","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#language-improvements","p":70},{"i":88,"t":"Github Actions","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#github-actions","p":70},{"i":90,"t":"What's Next? Check our RFCs!","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#whats-next-check-our-rfcs","p":70},{"i":92,"t":"OpenFGA Community","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#openfga-community","p":70},{"i":94,"t":"See you next month!","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#see-you-next-month","p":70},{"i":98,"t":"How to use it?","u":"/pr-preview/pr-728/blog/list-users-announcement","h":"#how-to-use-it","p":96},{"i":100,"t":"What's next?","u":"/pr-preview/pr-728/blog/list-users-announcement","h":"#whats-next","p":96},{"i":102,"t":"We want your feedback!","u":"/pr-preview/pr-728/blog/list-users-announcement","h":"#we-want-your-feedback","p":96},{"i":106,"t":"New Releases!","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-04","h":"#new-releases","p":104},{"i":108,"t":"OpenFGA Hackathon","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-04","h":"#openfga-hackathon","p":104},{"i":110,"t":"OpenFGA Security Assessment","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-04","h":"#openfga-security-assessment","p":104},{"i":112,"t":"What's Next","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-04","h":"#whats-next","p":104},{"i":114,"t":"Transitioning from Discord to CNCF's Slack","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-04","h":"#transitioning-from-discord-to-cncfs-slack","p":104},{"i":116,"t":"See you next month!","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-04","h":"#see-you-next-month","p":104},{"i":119,"t":"Slack (CNCF Community)","u":"/pr-preview/pr-728/docs/community","h":"#slack-cncf-community","p":118},{"i":121,"t":"GitHub Discussions","u":"/pr-preview/pr-728/docs/community","h":"#github-discussions","p":118},{"i":123,"t":"X (formerly Twitter)","u":"/pr-preview/pr-728/docs/community","h":"#x-formerly-twitter","p":118},{"i":125,"t":"YouTube","u":"/pr-preview/pr-728/docs/community","h":"#youtube","p":118},{"i":127,"t":"Mastodon","u":"/pr-preview/pr-728/docs/community","h":"#mastodon","p":118},{"i":129,"t":"Monthly Community Meetings","u":"/pr-preview/pr-728/docs/community","h":"#monthly-community-meetings","p":118},{"i":134,"t":"Authentication and Authorization","u":"/pr-preview/pr-728/docs/authorization-concepts","h":"#authentication-and-authorization","p":133},{"i":136,"t":"What is Fine-Grained Authorization?","u":"/pr-preview/pr-728/docs/authorization-concepts","h":"#what-is-fine-grained-authorization","p":133},{"i":138,"t":"What is Role-Based Access Control?","u":"/pr-preview/pr-728/docs/authorization-concepts","h":"#what-is-role-based-access-control","p":133},{"i":140,"t":"What is Attribute-Based Access Control?","u":"/pr-preview/pr-728/docs/authorization-concepts","h":"#what-is-attribute-based-access-control","p":133},{"i":142,"t":"What is Policy-Based Access Control?","u":"/pr-preview/pr-728/docs/authorization-concepts","h":"#what-is-policy-based-access-control","p":133},{"i":144,"t":"What is Relationship-Based Access Control?","u":"/pr-preview/pr-728/docs/authorization-concepts","h":"#what-is-relationship-based-access-control","p":133},{"i":146,"t":"What is Zanzibar?","u":"/pr-preview/pr-728/docs/authorization-concepts","h":"#what-is-zanzibar","p":133},{"i":150,"t":"How to use it?","u":"/pr-preview/pr-728/blog/modular-models-announcement","h":"#how-to-use-it","p":148},{"i":152,"t":"What's next?","u":"/pr-preview/pr-728/blog/modular-models-announcement","h":"#whats-next","p":148},{"i":154,"t":"Reach out!","u":"/pr-preview/pr-728/blog/modular-models-announcement","h":"#reach-out","p":148},{"i":160,"t":"Benefits","u":"/pr-preview/pr-728/docs/fga","h":"#benefits","p":158},{"i":162,"t":"Features","u":"/pr-preview/pr-728/docs/fga","h":"#features","p":158},{"i":164,"t":"Related Sections","u":"/pr-preview/pr-728/docs/fga","h":"#related-sections","p":158},{"i":168,"t":"Configuration","u":"/pr-preview/pr-728/docs/getting-started/cli","h":"#configuration","p":166},{"i":170,"t":"Basic Operations","u":"/pr-preview/pr-728/docs/getting-started/cli","h":"#basic-operations","p":166},{"i":172,"t":"Work with Authorization Model versions","u":"/pr-preview/pr-728/docs/getting-started/cli","h":"#work-with-authorization-model-versions","p":166},{"i":174,"t":"Import tuples","u":"/pr-preview/pr-728/docs/getting-started/cli","h":"#import-tuples","p":166},{"i":176,"t":"yaml","u":"/pr-preview/pr-728/docs/getting-started/cli","h":"#yaml","p":166},{"i":178,"t":"JSON","u":"/pr-preview/pr-728/docs/getting-started/cli","h":"#json","p":166},{"i":180,"t":"CSV","u":"/pr-preview/pr-728/docs/getting-started/cli","h":"#csv","p":166},{"i":182,"t":"Delete Tuples","u":"/pr-preview/pr-728/docs/getting-started/cli","h":"#delete-tuples","p":166},{"i":184,"t":"Import Stores","u":"/pr-preview/pr-728/docs/getting-started/cli","h":"#import-stores","p":166},{"i":186,"t":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/cli","h":"#related-sections","p":166},{"i":190,"t":"Step By Step","u":"/pr-preview/pr-728/docs/getting-started/create-store","h":"#step-by-step","p":188},{"i":194,"t":"Before You Start","u":"/pr-preview/pr-728/docs/getting-started/framework","h":"#before-you-start","p":192},{"i":196,"t":"Step By Step","u":"/pr-preview/pr-728/docs/getting-started/framework","h":"#step-by-step","p":192},{"i":198,"t":"01. Install And Setup Framework","u":"/pr-preview/pr-728/docs/getting-started/framework","h":"#01-install-and-setup-framework","p":192},{"i":200,"t":"02. Authenticate And Get User ID","u":"/pr-preview/pr-728/docs/getting-started/framework","h":"#02-authenticate-and-get-user-id","p":192},{"i":202,"t":"03. Integrate The OpenFGA Check API Into The Service","u":"/pr-preview/pr-728/docs/getting-started/framework","h":"#03-integrate-the--check-api-into-the-service","p":192},{"i":204,"t":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/framework","h":"#related-sections","p":192},{"i":208,"t":"Brew","u":"/pr-preview/pr-728/docs/getting-started/install-sdk","h":"#brew","p":206},{"i":210,"t":"Linux (deb, rpm and apk) packages","u":"/pr-preview/pr-728/docs/getting-started/install-sdk","h":"#linux-deb-rpm-and-apk-packages","p":206},{"i":212,"t":"Docker","u":"/pr-preview/pr-728/docs/getting-started/install-sdk","h":"#docker","p":206},{"i":214,"t":"Go","u":"/pr-preview/pr-728/docs/getting-started/install-sdk","h":"#go","p":206},{"i":216,"t":"Manually","u":"/pr-preview/pr-728/docs/getting-started/install-sdk","h":"#manually","p":206},{"i":218,"t":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/install-sdk","h":"#related-sections","p":206},{"i":222,"t":"Viewing All the Authorization Models","u":"/pr-preview/pr-728/docs/getting-started/immutable-models","h":"#viewing-all-the-authorization-models","p":220},{"i":224,"t":"How to Target a Particular Model","u":"/pr-preview/pr-728/docs/getting-started/immutable-models","h":"#how-to-target-a-particular-model","p":220},{"i":226,"t":"Benefits of Passing in an Authorization Model ID","u":"/pr-preview/pr-728/docs/getting-started/immutable-models","h":"#benefits-of-passing-in-an-authorization-model-id","p":220},{"i":228,"t":"Potential Use-cases","u":"/pr-preview/pr-728/docs/getting-started/immutable-models","h":"#potential-use-cases","p":220},{"i":230,"t":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/immutable-models","h":"#related-sections","p":220},{"i":234,"t":"Before You Start","u":"/pr-preview/pr-728/docs/getting-started/perform-check","h":"#before-you-start","p":232},{"i":236,"t":"Step By Step","u":"/pr-preview/pr-728/docs/getting-started/perform-check","h":"#step-by-step","p":232},{"i":238,"t":"01. Configure the OpenFGA API Client","u":"/pr-preview/pr-728/docs/getting-started/perform-check","h":"#01-configure-the--api-client","p":232},{"i":240,"t":"02. Calling Check API","u":"/pr-preview/pr-728/docs/getting-started/perform-check","h":"#02-calling-check-api","p":232},{"i":242,"t":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/perform-check","h":"#related-sections","p":232},{"i":246,"t":"Before You Start","u":"/pr-preview/pr-728/docs/getting-started/perform-list-objects","h":"#before-you-start","p":244},{"i":248,"t":"Step By Step","u":"/pr-preview/pr-728/docs/getting-started/perform-list-objects","h":"#step-by-step","p":244},{"i":250,"t":"01. Configure the OpenFGA API Client","u":"/pr-preview/pr-728/docs/getting-started/perform-list-objects","h":"#01-configure-the--api-client","p":244},{"i":252,"t":"02. Calling List Objects API","u":"/pr-preview/pr-728/docs/getting-started/perform-list-objects","h":"#02-calling-list-objects-api","p":244},{"i":254,"t":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/perform-list-objects","h":"#related-sections","p":244},{"i":258,"t":"Database Recommendations","u":"/pr-preview/pr-728/docs/getting-started/running-in-production","h":"#database-recommendations","p":256},{"i":260,"t":"Concurrency Limits","u":"/pr-preview/pr-728/docs/getting-started/running-in-production","h":"#concurrency-limits","p":256},{"i":262,"t":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/running-in-production","h":"#related-sections","p":256},{"i":266,"t":"Using a configuration file","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#using-a-configuration-file","p":264},{"i":268,"t":"Using environment variables","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#using-environment-variables","p":264},{"i":270,"t":"Using command line variables","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#using-command-line-variables","p":264},{"i":272,"t":"Configuring Data Storage","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#configuring-data-storage","p":264},{"i":274,"t":"Postgres","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#postgres","p":264},{"i":276,"t":"MySQL","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#mysql","p":264},{"i":278,"t":"Configuring Authentication","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#configuring-authentication","p":264},{"i":280,"t":"Pre-shared Key Authentication","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#pre-shared-key-authentication","p":264},{"i":282,"t":"OIDC","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#oidc","p":264},{"i":284,"t":"Profiler (pprof)","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#profiler-pprof","p":264},{"i":286,"t":"Health Check","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#health-check","p":264},{"i":288,"t":"Experimental Features","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#experimental-features","p":264},{"i":290,"t":"Telemetry","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#telemetry","p":264},{"i":292,"t":"Metrics","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#metrics","p":264},{"i":294,"t":"Tracing","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#tracing","p":264},{"i":296,"t":"Logging","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#logging","p":264},{"i":298,"t":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#related-sections","p":264},{"i":302,"t":"Step By Step","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/docker","h":"#step-by-step","p":300},{"i":304,"t":"Using Postgres","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/docker","h":"#using-postgres","p":300},{"i":306,"t":"Using MySQL","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/docker","h":"#using-mysql","p":300},{"i":308,"t":"Pre-shared Key Authentication","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/docker","h":"#pre-shared-key-authentication","p":300},{"i":310,"t":"OIDC Authentication","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/docker","h":"#oidc-authentication","p":300},{"i":312,"t":"Enabling Profiling","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/docker","h":"#enabling-profiling","p":300},{"i":314,"t":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/docker","h":"#related-sections","p":300},{"i":318,"t":"Before You Start","u":"/pr-preview/pr-728/docs/getting-started/configure-model","h":"#before-you-start","p":316},{"i":320,"t":"Step By Step","u":"/pr-preview/pr-728/docs/getting-started/configure-model","h":"#step-by-step","p":316},{"i":322,"t":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/configure-model","h":"#related-sections","p":316},{"i":330,"t":"Do Not Store Personal Identifiable Information in Tuples","u":"/pr-preview/pr-728/docs/getting-started/tuples-api-best-practices","h":"#do-not-store-personal-identifiable-information-in-tuples","p":328},{"i":332,"t":"Always Specify Authorization Model ID Whenever Possible","u":"/pr-preview/pr-728/docs/getting-started/tuples-api-best-practices","h":"#always-specify-authorization-model-id-whenever-possible","p":328},{"i":334,"t":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/tuples-api-best-practices","h":"#related-sections","p":328},{"i":338,"t":"Running the Playground in a different port","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/playground","h":"#running-the-playground-in-a-different-port","p":336},{"i":340,"t":"Disabling the Playground","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/playground","h":"#disabling-the-playground","p":336},{"i":344,"t":"Before You Start","u":"/pr-preview/pr-728/docs/getting-started/update-tuples","h":"#before-you-start","p":342},{"i":346,"t":"Step By Step","u":"/pr-preview/pr-728/docs/getting-started/update-tuples","h":"#step-by-step","p":342},{"i":348,"t":"01. Configure The OpenFGA API Client","u":"/pr-preview/pr-728/docs/getting-started/update-tuples","h":"#01-configure-the--api-client","p":342},{"i":350,"t":"02. Calling Write API To Add New Relationship Tuples","u":"/pr-preview/pr-728/docs/getting-started/update-tuples","h":"#02-calling-write-api-to-add-new-relationship-tuples","p":342},{"i":352,"t":"03. Calling Write API To Delete Relationship Tuples","u":"/pr-preview/pr-728/docs/getting-started/update-tuples","h":"#03-calling-write-api-to-delete-relationship-tuples","p":342},{"i":354,"t":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/update-tuples","h":"#related-sections","p":342},{"i":360,"t":"What Does The Configuration Language Look Like?","u":"/pr-preview/pr-728/docs/configuration-language","h":"#what-does-the-configuration-language-look-like","p":358},{"i":362,"t":"Direct Relationship Type Restrictions","u":"/pr-preview/pr-728/docs/configuration-language","h":"#direct-relationship-type-restrictions","p":358},{"i":364,"t":"Referencing Other Relations On The Same Object","u":"/pr-preview/pr-728/docs/configuration-language","h":"#referencing-other-relations-on-the-same-object","p":358},{"i":366,"t":"Referencing Relations On Related Objects","u":"/pr-preview/pr-728/docs/configuration-language","h":"#referencing-relations-on-related-objects","p":358},{"i":368,"t":"The Union Operator","u":"/pr-preview/pr-728/docs/configuration-language","h":"#the-union-operator","p":358},{"i":370,"t":"The Intersection Operator","u":"/pr-preview/pr-728/docs/configuration-language","h":"#the-intersection-operator","p":358},{"i":372,"t":"The Exclusion Operator","u":"/pr-preview/pr-728/docs/configuration-language","h":"#the-exclusion-operator","p":358},{"i":374,"t":"Equivalent Zanzibar Concepts","u":"/pr-preview/pr-728/docs/configuration-language","h":"#equivalent-zanzibar-concepts","p":358},{"i":376,"t":"Related Sections","u":"/pr-preview/pr-728/docs/configuration-language","h":"#related-sections","p":358},{"i":380,"t":"What Is A Type?","u":"/pr-preview/pr-728/docs/concepts","h":"#what-is-a-type","p":378},{"i":382,"t":"What Is A Type Definition?","u":"/pr-preview/pr-728/docs/concepts","h":"#what-is-a-type-definition","p":378},{"i":384,"t":"What Is An Authorization Model?","u":"/pr-preview/pr-728/docs/concepts","h":"#what-is-an-authorization-model","p":378},{"i":386,"t":"What Is A Store?","u":"/pr-preview/pr-728/docs/concepts","h":"#what-is-a-store","p":378},{"i":388,"t":"What Is An Object?","u":"/pr-preview/pr-728/docs/concepts","h":"#what-is-an-object","p":378},{"i":390,"t":"What Is A User?","u":"/pr-preview/pr-728/docs/concepts","h":"#what-is-a-user","p":378},{"i":392,"t":"What Is A Relation?","u":"/pr-preview/pr-728/docs/concepts","h":"#what-is-a-relation","p":378},{"i":394,"t":"What Is A Relation Definition?","u":"/pr-preview/pr-728/docs/concepts","h":"#what-is-a-relation-definition","p":378},{"i":396,"t":"What Is A Directly Related User Type?","u":"/pr-preview/pr-728/docs/concepts","h":"#what-is-a-directly-related-user-type","p":378},{"i":398,"t":"What is a Condition?","u":"/pr-preview/pr-728/docs/concepts","h":"#what-is-a-condition","p":378},{"i":400,"t":"What Is A Relationship Tuple?","u":"/pr-preview/pr-728/docs/concepts","h":"#what-is-a-relationship-tuple","p":378},{"i":402,"t":"What Is A Conditional Relationship Tuple?","u":"/pr-preview/pr-728/docs/concepts","h":"#what-is-a-conditional-relationship-tuple","p":378},{"i":404,"t":"What Is A Relationship?","u":"/pr-preview/pr-728/docs/concepts","h":"#what-is-a-relationship","p":378},{"i":406,"t":"What Are Direct And Implied Relationships?","u":"/pr-preview/pr-728/docs/concepts","h":"#what-are-direct-and-implied-relationships","p":378},{"i":408,"t":"What Is A Check Request?","u":"/pr-preview/pr-728/docs/concepts","h":"#what-is-a-check-request","p":378},{"i":410,"t":"What Is A List Objects Request?","u":"/pr-preview/pr-728/docs/concepts","h":"#what-is-a-list-objects-request","p":378},{"i":412,"t":"What Are Contextual Tuples?","u":"/pr-preview/pr-728/docs/concepts","h":"#what-are-contextual-tuples","p":378},{"i":414,"t":"What Is Type Bound Public Access?","u":"/pr-preview/pr-728/docs/concepts","h":"#what-is-type-bound-public-access","p":378},{"i":416,"t":"Related Sections","u":"/pr-preview/pr-728/docs/concepts","h":"#related-sections","p":378},{"i":420,"t":"Using No Authentication","u":"/pr-preview/pr-728/docs/getting-started/setup-sdk-client","h":"#using-no-authentication","p":418},{"i":422,"t":"Using Shared Key Authentication","u":"/pr-preview/pr-728/docs/getting-started/setup-sdk-client","h":"#using-shared-key-authentication","p":418},{"i":424,"t":"Using Client Credentials Flow","u":"/pr-preview/pr-728/docs/getting-started/setup-sdk-client","h":"#using-client-credentials-flow","p":418},{"i":428,"t":"Before You Start","u":"/pr-preview/pr-728/docs/interacting/managing-user-access","h":"#before-you-start","p":426},{"i":430,"t":"Direct Access","u":"/pr-preview/pr-728/docs/interacting/managing-user-access","h":"#direct-access","p":426},{"i":432,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/interacting/managing-user-access","h":"#-concepts","p":426},{"i":434,"t":"Step By Step","u":"/pr-preview/pr-728/docs/interacting/managing-user-access","h":"#step-by-step","p":426},{"i":435,"t":"01. Adding Direct Relationship","u":"/pr-preview/pr-728/docs/interacting/managing-user-access","h":"#01-adding-direct-relationship","p":426},{"i":437,"t":"02. Removing Direct Relationship","u":"/pr-preview/pr-728/docs/interacting/managing-user-access","h":"#02-removing-direct-relationship","p":426},{"i":439,"t":"Related Sections","u":"/pr-preview/pr-728/docs/interacting/managing-user-access","h":"#related-sections","p":426},{"i":443,"t":"Before you start","u":"/pr-preview/pr-728/docs/interacting/read-tuple-changes","h":"#before-you-start","p":441},{"i":445,"t":"Step By Step","u":"/pr-preview/pr-728/docs/interacting/read-tuple-changes","h":"#step-by-step","p":441},{"i":447,"t":"01. Configure The OpenFGA API Client","u":"/pr-preview/pr-728/docs/interacting/read-tuple-changes","h":"#01-configure-the--api-client","p":441},{"i":449,"t":"02. Get Changes For All Object Types","u":"/pr-preview/pr-728/docs/interacting/read-tuple-changes","h":"#02-get-changes-for-all-object-types","p":441},{"i":451,"t":"03. Get Changes For A Specific Object Type","u":"/pr-preview/pr-728/docs/interacting/read-tuple-changes","h":"#03-get-changes-for-a-specific-object-type","p":441},{"i":455,"t":"Before You Start","u":"/pr-preview/pr-728/docs/interacting/managing-group-access","h":"#before-you-start","p":453},{"i":457,"t":"Modeling User Groups","u":"/pr-preview/pr-728/docs/interacting/managing-group-access","h":"#modeling-user-groups","p":453},{"i":459,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/interacting/managing-group-access","h":"#-concepts","p":453},{"i":461,"t":"Step By Step","u":"/pr-preview/pr-728/docs/interacting/managing-group-access","h":"#step-by-step","p":453},{"i":462,"t":"01. Adding Company To The Document","u":"/pr-preview/pr-728/docs/interacting/managing-group-access","h":"#01-adding-company-to-the-document","p":453},{"i":464,"t":"02. Adding Employee To The Company","u":"/pr-preview/pr-728/docs/interacting/managing-group-access","h":"#02-adding-employee-to-the-company","p":453},{"i":466,"t":"03. Checking An Individual Member's Access To An Object","u":"/pr-preview/pr-728/docs/interacting/managing-group-access","h":"#03-checking-an-individual-members-access-to-an-object","p":453},{"i":468,"t":"Related Sections","u":"/pr-preview/pr-728/docs/interacting/managing-group-access","h":"#related-sections","p":453},{"i":472,"t":"Possible Options","u":"/pr-preview/pr-728/docs/interacting/search-with-permissions","h":"#possible-options","p":470},{"i":474,"t":"Option 1: Search, Then Check","u":"/pr-preview/pr-728/docs/interacting/search-with-permissions","h":"#option-1-search-then-check","p":470},{"i":476,"t":"Option 2: Build A Local Index From Changes Endpoint, Search, Then Check","u":"/pr-preview/pr-728/docs/interacting/search-with-permissions","h":"#option-2-build-a-local-index-from-changes-endpoint-search-then-check","p":470},{"i":478,"t":"Option 3: Build A List Of IDs, Then Search","u":"/pr-preview/pr-728/docs/interacting/search-with-permissions","h":"#option-3-build-a-list-of-ids-then-search","p":470},{"i":480,"t":"Choosing The Best Option","u":"/pr-preview/pr-728/docs/interacting/search-with-permissions","h":"#choosing-the-best-option","p":470},{"i":482,"t":"Summary","u":"/pr-preview/pr-728/docs/interacting/search-with-permissions","h":"#summary","p":470},{"i":488,"t":"Use-cases","u":"/pr-preview/pr-728/docs/modeling/advanced","h":"#use-cases","p":486},{"i":490,"t":"Patterns","u":"/pr-preview/pr-728/docs/modeling/advanced","h":"#patterns","p":486},{"i":494,"t":"Before You Start","u":"/pr-preview/pr-728/docs/interacting/transactional-writes","h":"#before-you-start","p":492},{"i":496,"t":"Direct Access","u":"/pr-preview/pr-728/docs/interacting/transactional-writes","h":"#direct-access","p":492},{"i":498,"t":"Modeling Public Access","u":"/pr-preview/pr-728/docs/interacting/transactional-writes","h":"#modeling-public-access","p":492},{"i":500,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/interacting/transactional-writes","h":"#-concepts","p":492},{"i":502,"t":"Step By Step","u":"/pr-preview/pr-728/docs/interacting/transactional-writes","h":"#step-by-step","p":492},{"i":503,"t":"01. Adding And Removing Relationship Tuples In The Same Transaction","u":"/pr-preview/pr-728/docs/interacting/transactional-writes","h":"#01-adding-and-removing-relationship-tuples-in-the-same-transaction","p":492},{"i":505,"t":"02. Adding Multiple Related Relationship Tuples In The Same Transaction","u":"/pr-preview/pr-728/docs/interacting/transactional-writes","h":"#02-adding-multiple-related-relationship-tuples-in-the-same-transaction","p":492},{"i":507,"t":"Related Sections","u":"/pr-preview/pr-728/docs/interacting/transactional-writes","h":"#related-sections","p":492},{"i":513,"t":"Before You Start","u":"/pr-preview/pr-728/docs/modeling/building-blocks/concentric-relationships","h":"#before-you-start","p":511},{"i":515,"t":"Modeling User Groups","u":"/pr-preview/pr-728/docs/modeling/building-blocks/concentric-relationships","h":"#modeling-user-groups","p":511},{"i":517,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/modeling/building-blocks/concentric-relationships","h":"#-concepts","p":511},{"i":519,"t":"Step By Step","u":"/pr-preview/pr-728/docs/modeling/building-blocks/concentric-relationships","h":"#step-by-step","p":511},{"i":521,"t":"01. Modify Our Model To Imply Editor As Viewer","u":"/pr-preview/pr-728/docs/modeling/building-blocks/concentric-relationships","h":"#01-modify-our-model-to-imply-editor-as-viewer","p":511},{"i":523,"t":"02. Check That Editors Are Viewers","u":"/pr-preview/pr-728/docs/modeling/building-blocks/concentric-relationships","h":"#02-check-that-editors-are-viewers","p":511},{"i":525,"t":"Related Sections","u":"/pr-preview/pr-728/docs/modeling/building-blocks/concentric-relationships","h":"#related-sections","p":511},{"i":528,"t":"Overview","u":"/pr-preview/pr-728/docs/modeling/conditions","h":"#overview","p":527},{"i":530,"t":"Defining Conditions in Models","u":"/pr-preview/pr-728/docs/modeling/conditions","h":"#defining-conditions-in-models","p":527},{"i":532,"t":"Writing Conditional Relationship Tuples","u":"/pr-preview/pr-728/docs/modeling/conditions","h":"#writing-conditional-relationship-tuples","p":527},{"i":534,"t":"Queries with Condition Context","u":"/pr-preview/pr-728/docs/modeling/conditions","h":"#queries-with-condition-context","p":527},{"i":536,"t":"Examples","u":"/pr-preview/pr-728/docs/modeling/conditions","h":"#examples","p":527},{"i":538,"t":"Supported Parameter Types","u":"/pr-preview/pr-728/docs/modeling/conditions","h":"#supported-parameter-types","p":527},{"i":540,"t":"Limitations","u":"/pr-preview/pr-728/docs/modeling/conditions","h":"#limitations","p":527},{"i":543,"t":"What Is A Userset?","u":"/pr-preview/pr-728/docs/modeling/building-blocks/usersets","h":"#what-is-a-userset","p":542},{"i":545,"t":"How Do Check Requests Work With Usersets?","u":"/pr-preview/pr-728/docs/modeling/building-blocks/usersets","h":"#how-do-check-requests-work-with-usersets","p":542},{"i":547,"t":"How Do Expand Requests Work With Usersets?","u":"/pr-preview/pr-728/docs/modeling/building-blocks/usersets","h":"#how-do-expand-requests-work-with-usersets","p":542},{"i":549,"t":"Internals","u":"/pr-preview/pr-728/docs/modeling/building-blocks/usersets","h":"#internals","p":542},{"i":551,"t":"Related Sections","u":"/pr-preview/pr-728/docs/modeling/building-blocks/usersets","h":"#related-sections","p":542},{"i":555,"t":"Before you start","u":"/pr-preview/pr-728/docs/modeling/direct-access","h":"#before-you-start","p":553},{"i":557,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/modeling/direct-access","h":"#-concepts","p":553},{"i":559,"t":"Step By Step","u":"/pr-preview/pr-728/docs/modeling/direct-access","h":"#step-by-step","p":553},{"i":561,"t":"01. Create A Relationship Tuple","u":"/pr-preview/pr-728/docs/modeling/direct-access","h":"#01-create-a-relationship-tuple","p":553},{"i":563,"t":"02. Check That The Relationship Exists","u":"/pr-preview/pr-728/docs/modeling/direct-access","h":"#02-check-that-the-relationship-exists","p":553},{"i":565,"t":"Related Sections","u":"/pr-preview/pr-728/docs/modeling/direct-access","h":"#related-sections","p":553},{"i":571,"t":"Before you start","u":"/pr-preview/pr-728/docs/modeling/custom-roles","h":"#before-you-start","p":569},{"i":573,"t":"Initial Model","u":"/pr-preview/pr-728/docs/modeling/custom-roles","h":"#initial-model","p":569},{"i":575,"t":"Modeling Roles and Permissions","u":"/pr-preview/pr-728/docs/modeling/custom-roles","h":"#modeling-roles-and-permissions","p":569},{"i":577,"t":"Modeling Object-to-Object Relationships","u":"/pr-preview/pr-728/docs/modeling/custom-roles","h":"#modeling-object-to-object-relationships","p":569},{"i":579,"t":"Concepts & Configuration Language","u":"/pr-preview/pr-728/docs/modeling/custom-roles","h":"#concepts--configuration-language","p":569},{"i":581,"t":"Step By Step","u":"/pr-preview/pr-728/docs/modeling/custom-roles","h":"#step-by-step","p":569},{"i":583,"t":"01. Update The Authorization Model To Add A Role Type","u":"/pr-preview/pr-728/docs/modeling/custom-roles","h":"#01-update-the-authorization-model-to-add-a-role-type","p":569},{"i":585,"t":"02.Use Relationship Tuples To Tie The Users To The Roles","u":"/pr-preview/pr-728/docs/modeling/custom-roles","h":"#02use-relationship-tuples-to-tie-the-users-to-the-roles","p":569},{"i":587,"t":"03. Use Relationship Tuples To Associate Permissions With The Roles","u":"/pr-preview/pr-728/docs/modeling/custom-roles","h":"#03-use-relationship-tuples-to-associate-permissions-with-the-roles","p":569},{"i":589,"t":"04. Verify That The Authorization Model Works","u":"/pr-preview/pr-728/docs/modeling/custom-roles","h":"#04-verify-that-the-authorization-model-works","p":569},{"i":591,"t":"Related Sections","u":"/pr-preview/pr-728/docs/modeling/custom-roles","h":"#related-sections","p":569},{"i":595,"t":"Introduction To Modeling","u":"/pr-preview/pr-728/docs/modeling/getting-started","h":"#introduction-to-modeling","p":593},{"i":597,"t":"A Process For Defining Authorization Models","u":"/pr-preview/pr-728/docs/modeling/getting-started","h":"#a-process-for-defining-authorization-models","p":593},{"i":599,"t":"01. Pick The Most Important Feature","u":"/pr-preview/pr-728/docs/modeling/getting-started","h":"#01-pick-the-most-important-feature","p":593},{"i":601,"t":"02. List The Object Types","u":"/pr-preview/pr-728/docs/modeling/getting-started","h":"#02-list-the-object-types","p":593},{"i":603,"t":"03. List Relations For Those Types","u":"/pr-preview/pr-728/docs/modeling/getting-started","h":"#03-list-relations-for-those-types","p":593},{"i":605,"t":"04. Define Relations","u":"/pr-preview/pr-728/docs/modeling/getting-started","h":"#04-define-relations","p":593},{"i":607,"t":"05. Test The Model","u":"/pr-preview/pr-728/docs/modeling/getting-started","h":"#05-test-the-model","p":593},{"i":609,"t":"06. Iterate","u":"/pr-preview/pr-728/docs/modeling/getting-started","h":"#06-iterate","p":593},{"i":611,"t":"Related Sections","u":"/pr-preview/pr-728/docs/modeling/getting-started","h":"#related-sections","p":593},{"i":615,"t":"Before You Start","u":"/pr-preview/pr-728/docs/modeling/multiple-restrictions","h":"#before-you-start","p":613},{"i":617,"t":"Modeling Parent-Child Objects","u":"/pr-preview/pr-728/docs/modeling/multiple-restrictions","h":"#modeling-parent-child-objects","p":613},{"i":619,"t":"Modeling Roles And Permissions","u":"/pr-preview/pr-728/docs/modeling/multiple-restrictions","h":"#modeling-roles-and-permissions","p":613},{"i":621,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/modeling/multiple-restrictions","h":"#-concepts","p":613},{"i":623,"t":"Step By Step","u":"/pr-preview/pr-728/docs/modeling/multiple-restrictions","h":"#step-by-step","p":613},{"i":625,"t":"01. Add can_delete Relation To Only Allow Writers That Are Members Of The Ownership Organization","u":"/pr-preview/pr-728/docs/modeling/multiple-restrictions","h":"#01-add-can_delete-relation-to-only-allow-writers-that-are-members-of-the-ownership-organization","p":613},{"i":627,"t":"02. Verify That Our Solutions Work","u":"/pr-preview/pr-728/docs/modeling/multiple-restrictions","h":"#02-verify-that-our-solutions-work","p":613},{"i":629,"t":"Related Sections","u":"/pr-preview/pr-728/docs/modeling/multiple-restrictions","h":"#related-sections","p":613},{"i":633,"t":"Key Concepts","u":"/pr-preview/pr-728/docs/modeling/modular-models","h":"#key-concepts","p":631},{"i":634,"t":"fga.mod","u":"/pr-preview/pr-728/docs/modeling/modular-models","h":"#fgamod","p":631},{"i":636,"t":"Modules","u":"/pr-preview/pr-728/docs/modeling/modular-models","h":"#modules","p":631},{"i":638,"t":"Type Extensions","u":"/pr-preview/pr-728/docs/modeling/modular-models","h":"#type-extensions","p":631},{"i":640,"t":"Example","u":"/pr-preview/pr-728/docs/modeling/modular-models","h":"#example","p":631},{"i":642,"t":"Core","u":"/pr-preview/pr-728/docs/modeling/modular-models","h":"#core","p":631},{"i":644,"t":"Issue tracking","u":"/pr-preview/pr-728/docs/modeling/modular-models","h":"#issue-tracking","p":631},{"i":646,"t":"Wiki","u":"/pr-preview/pr-728/docs/modeling/modular-models","h":"#wiki","p":631},{"i":648,"t":"fga.mod","u":"/pr-preview/pr-728/docs/modeling/modular-models","h":"#fgamod-1","p":631},{"i":650,"t":"Putting it all together","u":"/pr-preview/pr-728/docs/modeling/modular-models","h":"#putting-it-all-together","p":631},{"i":652,"t":"Viewing the model","u":"/pr-preview/pr-728/docs/modeling/modular-models","h":"#viewing-the-model","p":631},{"i":656,"t":"Before You Start","u":"/pr-preview/pr-728/docs/modeling/parent-child","h":"#before-you-start","p":654},{"i":658,"t":"Direct Access","u":"/pr-preview/pr-728/docs/modeling/parent-child","h":"#direct-access","p":654},{"i":660,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/modeling/parent-child","h":"#-concepts","p":654},{"i":662,"t":"Step By Step","u":"/pr-preview/pr-728/docs/modeling/parent-child","h":"#step-by-step","p":654},{"i":664,"t":"01. Update The Authorization Model To Allow A Parent Relationship Between Folder And Document","u":"/pr-preview/pr-728/docs/modeling/parent-child","h":"#01-update-the-authorization-model-to-allow-a-parent-relationship-between-folder-and-document","p":654},{"i":666,"t":"02. Update The Editor Relation In The Document Type Definition To Support Cascading From Folder","u":"/pr-preview/pr-728/docs/modeling/parent-child","h":"#02-update-the-editor-relation-in-the-document-type-definition-to-support-cascading-from-folder","p":654},{"i":668,"t":"03. Create A New Relationship Tuple To Indicate That bob Is An Editor Of folder:notes","u":"/pr-preview/pr-728/docs/modeling/parent-child","h":"#03-create-a-new-relationship-tuple-to-indicate-that-bob-is-an-editor-of-folder","p":654},{"i":670,"t":"04. Create A New Relationship Tuple To Indicate That folder:notes Is A Parent Of document:meeting_notes.doc","u":"/pr-preview/pr-728/docs/modeling/parent-child","h":"#04-create-a-new-relationship-tuple-to-indicate-that-folder-is-a-parent-of-documentdoc","p":654},{"i":672,"t":"05. Check To See If bob Is An Editor Of document:meeting_notes.doc","u":"/pr-preview/pr-728/docs/modeling/parent-child","h":"#05-check-to-see-if-bob-is-an-editor-of-documentdoc","p":654},{"i":674,"t":"Related Sections","u":"/pr-preview/pr-728/docs/modeling/parent-child","h":"#related-sections","p":654},{"i":678,"t":"Define the model and tuples","u":"/pr-preview/pr-728/docs/modeling/testing","h":"#define-the-model-and-tuples","p":676},{"i":680,"t":"Write tests","u":"/pr-preview/pr-728/docs/modeling/testing","h":"#write-tests","p":676},{"i":682,"t":"Write Check tests","u":"/pr-preview/pr-728/docs/modeling/testing","h":"#write-check-tests","p":676},{"i":684,"t":"Write List Objects tests","u":"/pr-preview/pr-728/docs/modeling/testing","h":"#write-list-objects-tests","p":676},{"i":686,"t":"Running tests","u":"/pr-preview/pr-728/docs/modeling/testing","h":"#running-tests","p":676},{"i":688,"t":"Running tests using GitHub Actions","u":"/pr-preview/pr-728/docs/modeling/testing","h":"#running-tests-using-github-actions","p":676},{"i":690,"t":"Related Sections","u":"/pr-preview/pr-728/docs/modeling/testing","h":"#related-sections","p":676},{"i":694,"t":"Before You Start","u":"/pr-preview/pr-728/docs/modeling/token-claims-contextual-tuples","h":"#before-you-start","p":692},{"i":696,"t":"User Directories, Identity Tokens, And Relationships","u":"/pr-preview/pr-728/docs/modeling/token-claims-contextual-tuples","h":"#user-directories-identity-tokens-and-relationships","p":692},{"i":698,"t":"Example","u":"/pr-preview/pr-728/docs/modeling/token-claims-contextual-tuples","h":"#example","p":692},{"i":700,"t":"Related Sections","u":"/pr-preview/pr-728/docs/modeling/token-claims-contextual-tuples","h":"#related-sections","p":692},{"i":704,"t":"Before You Start","u":"/pr-preview/pr-728/docs/modeling/public-access","h":"#before-you-start","p":702},{"i":706,"t":"Direct Access","u":"/pr-preview/pr-728/docs/modeling/public-access","h":"#direct-access","p":702},{"i":708,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/modeling/public-access","h":"#-concepts","p":702},{"i":710,"t":"Step By Step","u":"/pr-preview/pr-728/docs/modeling/public-access","h":"#step-by-step","p":702},{"i":712,"t":"01. Create A Relationship Tuple","u":"/pr-preview/pr-728/docs/modeling/public-access","h":"#01-create-a-relationship-tuple","p":702},{"i":714,"t":"02. Check That The Relationship Exists","u":"/pr-preview/pr-728/docs/modeling/public-access","h":"#02-check-that-the-relationship-exists","p":702},{"i":716,"t":"Related Sections","u":"/pr-preview/pr-728/docs/modeling/public-access","h":"#related-sections","p":702},{"i":720,"t":"Before you start","u":"/pr-preview/pr-728/docs/modeling/user-groups","h":"#before-you-start","p":718},{"i":722,"t":"Direct Access","u":"/pr-preview/pr-728/docs/modeling/user-groups","h":"#direct-access","p":718},{"i":724,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/modeling/user-groups","h":"#-concepts","p":718},{"i":726,"t":"Step By Step","u":"/pr-preview/pr-728/docs/modeling/user-groups","h":"#step-by-step","p":718},{"i":728,"t":"01. Introduce The Concept Of A Team To The Authorization Model","u":"/pr-preview/pr-728/docs/modeling/user-groups","h":"#01-introduce-the-concept-of-a-team-to-the-authorization-model","p":718},{"i":730,"t":"02. Add Users As Members To The Team","u":"/pr-preview/pr-728/docs/modeling/user-groups","h":"#02-add-users-as-members-to-the-team","p":718},{"i":732,"t":"03. Assign The Team Members A Relation To An Object","u":"/pr-preview/pr-728/docs/modeling/user-groups","h":"#03-assign-the-team-members-a-relation-to-an-object","p":718},{"i":734,"t":"04. Checking An Individual Member's Access To An Object","u":"/pr-preview/pr-728/docs/modeling/user-groups","h":"#04-checking-an-individual-members-access-to-an-object","p":718},{"i":736,"t":"Related Sections","u":"/pr-preview/pr-728/docs/modeling/user-groups","h":"#related-sections","p":718},{"i":740,"t":"Before you start","u":"/pr-preview/pr-728/docs/interacting/managing-relationships-between-objects","h":"#before-you-start","p":738},{"i":742,"t":"Direct Access","u":"/pr-preview/pr-728/docs/interacting/managing-relationships-between-objects","h":"#direct-access","p":738},{"i":744,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/interacting/managing-relationships-between-objects","h":"#-concepts","p":738},{"i":746,"t":"Step By Step","u":"/pr-preview/pr-728/docs/interacting/managing-relationships-between-objects","h":"#step-by-step","p":738},{"i":748,"t":"01. Modify Authorization Model","u":"/pr-preview/pr-728/docs/interacting/managing-relationships-between-objects","h":"#01-modify-authorization-model","p":738},{"i":750,"t":"02. Adding Relationship Tuples Where User Is Another Object","u":"/pr-preview/pr-728/docs/interacting/managing-relationships-between-objects","h":"#02-adding-relationship-tuples-where-user-is-another-object","p":738},{"i":752,"t":"03. Adding Relationship Tuples To The Other Object","u":"/pr-preview/pr-728/docs/interacting/managing-relationships-between-objects","h":"#03-adding-relationship-tuples-to-the-other-object","p":738},{"i":754,"t":"04. Validating User Access","u":"/pr-preview/pr-728/docs/interacting/managing-relationships-between-objects","h":"#04-validating-user-access","p":738},{"i":756,"t":"05. Revoking Access","u":"/pr-preview/pr-728/docs/interacting/managing-relationships-between-objects","h":"#05-revoking-access","p":738},{"i":758,"t":"Related Sections","u":"/pr-preview/pr-728/docs/interacting/managing-relationships-between-objects","h":"#related-sections","p":738},{"i":762,"t":"Before You Start","u":"/pr-preview/pr-728/docs/interacting/managing-group-membership","h":"#before-you-start","p":760},{"i":764,"t":"Modeling User Groups","u":"/pr-preview/pr-728/docs/interacting/managing-group-membership","h":"#modeling-user-groups","p":760},{"i":766,"t":"Managing Group Access","u":"/pr-preview/pr-728/docs/interacting/managing-group-membership","h":"#managing-group-access","p":760},{"i":768,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/interacting/managing-group-membership","h":"#-concepts","p":760},{"i":770,"t":"Step By Step","u":"/pr-preview/pr-728/docs/interacting/managing-group-membership","h":"#step-by-step","p":760},{"i":771,"t":"01. Revoking Group Membership","u":"/pr-preview/pr-728/docs/interacting/managing-group-membership","h":"#01-revoking-group-membership","p":760},{"i":773,"t":"02. Validating revoked member no longer has access","u":"/pr-preview/pr-728/docs/interacting/managing-group-membership","h":"#02-validating-revoked-member-no-longer-has-access","p":760},{"i":775,"t":"Related Sections","u":"/pr-preview/pr-728/docs/interacting/managing-group-membership","h":"#related-sections","p":760},{"i":779,"t":"Before You Start","u":"/pr-preview/pr-728/docs/modeling/blocklists","h":"#before-you-start","p":777},{"i":781,"t":"Modeling User Groups","u":"/pr-preview/pr-728/docs/modeling/blocklists","h":"#modeling-user-groups","p":777},{"i":783,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/modeling/blocklists","h":"#-concepts","p":777},{"i":785,"t":"Step By Step","u":"/pr-preview/pr-728/docs/modeling/blocklists","h":"#step-by-step","p":777},{"i":787,"t":"01. Modify Our Model So Users Can Be Blocked From Accessing A Document","u":"/pr-preview/pr-728/docs/modeling/blocklists","h":"#01-modify-our-model-so-users-can-be-blocked-from-accessing-a-document","p":777},{"i":789,"t":"02. Modify Our Model So Users Who Are Blocked Can No Longer Edit The Document","u":"/pr-preview/pr-728/docs/modeling/blocklists","h":"#02-modify-our-model-so-users-who-are-blocked-can-no-longer-edit-the-document","p":777},{"i":791,"t":"03. Verify Our Solution Works","u":"/pr-preview/pr-728/docs/modeling/blocklists","h":"#03-verify-our-solution-works","p":777},{"i":793,"t":"Related Sections","u":"/pr-preview/pr-728/docs/modeling/blocklists","h":"#related-sections","p":777},{"i":797,"t":"Before You Start","u":"/pr-preview/pr-728/docs/interacting/relationship-queries","h":"#before-you-start","p":795},{"i":799,"t":"Direct Access","u":"/pr-preview/pr-728/docs/interacting/relationship-queries","h":"#direct-access","p":795},{"i":801,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/interacting/relationship-queries","h":"#-concepts","p":795},{"i":803,"t":"Check","u":"/pr-preview/pr-728/docs/interacting/relationship-queries","h":"#check","p":795},{"i":804,"t":"What Is It For?","u":"/pr-preview/pr-728/docs/interacting/relationship-queries","h":"#what-is-it-for","p":795},{"i":806,"t":"When To Use?","u":"/pr-preview/pr-728/docs/interacting/relationship-queries","h":"#when-to-use","p":795},{"i":808,"t":"Caveats And When Not To Use It","u":"/pr-preview/pr-728/docs/interacting/relationship-queries","h":"#caveats-and-when-not-to-use-it","p":795},{"i":810,"t":"Read","u":"/pr-preview/pr-728/docs/interacting/relationship-queries","h":"#read","p":795},{"i":811,"t":"What Is It For?","u":"/pr-preview/pr-728/docs/interacting/relationship-queries","h":"#what-is-it-for-1","p":795},{"i":813,"t":"When To Use?","u":"/pr-preview/pr-728/docs/interacting/relationship-queries","h":"#when-to-use-1","p":795},{"i":815,"t":"Caveats And When Not To Use It","u":"/pr-preview/pr-728/docs/interacting/relationship-queries","h":"#caveats-and-when-not-to-use-it-1","p":795},{"i":817,"t":"Expand","u":"/pr-preview/pr-728/docs/interacting/relationship-queries","h":"#expand","p":795},{"i":818,"t":"What Is It For?","u":"/pr-preview/pr-728/docs/interacting/relationship-queries","h":"#what-is-it-for-2","p":795},{"i":820,"t":"When To Use?","u":"/pr-preview/pr-728/docs/interacting/relationship-queries","h":"#when-to-use-2","p":795},{"i":822,"t":"ListObjects","u":"/pr-preview/pr-728/docs/interacting/relationship-queries","h":"#listobjects","p":795},{"i":823,"t":"What Is It For?","u":"/pr-preview/pr-728/docs/interacting/relationship-queries","h":"#what-is-it-for-3","p":795},{"i":825,"t":"When To Use?","u":"/pr-preview/pr-728/docs/interacting/relationship-queries","h":"#when-to-use-3","p":795},{"i":827,"t":"Caveats","u":"/pr-preview/pr-728/docs/interacting/relationship-queries","h":"#caveats","p":795},{"i":829,"t":"Summary","u":"/pr-preview/pr-728/docs/interacting/relationship-queries","h":"#summary","p":795},{"i":831,"t":"Related Sections","u":"/pr-preview/pr-728/docs/interacting/relationship-queries","h":"#related-sections","p":795},{"i":835,"t":"Before You Start","u":"/pr-preview/pr-728/docs/modeling/building-blocks/object-to-object-relationships","h":"#before-you-start","p":833},{"i":837,"t":"Modeling User Groups","u":"/pr-preview/pr-728/docs/modeling/building-blocks/object-to-object-relationships","h":"#modeling-user-groups","p":833},{"i":839,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/modeling/building-blocks/object-to-object-relationships","h":"#-concepts","p":833},{"i":841,"t":"Step By Step","u":"/pr-preview/pr-728/docs/modeling/building-blocks/object-to-object-relationships","h":"#step-by-step","p":833},{"i":842,"t":"01. Create Parent Relations In Document","u":"/pr-preview/pr-728/docs/modeling/building-blocks/object-to-object-relationships","h":"#01-create-parent-relations-in-document","p":833},{"i":844,"t":"02. Add Parent Relationship Tuples","u":"/pr-preview/pr-728/docs/modeling/building-blocks/object-to-object-relationships","h":"#02-add-parent-relationship-tuples","p":833},{"i":846,"t":"03. Check That Parent Folders Have Permissions","u":"/pr-preview/pr-728/docs/modeling/building-blocks/object-to-object-relationships","h":"#03-check-that-parent-folders-have-permissions","p":833},{"i":848,"t":"Advanced Object to Object Relationships","u":"/pr-preview/pr-728/docs/modeling/building-blocks/object-to-object-relationships","h":"#advanced-object-to-object-relationships","p":833},{"i":850,"t":"01. Create Authorization Model With Object To Object Relationships","u":"/pr-preview/pr-728/docs/modeling/building-blocks/object-to-object-relationships","h":"#01-create-authorization-model-with-object-to-object-relationships","p":833},{"i":852,"t":"02. Adding Relationship Tuples","u":"/pr-preview/pr-728/docs/modeling/building-blocks/object-to-object-relationships","h":"#02-adding-relationship-tuples","p":833},{"i":854,"t":"03. Check To See If Access Is Allowed Without Direct Relationship","u":"/pr-preview/pr-728/docs/modeling/building-blocks/object-to-object-relationships","h":"#03-check-to-see-if-access-is-allowed-without-direct-relationship","p":833},{"i":856,"t":"04. Disassociating Plan From Feature","u":"/pr-preview/pr-728/docs/modeling/building-blocks/object-to-object-relationships","h":"#04-disassociating-plan-from-feature","p":833},{"i":858,"t":"Related Sections","u":"/pr-preview/pr-728/docs/modeling/building-blocks/object-to-object-relationships","h":"#related-sections","p":833},{"i":862,"t":"Before you start","u":"/pr-preview/pr-728/docs/modeling/roles-and-permissions","h":"#before-you-start","p":860},{"i":864,"t":"Direct Access","u":"/pr-preview/pr-728/docs/modeling/roles-and-permissions","h":"#direct-access","p":860},{"i":866,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/modeling/roles-and-permissions","h":"#-concepts","p":860},{"i":868,"t":"Step By Step","u":"/pr-preview/pr-728/docs/modeling/roles-and-permissions","h":"#step-by-step","p":860},{"i":870,"t":"01. Understand How Roles Work Within Our Trip Booking System","u":"/pr-preview/pr-728/docs/modeling/roles-and-permissions","h":"#01-understand-how-roles-work-within-our-trip-booking-system","p":860},{"i":872,"t":"02. Add Permissions For Bookings","u":"/pr-preview/pr-728/docs/modeling/roles-and-permissions","h":"#02-add-permissions-for-bookings","p":860},{"i":874,"t":"03. Checking User Roles And Their Permissions","u":"/pr-preview/pr-728/docs/modeling/roles-and-permissions","h":"#03-checking-user-roles-and-their-permissions","p":860},{"i":876,"t":"Related Sections","u":"/pr-preview/pr-728/docs/modeling/roles-and-permissions","h":"#related-sections","p":860},{"i":880,"t":"Before You Start","u":"/pr-preview/pr-728/docs/modeling/building-blocks/direct-relationships","h":"#before-you-start","p":878},{"i":882,"t":"Direct Access","u":"/pr-preview/pr-728/docs/modeling/building-blocks/direct-relationships","h":"#direct-access","p":878},{"i":884,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/modeling/building-blocks/direct-relationships","h":"#-concepts","p":878},{"i":886,"t":"What Are Direct Relationships?","u":"/pr-preview/pr-728/docs/modeling/building-blocks/direct-relationships","h":"#what-are-direct-relationships","p":878},{"i":888,"t":"Enable Or Disable Direct Relationships","u":"/pr-preview/pr-728/docs/modeling/building-blocks/direct-relationships","h":"#enable-or-disable-direct-relationships","p":878},{"i":890,"t":"How It Affects Your System","u":"/pr-preview/pr-728/docs/modeling/building-blocks/direct-relationships","h":"#how-it-affects-your-system","p":878},{"i":892,"t":"1. With Direct Relationships Enabled","u":"/pr-preview/pr-728/docs/modeling/building-blocks/direct-relationships","h":"#1-with-direct-relationships-enabled","p":878},{"i":894,"t":"2. With Direct Relationships Disabled","u":"/pr-preview/pr-728/docs/modeling/building-blocks/direct-relationships","h":"#2-with-direct-relationships-disabled","p":878},{"i":896,"t":"Related Sections","u":"/pr-preview/pr-728/docs/modeling/building-blocks/direct-relationships","h":"#related-sections","p":878},{"i":900,"t":"Before You Start","u":"/pr-preview/pr-728/docs/modeling/migrating/migrating-relations","h":"#before-you-start","p":898},{"i":902,"t":"Step By Step","u":"/pr-preview/pr-728/docs/modeling/migrating/migrating-relations","h":"#step-by-step","p":898},{"i":904,"t":"01. Create A Backwards Compatible Model","u":"/pr-preview/pr-728/docs/modeling/migrating/migrating-relations","h":"#01-create-a-backwards-compatible-model","p":898},{"i":906,"t":"02. Create a New Relationship Tuple","u":"/pr-preview/pr-728/docs/modeling/migrating/migrating-relations","h":"#02-create-a-new-relationship-tuple","p":898},{"i":908,"t":"03. Migrate The Existing Relationship Tuples","u":"/pr-preview/pr-728/docs/modeling/migrating/migrating-relations","h":"#03-migrate-the-existing-relationship-tuples","p":898},{"i":910,"t":"04. Remove Obsolete Relationship From The Model","u":"/pr-preview/pr-728/docs/modeling/migrating/migrating-relations","h":"#04-remove-obsolete-relationship-from-the-model","p":898},{"i":912,"t":"Related Sections","u":"/pr-preview/pr-728/docs/modeling/migrating/migrating-relations","h":"#related-sections","p":898},{"i":916,"t":"Before You Start","u":"/pr-preview/pr-728/docs/modeling/organization-context-authorization","h":"#before-you-start","p":914},{"i":918,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/modeling/organization-context-authorization","h":"#-concepts","p":914},{"i":920,"t":"Scenario","u":"/pr-preview/pr-728/docs/modeling/organization-context-authorization","h":"#scenario","p":914},{"i":922,"t":"Requirements","u":"/pr-preview/pr-728/docs/modeling/organization-context-authorization","h":"#requirements","p":914},{"i":924,"t":"Step By Step","u":"/pr-preview/pr-728/docs/modeling/organization-context-authorization","h":"#step-by-step","p":914},{"i":926,"t":"Understand Relationships Without Contextual Data","u":"/pr-preview/pr-728/docs/modeling/organization-context-authorization","h":"#understand-relationships-without-contextual-data","p":914},{"i":928,"t":"Take Organization Context Into Consideration","u":"/pr-preview/pr-728/docs/modeling/organization-context-authorization","h":"#take-organization-context-into-consideration","p":914},{"i":930,"t":"Use Contextual Tuples For Context Related Checks","u":"/pr-preview/pr-728/docs/modeling/organization-context-authorization","h":"#use-contextual-tuples-for-context-related-checks","p":914},{"i":932,"t":"Summary","u":"/pr-preview/pr-728/docs/modeling/organization-context-authorization","h":"#summary","p":914},{"i":934,"t":"Related Sections","u":"/pr-preview/pr-728/docs/modeling/organization-context-authorization","h":"#related-sections","p":914},{"i":938,"t":"Before You Start","u":"/pr-preview/pr-728/docs/modeling/advanced/iot","h":"#before-you-start","p":936},{"i":940,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/modeling/advanced/iot","h":"#-concepts","p":936},{"i":942,"t":"What You Will Be Modeling","u":"/pr-preview/pr-728/docs/modeling/advanced/iot","h":"#what-you-will-be-modeling","p":936},{"i":944,"t":"Requirements","u":"/pr-preview/pr-728/docs/modeling/advanced/iot","h":"#requirements","p":936},{"i":946,"t":"Defined Scenarios","u":"/pr-preview/pr-728/docs/modeling/advanced/iot","h":"#defined-scenarios","p":936},{"i":948,"t":"Modeling Device Authorization","u":"/pr-preview/pr-728/docs/modeling/advanced/iot","h":"#modeling-device-authorization","p":936},{"i":950,"t":"01. Writing The Initial Model For A Device","u":"/pr-preview/pr-728/docs/modeling/advanced/iot","h":"#01-writing-the-initial-model-for-a-device","p":936},{"i":952,"t":"02. Inserting Some Relationship Tuples","u":"/pr-preview/pr-728/docs/modeling/advanced/iot","h":"#02-inserting-some-relationship-tuples","p":936},{"i":954,"t":"03. Updating Our Authorization Model To Facilitate Future Changes","u":"/pr-preview/pr-728/docs/modeling/advanced/iot","h":"#03-updating-our-authorization-model-to-facilitate-future-changes","p":936},{"i":956,"t":"04. Modeling Device Groups","u":"/pr-preview/pr-728/docs/modeling/advanced/iot","h":"#04-modeling-device-groups","p":936},{"i":958,"t":"05. Disallow Direct Relationships To Users","u":"/pr-preview/pr-728/docs/modeling/advanced/iot","h":"#05-disallow-direct-relationships-to-users","p":936},{"i":960,"t":"Summary","u":"/pr-preview/pr-728/docs/modeling/advanced/iot","h":"#summary","p":936},{"i":962,"t":"Exercises For You","u":"/pr-preview/pr-728/docs/modeling/advanced/iot","h":"#exercises-for-you","p":936},{"i":966,"t":"Before You Start","u":"/pr-preview/pr-728/docs/modeling/advanced/entitlements","h":"#before-you-start","p":964},{"i":968,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/modeling/advanced/entitlements","h":"#-concepts","p":964},{"i":970,"t":"What You Will Be Modeling","u":"/pr-preview/pr-728/docs/modeling/advanced/entitlements","h":"#what-you-will-be-modeling","p":964},{"i":972,"t":"Requirements","u":"/pr-preview/pr-728/docs/modeling/advanced/entitlements","h":"#requirements","p":964},{"i":974,"t":"Defined Scenarios","u":"/pr-preview/pr-728/docs/modeling/advanced/entitlements","h":"#defined-scenarios","p":964},{"i":976,"t":"Modeling Entitlements For GitHub","u":"/pr-preview/pr-728/docs/modeling/advanced/entitlements","h":"#modeling-entitlements-for-github","p":964},{"i":977,"t":"01. Building The Initial Authorization Model And Relationship Tuples","u":"/pr-preview/pr-728/docs/modeling/advanced/entitlements","h":"#01-building-the-initial-authorization-model-and-relationship-tuples","p":964},{"i":979,"t":"02. Populating The Relationship Tuples","u":"/pr-preview/pr-728/docs/modeling/advanced/entitlements","h":"#02-populating-the-relationship-tuples","p":964},{"i":981,"t":"03. Updating The Authorization Model","u":"/pr-preview/pr-728/docs/modeling/advanced/entitlements","h":"#03-updating-the-authorization-model","p":964},{"i":983,"t":"Summary","u":"/pr-preview/pr-728/docs/modeling/advanced/entitlements","h":"#summary","p":964},{"i":987,"t":"Before You Start","u":"/pr-preview/pr-728/docs/modeling/advanced/github","h":"#before-you-start","p":985},{"i":989,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/modeling/advanced/github","h":"#-concepts","p":985},{"i":991,"t":"What You Will Be Modeling","u":"/pr-preview/pr-728/docs/modeling/advanced/github","h":"#what-you-will-be-modeling","p":985},{"i":993,"t":"Requirements","u":"/pr-preview/pr-728/docs/modeling/advanced/github","h":"#requirements","p":985},{"i":995,"t":"Defined Scenarios","u":"/pr-preview/pr-728/docs/modeling/advanced/github","h":"#defined-scenarios","p":985},{"i":997,"t":"Modeling GitHub's Permissions","u":"/pr-preview/pr-728/docs/modeling/advanced/github","h":"#modeling-githubs-permissions","p":985},{"i":998,"t":"01. Permissions For Individuals In An Org","u":"/pr-preview/pr-728/docs/modeling/advanced/github","h":"#01-permissions-for-individuals-in-an-org","p":985},{"i":1000,"t":"02. Permissions For Teams In An Org","u":"/pr-preview/pr-728/docs/modeling/advanced/github","h":"#02-permissions-for-teams-in-an-org","p":985},{"i":1002,"t":"03. Permissions For Child Teams In An Org","u":"/pr-preview/pr-728/docs/modeling/advanced/github","h":"#03-permissions-for-child-teams-in-an-org","p":985},{"i":1004,"t":"04. Base Permissions For Org Members","u":"/pr-preview/pr-728/docs/modeling/advanced/github","h":"#04-base-permissions-for-org-members","p":985},{"i":1006,"t":"Summary","u":"/pr-preview/pr-728/docs/modeling/advanced/github","h":"#summary","p":985},{"i":1010,"t":"Before You Start","u":"/pr-preview/pr-728/docs/modeling/contextual-time-based-authorization","h":"#before-you-start","p":1008},{"i":1012,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/modeling/contextual-time-based-authorization","h":"#-concepts","p":1008},{"i":1014,"t":"Scenario","u":"/pr-preview/pr-728/docs/modeling/contextual-time-based-authorization","h":"#scenario","p":1008},{"i":1016,"t":"Requirements","u":"/pr-preview/pr-728/docs/modeling/contextual-time-based-authorization","h":"#requirements","p":1008},{"i":1018,"t":"Step By Step","u":"/pr-preview/pr-728/docs/modeling/contextual-time-based-authorization","h":"#step-by-step","p":1008},{"i":1020,"t":"Understand Relationships Without Contextual Data","u":"/pr-preview/pr-728/docs/modeling/contextual-time-based-authorization","h":"#understand-relationships-without-contextual-data","p":1008},{"i":1022,"t":"Take Time And IP Address Into Consideration","u":"/pr-preview/pr-728/docs/modeling/contextual-time-based-authorization","h":"#take-time-and-ip-address-into-consideration","p":1008},{"i":1024,"t":"Use Contextual Tuples For Context Related Checks","u":"/pr-preview/pr-728/docs/modeling/contextual-time-based-authorization","h":"#use-contextual-tuples-for-context-related-checks","p":1008},{"i":1026,"t":"Summary","u":"/pr-preview/pr-728/docs/modeling/contextual-time-based-authorization","h":"#summary","p":1008},{"i":1028,"t":"Taking It A Step Further: Banks As A Service Authorization","u":"/pr-preview/pr-728/docs/modeling/contextual-time-based-authorization","h":"#taking-it-a-step-further-banks-as-a-service-authorization","p":1008},{"i":1030,"t":"Related Sections","u":"/pr-preview/pr-728/docs/modeling/contextual-time-based-authorization","h":"#related-sections","p":1008},{"i":1034,"t":"Before You Start","u":"/pr-preview/pr-728/docs/modeling/advanced/gdrive","h":"#before-you-start","p":1032},{"i":1036,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/modeling/advanced/gdrive","h":"#-concepts","p":1032},{"i":1038,"t":"What You Will Be Modeling","u":"/pr-preview/pr-728/docs/modeling/advanced/gdrive","h":"#what-you-will-be-modeling","p":1032},{"i":1040,"t":"Requirements","u":"/pr-preview/pr-728/docs/modeling/advanced/gdrive","h":"#requirements","p":1032},{"i":1042,"t":"Defined Scenarios","u":"/pr-preview/pr-728/docs/modeling/advanced/gdrive","h":"#defined-scenarios","p":1032},{"i":1044,"t":"Modeling Google Drive's Permissions","u":"/pr-preview/pr-728/docs/modeling/advanced/gdrive","h":"#modeling-google-drives-permissions","p":1032},{"i":1045,"t":"01. Individual Permissions","u":"/pr-preview/pr-728/docs/modeling/advanced/gdrive","h":"#01-individual-permissions","p":1032},{"i":1047,"t":"02. Organization Permissions","u":"/pr-preview/pr-728/docs/modeling/advanced/gdrive","h":"#02-organization-permissions","p":1032},{"i":1049,"t":"03. Folder Permission Propagation","u":"/pr-preview/pr-728/docs/modeling/advanced/gdrive","h":"#03-folder-permission-propagation","p":1032},{"i":1051,"t":"04. Sharing Files And Folders Publicly","u":"/pr-preview/pr-728/docs/modeling/advanced/gdrive","h":"#04-sharing-files-and-folders-publicly","p":1032},{"i":1053,"t":"Related Sections","u":"/pr-preview/pr-728/docs/modeling/advanced/gdrive","h":"#related-sections","p":1032},{"i":1057,"t":"Before You Start","u":"/pr-preview/pr-728/docs/modeling/advanced/slack","h":"#before-you-start","p":1055},{"i":1059,"t":"OpenFGA Concepts","u":"/pr-preview/pr-728/docs/modeling/advanced/slack","h":"#-concepts","p":1055},{"i":1061,"t":"What you will be modeling","u":"/pr-preview/pr-728/docs/modeling/advanced/slack","h":"#what-you-will-be-modeling","p":1055},{"i":1063,"t":"Requirements","u":"/pr-preview/pr-728/docs/modeling/advanced/slack","h":"#requirements","p":1055},{"i":1065,"t":"Defined Scenarios","u":"/pr-preview/pr-728/docs/modeling/advanced/slack","h":"#defined-scenarios","p":1055},{"i":1067,"t":"Modeling Workspaces & Channels","u":"/pr-preview/pr-728/docs/modeling/advanced/slack","h":"#modeling-workspaces--channels","p":1055},{"i":1069,"t":"01. Individual Permissions","u":"/pr-preview/pr-728/docs/modeling/advanced/slack","h":"#01-individual-permissions","p":1055},{"i":1071,"t":"02. Updating The workspace Authorization Model With Implied Relations","u":"/pr-preview/pr-728/docs/modeling/advanced/slack","h":"#02-updating-the-workspace-authorization-model-with-implied-relations","p":1055},{"i":1073,"t":"03. Updating The Authorization Model To Include Channels","u":"/pr-preview/pr-728/docs/modeling/advanced/slack","h":"#03-updating-the-authorization-model-to-include-channels","p":1055},{"i":1075,"t":"Summary","u":"/pr-preview/pr-728/docs/modeling/advanced/slack","h":"#summary","p":1055},{"i":1077,"t":"Exercises For You","u":"/pr-preview/pr-728/docs/modeling/advanced/slack","h":"#exercises-for-you","p":1055}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/4",[0,3.371,1,5.579]],["t/6",[0,4.036]],["t/8",[2,6.541,3,4.333]],["t/10",[4,5.961,5,5.961]],["t/14",[6,4.714,7,4.229]],["t/16",[8,4.92,9,4.92,10,4.92,11,2.128]],["t/18",[11,2.429,12,5.615,13,4.545]],["t/20",[11,2.429,13,4.545,14,5.615]],["t/22",[11,2.829,15,6.541]],["t/24",[16,5.579,17,4.572]],["t/26",[17,4.572,18,5.294]],["t/28",[17,3.439,19,4.92,20,4.484,21,4.484]],["t/30",[22,4.545,23,5.615,24,4.545]],["t/32",[11,2.829,25,4.877]],["t/34",[3,3.72,26,4.048,27,4.35]],["t/38",[22,3.543,24,3.543,28,3.734,29,4.377,30,4.377]],["t/40",[17,4.572,31,4.714]],["t/42",[11,2.429,32,5.615,33,5.615]],["t/44",[16,5.579,17,4.572]],["t/46",[34,6.541,35,2.506]],["t/48",[7,4.229,25,4.877]],["t/50",[36,4.196,37,4.196,38,4.196,39,3.982]],["t/52",[3,3.72,26,4.048,27,4.35]],["t/56",[22,3.543,24,3.543,28,3.734,40,4.377,41,4.377]],["t/58",[42,5.961,43,6.541]],["t/60",[7,4.229,44,6.541]],["t/62",[7,4.229,25,4.877]],["t/64",[7,4.229,45,5.961]],["t/66",[36,4.196,37,4.196,38,4.196,39,3.982]],["t/68",[3,3.72,26,4.048,27,4.35]],["t/72",[6,4.714,7,4.229]],["t/74",[22,4.545,24,4.545,28,4.79]],["t/76",[11,2.429,46,5.615,47,5.615]],["t/78",[20,3.989,48,4.377,49,4.377,50,3.989,51,4.377]],["t/80",[17,4.572,52,6.541]],["t/82",[11,2.829,53,6.541]],["t/84",[16,5.579,17,4.572]],["t/86",[17,4.572,18,5.294]],["t/88",[54,5.294,55,5.961]],["t/90",[3,3.259,56,3.982,57,2.647,58,4.92]],["t/92",[11,2.829,25,4.877]],["t/94",[3,3.72,26,4.048,27,4.35]],["t/98",[0,4.036]],["t/100",[3,4.333,56,5.294]],["t/102",[59,6.541,60,6.541]],["t/106",[7,4.229,45,5.961]],["t/108",[11,2.829,61,6.541]],["t/110",[11,2.429,62,5.615,63,5.615]],["t/112",[3,4.333,56,5.294]],["t/114",[36,4.196,37,4.196,38,4.196,39,3.982]],["t/116",[3,3.72,26,4.048,27,4.35]],["t/119",[25,4.187,39,4.545,42,5.118]],["t/121",[54,5.294,64,6.541]],["t/123",[65,5.615,66,5.615,67,5.615]],["t/125",[68,7.831]],["t/127",[69,7.831]],["t/129",[25,4.187,70,5.615,71,5.615]],["t/134",[72,4.572,73,3.519]],["t/136",[73,3.022,74,5.615,75,5.615]],["t/138",[76,3.439,77,3.811,78,2.571,79,3.982]],["t/140",[77,3.811,78,2.571,79,3.982,80,4.92]],["t/142",[77,3.811,78,2.571,79,3.982,81,4.92]],["t/144",[77,3.811,78,2.571,79,3.982,82,2.026]],["t/146",[83,7.137]],["t/150",[0,4.036]],["t/152",[3,4.333,56,5.294]],["t/154",[4,5.961,5,5.961]],["t/160",[84,7.137]],["t/162",[85,6.338]],["t/164",[86,2.443,87,2.801]],["t/168",[88,5.187]],["t/170",[89,6.541,90,5.294]],["t/172",[35,1.885,73,2.647,91,3.546,92,4.92]],["t/174",[93,5.579,94,3.16]],["t/176",[95,7.831]],["t/178",[96,7.831]],["t/180",[97,7.831]],["t/182",[94,3.16,98,5.961]],["t/184",[93,5.579,99,5.579]],["t/186",[86,2.443,87,2.801]],["t/190",[100,4.275]],["t/194",[101,3.05,102,3.05]],["t/196",[100,4.275]],["t/198",[103,2.407,104,4.92,105,4.92,106,4.92]],["t/200",[72,3.439,107,2.437,108,2.823,109,3.982]],["t/202",[11,1.705,50,3.593,57,2.121,110,2.188,111,2.68,112,3.593]],["t/204",[86,2.443,87,2.801]],["t/208",[113,7.831]],["t/210",[114,4.377,115,4.377,116,4.377,117,4.377,118,4.377]],["t/212",[119,7.831]],["t/214",[120,7.831]],["t/216",[121,7.831]],["t/218",[86,2.443,87,2.801]],["t/222",[35,2.152,73,3.022,122,5.118]],["t/224",[35,2.152,123,5.615,124,5.615]],["t/226",[35,1.677,73,2.355,84,3.989,109,3.543,125,4.377]],["t/228",[0,2.894,1,4.79,126,5.615]],["t/230",[86,2.443,87,2.801]],["t/234",[101,3.05,102,3.05]],["t/236",[100,4.275]],["t/238",[11,1.893,88,2.899,103,2.141,111,2.975,127,3.391]],["t/240",[57,2.647,107,2.437,111,3.344,128,3.982]],["t/242",[86,2.443,87,2.801]],["t/246",[101,3.05,102,3.05]],["t/248",[100,4.275]],["t/250",[11,1.893,88,2.899,103,2.141,111,2.975,127,3.391]],["t/252",[107,2.168,111,2.975,128,3.543,129,3.264,130,2.469]],["t/254",[86,2.443,87,2.801]],["t/258",[131,6.541,132,6.541]],["t/260",[133,6.541,134,5.961]],["t/262",[86,2.443,87,2.801]],["t/266",[0,2.894,88,3.72,135,5.118]],["t/268",[0,2.894,136,5.615,137,5.118]],["t/270",[0,2.536,137,4.484,138,4.92,139,4.92]],["t/272",[88,3.72,140,4.79,141,5.615]],["t/274",[142,7.137]],["t/276",[143,7.137]],["t/278",[72,4.572,88,4.333]],["t/280",[72,3.439,144,4.484,145,3.982,146,3.982]],["t/282",[147,7.137]],["t/284",[148,5.961,149,6.541]],["t/286",[57,3.519,150,6.541]],["t/288",[85,5.294,151,6.541]],["t/290",[152,7.831]],["t/292",[153,7.831]],["t/294",[154,7.831]],["t/296",[155,7.831]],["t/298",[86,2.443,87,2.801]],["t/302",[100,4.275]],["t/304",[0,3.371,142,5.961]],["t/306",[0,3.371,143,5.961]],["t/308",[72,3.439,144,4.484,145,3.982,146,3.982]],["t/310",[72,4.572,147,5.961]],["t/312",[148,5.961,156,5.579]],["t/314",[86,2.443,87,2.801]],["t/318",[101,3.05,102,3.05]],["t/320",[100,4.275]],["t/322",[86,2.443,87,2.801]],["t/330",[94,2.115,99,3.734,157,4.377,158,4.377,159,4.377]],["t/332",[35,1.374,73,1.93,109,2.903,160,3.586,161,3.586,162,3.586,163,3.269]],["t/334",[86,2.443,87,2.801]],["t/338",[164,4.196,165,4.484,166,4.92,167,4.92]],["t/340",[165,5.961,168,5.579]],["t/344",[101,3.05,102,3.05]],["t/346",[100,4.275]],["t/348",[11,1.893,88,2.899,103,2.141,111,2.975,127,3.391]],["t/350",[7,2.127,82,1.355,94,1.589,107,1.629,111,2.236,128,2.662,169,2.371,170,2.452]],["t/352",[82,1.477,94,1.733,98,3.269,110,1.99,111,2.438,128,2.903,169,2.585]],["t/354",[86,2.443,87,2.801]],["t/360",[18,4.545,88,3.72,171,5.615]],["t/362",[82,2.026,172,2.73,173,3.044,174,4.92]],["t/364",[86,1.838,130,2.775,175,4.484,176,4.196]],["t/366",[86,2.648,130,2.775,175,4.484]],["t/368",[90,5.294,177,6.541]],["t/370",[90,5.294,178,6.541]],["t/372",[90,5.294,179,6.541]],["t/374",[83,5.118,180,5.615,181,2.782]],["t/376",[86,2.443,87,2.801]],["t/380",[173,4.846]],["t/382",[173,4.047,182,5.579]],["t/384",[35,2.506,73,3.519]],["t/386",[99,6.68]],["t/388",[130,4.418]],["t/390",[108,4.493]],["t/392",[86,2.925]],["t/394",[86,2.443,182,5.579]],["t/396",[86,1.838,108,2.823,173,3.044,183,4.92]],["t/398",[184,6.066]],["t/400",[82,2.694,94,3.16]],["t/402",[82,2.313,94,2.713,184,4.35]],["t/404",[82,3.225]],["t/406",[82,2.313,172,3.117,185,4.79]],["t/408",[57,3.519,186,5.294]],["t/410",[129,4.187,130,3.168,186,4.545]],["t/412",[94,3.16,187,5.066]],["t/414",[78,2.571,173,3.044,188,4.92,189,4.484]],["t/416",[86,2.443,87,2.801]],["t/420",[0,3.371,72,4.572]],["t/422",[0,2.536,72,3.439,145,3.982,146,3.982]],["t/424",[0,2.536,127,3.811,190,4.92,191,4.92]],["t/428",[101,3.05,102,3.05]],["t/430",[78,3.418,172,3.63]],["t/432",[11,2.829,181,3.24]],["t/434",[100,4.275]],["t/435",[82,2.026,103,2.407,172,2.73,192,3.439]],["t/437",[82,2.026,107,2.437,172,2.73,193,4.196]],["t/439",[86,2.443,87,2.801]],["t/443",[101,3.05,102,3.05]],["t/445",[100,4.275]],["t/447",[11,1.893,88,2.899,103,2.141,111,2.975,127,3.391]],["t/449",[107,2.437,130,2.775,173,3.044,194,3.982]],["t/451",[110,2.429,130,2.469,173,2.709,194,3.543,195,4.377]],["t/455",[101,3.05,102,3.05]],["t/457",[35,2.152,108,3.222,196,3.926]],["t/459",[11,2.829,181,3.24]],["t/461",[100,4.275]],["t/462",[31,3.546,103,2.407,192,3.439,197,4.484]],["t/464",[107,2.437,192,3.439,197,4.484,198,4.92]],["t/466",[57,2.121,78,2.061,110,2.188,130,2.224,199,3.054,200,3.593]],["t/468",[86,2.443,87,2.801]],["t/472",[163,5.961,201,5.066]],["t/474",[57,2.647,201,3.811,202,4.484,203,4.196]],["t/476",[57,1.634,194,2.459,201,2.353,203,2.591,204,2.768,205,2.591,206,3.038,207,3.038,208,3.038]],["t/478",[109,3.191,129,2.94,201,3.054,203,3.363,205,3.363,209,3.942]],["t/480",[201,4.35,210,5.615,211,5.615]],["t/482",[212,5.474]],["t/488",[0,3.371,1,5.579]],["t/490",[213,7.831]],["t/494",[101,3.05,102,3.05]],["t/496",[78,3.418,172,3.63]],["t/498",[35,2.152,78,2.935,189,5.118]],["t/500",[11,2.829,181,3.24]],["t/502",[100,4.275]],["t/503",[82,1.477,94,1.733,103,1.754,176,3.059,192,2.507,193,3.059,214,3.269]],["t/505",[82,1.355,86,1.229,94,1.589,107,1.629,176,2.806,192,2.299,214,2.998,215,3.289]],["t/507",[86,2.443,87,2.801]],["t/513",[101,3.05,102,3.05]],["t/515",[35,2.152,108,3.222,196,3.926]],["t/517",[11,2.829,181,3.24]],["t/519",[100,4.275]],["t/521",[35,1.511,103,1.929,185,3.363,216,3.191,217,3.054,218,3.593]],["t/523",[57,2.647,107,2.437,217,3.811,218,4.484]],["t/525",[86,2.443,87,2.801]],["t/528",[219,7.831]],["t/530",[35,2.152,184,4.35,220,3.817]],["t/532",[82,2.026,94,2.377,169,3.546,184,3.811]],["t/534",[184,4.35,221,5.615,222,4.545]],["t/536",[223,6.68]],["t/538",[173,3.475,224,5.118,225,5.615]],["t/540",[134,7.137]],["t/543",[226,6.68]],["t/545",[57,2.647,91,3.546,186,3.982,226,4.196]],["t/547",[91,3.546,186,3.982,226,4.196,227,4.484]],["t/549",[228,7.831]],["t/551",[86,2.443,87,2.801]],["t/555",[101,3.05,102,3.05]],["t/557",[11,2.829,181,3.24]],["t/559",[100,4.275]],["t/561",[82,2.026,94,2.377,103,2.407,229,3.439]],["t/563",[57,2.647,82,2.026,107,2.437,230,4.196]],["t/565",[86,2.443,87,2.801]],["t/571",[101,3.05,102,3.05]],["t/573",[35,2.506,231,5.579]],["t/575",[35,2.152,76,3.926,232,3.279]],["t/577",[35,1.885,82,2.026,130,3.999]],["t/579",[13,3.982,18,3.982,88,3.259,181,2.437]],["t/581",[100,4.275]],["t/583",[35,1.374,73,1.93,76,2.507,103,1.754,170,2.674,173,2.219,233,2.585]],["t/585",[76,2.756,82,1.624,94,1.905,108,2.262,234,3.942,235,3.942]],["t/587",[0,1.848,76,2.507,82,1.477,94,1.733,110,1.99,232,2.094,236,3.586]],["t/589",[35,1.677,73,2.355,91,3.155,237,2.899,238,3.734]],["t/591",[86,2.443,87,2.801]],["t/595",[35,2.506,239,6.541]],["t/597",[35,1.885,73,2.647,220,3.344,240,4.92]],["t/599",[85,3.982,93,4.196,103,2.407,241,4.92]],["t/601",[107,2.437,129,3.668,130,2.775,173,3.044]],["t/603",[86,1.635,110,2.429,129,3.264,173,2.709,242,4.377]],["t/605",[86,2.098,220,3.817,237,3.72]],["t/607",[35,2.152,243,4.545,244,4.187]],["t/609",[245,6.541,246,6.541]],["t/611",[86,2.443,87,2.801]],["t/615",[101,3.05,102,3.05]],["t/617",[35,1.885,130,2.775,247,3.668,248,4.484]],["t/619",[35,2.152,76,3.926,232,3.279]],["t/621",[11,2.829,181,3.24]],["t/623",[100,4.275]],["t/625",[86,1.135,103,1.486,170,2.265,249,3.038,250,2.591,251,3.038,252,2.353,253,3.038,254,2.591]],["t/627",[91,3.546,107,2.437,238,4.196,255,4.484]],["t/629",[86,2.443,87,2.801]],["t/633",[146,5.294,181,3.24]],["t/634",[256,7.137]],["t/636",[257,7.831]],["t/638",[21,5.961,173,4.047]],["t/640",[223,6.68]],["t/642",[258,7.831]],["t/644",[259,6.541,260,6.541]],["t/646",[261,7.831]],["t/648",[256,7.137]],["t/650",[262,6.541,263,6.541]],["t/652",[35,2.506,122,5.961]],["t/656",[101,3.05,102,3.05]],["t/658",[78,3.418,172,3.63]],["t/660",[11,2.829,181,3.24]],["t/662",[100,4.275]],["t/664",[31,2.034,35,1.081,73,1.518,82,1.162,103,1.38,233,2.034,247,2.104,250,2.407,264,2.822,265,2.186]],["t/666",[31,2.034,86,1.054,107,1.398,173,1.746,182,2.407,217,2.186,224,2.572,233,2.034,265,2.186,266,2.822]],["t/668",[7,1.964,82,1.251,94,1.468,110,1.686,217,2.353,229,2.123,267,2.768,268,2.768,269,2.768]],["t/670",[7,1.964,82,1.251,94,1.468,229,2.123,237,2.012,247,2.265,267,2.768,269,2.768,270,2.768]],["t/672",[26,2.842,57,2.121,217,3.054,243,3.191,268,3.593,270,3.593]],["t/674",[86,2.443,87,2.801]],["t/678",[35,2.152,94,2.713,220,3.817]],["t/680",[169,4.714,244,4.877]],["t/682",[57,3.022,169,4.048,244,4.187]],["t/684",[129,3.668,130,2.775,169,3.546,244,3.668]],["t/686",[164,5.579,244,4.877]],["t/688",[0,2.256,54,3.543,55,3.989,164,3.734,244,3.264]],["t/690",[86,2.443,87,2.801]],["t/694",[101,3.05,102,3.05]],["t/696",[82,1.803,108,2.512,271,4.377,272,4.377,273,4.377]],["t/698",[223,6.68]],["t/700",[86,2.443,87,2.801]],["t/704",[101,3.05,102,3.05]],["t/706",[78,3.418,172,3.63]],["t/708",[11,2.829,181,3.24]],["t/710",[100,4.275]],["t/712",[82,2.026,94,2.377,103,2.407,229,3.439]],["t/714",[57,2.647,82,2.026,107,2.437,230,4.196]],["t/716",[86,2.443,87,2.801]],["t/720",[101,3.05,102,3.05]],["t/722",[78,3.418,172,3.63]],["t/724",[11,2.829,181,3.24]],["t/726",[100,4.275]],["t/728",[6,2.842,35,1.511,73,2.121,103,1.929,181,1.953,274,3.942]],["t/730",[6,3.155,107,2.168,108,2.512,170,3.264,252,3.391]],["t/732",[6,2.842,86,1.473,110,2.188,130,2.224,252,3.054,275,3.942]],["t/734",[57,2.121,78,2.061,130,2.224,199,3.054,200,3.593,237,2.612]],["t/736",[86,2.443,87,2.801]],["t/740",[101,3.05,102,3.05]],["t/742",[78,3.418,172,3.63]],["t/744",[11,2.829,181,3.24]],["t/746",[100,4.275]],["t/748",[35,1.885,73,2.647,103,2.407,216,3.982]],["t/750",[82,1.477,94,1.733,107,1.777,108,2.058,130,2.023,192,2.507,276,3.586]],["t/752",[82,1.803,94,2.115,110,2.429,130,2.469,192,3.06]],["t/754",[78,2.571,108,2.823,237,3.259,277,4.484]],["t/756",[78,2.935,243,4.545,278,4.79]],["t/758",[86,2.443,87,2.801]],["t/762",[101,3.05,102,3.05]],["t/764",[35,2.152,108,3.222,196,3.926]],["t/766",[78,2.935,196,3.926,279,5.615]],["t/768",[11,2.829,181,3.24]],["t/770",[100,4.275]],["t/771",[103,2.407,196,3.439,278,4.196,280,4.92]],["t/773",[78,2.061,107,1.953,252,3.054,277,3.593,278,3.363,281,3.593]],["t/775",[86,2.443,87,2.801]],["t/779",[101,3.05,102,3.05]],["t/781",[35,2.152,108,3.222,196,3.926]],["t/783",[11,2.829,181,3.24]],["t/785",[100,4.275]],["t/787",[31,2.585,35,1.374,78,1.874,103,1.754,108,2.058,216,2.903,282,3.269]],["t/789",[31,2.371,35,1.26,107,1.629,108,1.887,216,2.662,281,2.998,282,2.998,283,3.289]],["t/791",[91,3.546,110,2.73,238,4.196,255,4.484]],["t/793",[86,2.443,87,2.801]],["t/797",[101,3.05,102,3.05]],["t/799",[78,3.418,172,3.63]],["t/801",[11,2.829,181,3.24]],["t/803",[57,4.214]],["t/804",[]],["t/806",[0,4.036]],["t/808",[0,3.371,284,5.579]],["t/810",[285,7.831]],["t/811",[]],["t/813",[0,4.036]],["t/815",[0,3.371,284,5.579]],["t/817",[227,7.137]],["t/818",[]],["t/820",[0,4.036]],["t/822",[286,7.831]],["t/823",[]],["t/825",[0,4.036]],["t/827",[284,6.68]],["t/829",[212,5.474]],["t/831",[86,2.443,87,2.801]],["t/835",[101,3.05,102,3.05]],["t/837",[35,2.152,108,3.222,196,3.926]],["t/839",[11,2.829,181,3.24]],["t/841",[100,4.275]],["t/842",[31,3.155,86,1.635,103,2.141,229,3.06,247,3.264]],["t/844",[82,1.803,94,2.115,107,2.168,170,3.264,247,3.264]],["t/846",[57,2.355,110,2.429,232,2.556,247,3.264,265,3.391]],["t/848",[82,2.026,130,3.999,287,4.92]],["t/850",[35,1.374,73,1.93,82,1.477,103,1.754,130,3.154,229,2.507]],["t/852",[82,2.026,94,2.377,107,2.437,192,3.439]],["t/854",[26,2.371,57,1.77,78,1.719,82,1.355,110,1.826,172,1.826,250,2.806,288,2.806]],["t/856",[85,3.982,237,3.259,289,4.92,290,4.92]],["t/858",[86,2.443,87,2.801]],["t/862",[101,3.05,102,3.05]],["t/864",[78,3.418,172,3.63]],["t/866",[11,2.829,181,3.24]],["t/868",[100,4.275]],["t/870",[76,2.299,91,2.371,103,1.609,291,2.806,292,3.289,293,3.289,294,2.998,295,2.998]],["t/872",[107,2.437,170,3.668,232,2.873,294,4.484]],["t/874",[57,2.355,76,3.06,108,2.512,110,2.429,232,2.556]],["t/876",[86,2.443,87,2.801]],["t/880",[101,3.05,102,3.05]],["t/882",[78,3.418,172,3.63]],["t/884",[11,2.829,181,3.24]],["t/886",[82,2.694,172,3.63]],["t/888",[82,2.026,156,4.196,168,4.196,172,2.73]],["t/890",[295,5.961,296,6.541]],["t/892",[82,2.026,156,4.196,172,2.73,202,4.484]],["t/894",[82,2.026,168,4.196,172,2.73,204,4.484]],["t/896",[86,2.443,87,2.801]],["t/900",[101,3.05,102,3.05]],["t/902",[100,4.275]],["t/904",[35,1.677,103,2.141,229,3.06,297,4.377,298,4.377]],["t/906",[7,2.83,82,1.803,94,2.115,107,2.168,229,3.06]],["t/908",[82,1.803,94,2.115,110,2.429,230,3.734,299,4.377]],["t/910",[35,1.677,82,1.803,193,3.734,237,2.899,300,4.377]],["t/912",[86,2.443,87,2.801]],["t/916",[101,3.05,102,3.05]],["t/918",[11,2.829,181,3.24]],["t/920",[301,5.644]],["t/922",[302,5.644]],["t/924",[100,4.275]],["t/926",[82,1.803,140,3.734,187,3.391,288,3.734,291,3.734]],["t/928",[222,3.982,254,4.196,303,4.196,304,4.484]],["t/930",[0,2.032,57,2.121,86,1.473,94,1.905,187,3.054,222,3.191]],["t/932",[212,5.474]],["t/934",[86,2.443,87,2.801]],["t/938",[101,3.05,102,3.05]],["t/940",[11,2.829,181,3.24]],["t/942",[35,3.001]],["t/944",[302,5.644]],["t/946",[220,4.446,301,4.714]],["t/948",[35,2.152,73,3.022,305,4.79]],["t/950",[35,1.677,103,2.141,169,3.155,231,3.734,305,3.734]],["t/952",[82,2.026,94,2.377,107,2.437,306,4.92]],["t/954",[35,1.374,73,1.93,110,1.99,194,2.903,233,2.585,307,3.586,308,3.586]],["t/956",[35,1.885,196,3.439,237,3.259,305,4.196]],["t/958",[82,1.803,108,2.512,172,2.429,243,3.543,309,4.377]],["t/960",[212,5.474]],["t/962",[310,7.137]],["t/966",[101,3.05,102,3.05]],["t/968",[11,2.829,181,3.24]],["t/970",[35,3.001]],["t/972",[302,5.644]],["t/974",[220,4.446,301,4.714]],["t/976",[35,2.152,54,4.545,311,5.615]],["t/977",[35,1.374,73,1.93,82,1.477,94,1.733,103,1.754,205,3.059,231,3.059]],["t/979",[82,2.026,94,2.377,107,2.437,312,4.92]],["t/981",[35,1.885,73,2.647,110,2.73,233,3.546]],["t/983",[212,5.474]],["t/987",[101,3.05,102,3.05]],["t/989",[11,2.829,181,3.24]],["t/991",[35,3.001]],["t/993",[302,5.644]],["t/995",[220,4.446,301,4.714]],["t/997",[35,2.152,232,3.279,313,5.615]],["t/998",[103,2.407,199,3.811,232,2.873,314,3.982]],["t/1000",[6,3.546,107,2.437,232,2.873,314,3.982]],["t/1002",[6,3.155,110,2.429,232,2.556,248,3.989,314,3.543]],["t/1004",[77,3.391,232,2.556,237,2.899,252,3.391,314,3.543]],["t/1006",[212,5.474]],["t/1010",[101,3.05,102,3.05]],["t/1012",[11,2.829,181,3.24]],["t/1014",[301,5.644]],["t/1016",[302,5.644]],["t/1018",[100,4.275]],["t/1020",[82,1.803,140,3.734,187,3.391,288,3.734,291,3.734]],["t/1022",[303,3.734,304,3.989,315,4.377,316,4.377,317,4.377]],["t/1024",[0,2.032,57,2.121,86,1.473,94,1.905,187,3.054,222,3.191]],["t/1026",[212,5.474]],["t/1028",[73,2.121,100,1.953,112,3.593,303,3.363,318,3.942,319,3.942]],["t/1030",[86,2.443,87,2.801]],["t/1034",[101,3.05,102,3.05]],["t/1036",[11,2.829,181,3.24]],["t/1038",[35,3.001]],["t/1040",[302,5.644]],["t/1042",[220,4.446,301,4.714]],["t/1044",[35,1.885,232,2.873,320,4.92,321,4.92]],["t/1045",[103,2.747,199,4.35,232,3.279]],["t/1047",[107,2.782,232,3.279,254,4.79]],["t/1049",[110,2.73,232,2.873,265,3.811,322,4.92]],["t/1051",[135,3.989,145,3.543,237,2.899,265,3.391,323,4.377]],["t/1053",[86,2.443,87,2.801]],["t/1057",[101,3.05,102,3.05]],["t/1059",[11,2.829,181,3.24]],["t/1061",[35,3.001]],["t/1063",[302,5.644]],["t/1065",[220,4.446,301,4.714]],["t/1067",[13,3.982,35,1.885,324,4.484,325,4.484]],["t/1069",[103,2.747,199,4.35,232,3.279]],["t/1071",[35,1.374,73,1.93,86,1.34,107,1.777,185,3.059,233,2.585,324,3.269]],["t/1073",[35,1.511,73,2.121,110,2.188,233,2.842,325,3.593,326,3.942]],["t/1075",[212,5.474]],["t/1077",[310,7.137]]],"invertedIndex":[["",{"_index":13,"t":{"18":{"position":[[8,1]]},"20":{"position":[[10,1]]},"579":{"position":[[9,1]]},"1067":{"position":[[20,1]]}}}],["01",{"_index":103,"t":{"198":{"position":[[0,3]]},"238":{"position":[[0,3]]},"250":{"position":[[0,3]]},"348":{"position":[[0,3]]},"435":{"position":[[0,3]]},"447":{"position":[[0,3]]},"462":{"position":[[0,3]]},"503":{"position":[[0,3]]},"521":{"position":[[0,3]]},"561":{"position":[[0,3]]},"583":{"position":[[0,3]]},"599":{"position":[[0,3]]},"625":{"position":[[0,3]]},"664":{"position":[[0,3]]},"712":{"position":[[0,3]]},"728":{"position":[[0,3]]},"748":{"position":[[0,3]]},"771":{"position":[[0,3]]},"787":{"position":[[0,3]]},"842":{"position":[[0,3]]},"850":{"position":[[0,3]]},"870":{"position":[[0,3]]},"904":{"position":[[0,3]]},"950":{"position":[[0,3]]},"977":{"position":[[0,3]]},"998":{"position":[[0,3]]},"1045":{"position":[[0,3]]},"1069":{"position":[[0,3]]}}}],["02",{"_index":107,"t":{"200":{"position":[[0,3]]},"240":{"position":[[0,3]]},"252":{"position":[[0,3]]},"350":{"position":[[0,3]]},"437":{"position":[[0,3]]},"449":{"position":[[0,3]]},"464":{"position":[[0,3]]},"505":{"position":[[0,3]]},"523":{"position":[[0,3]]},"563":{"position":[[0,3]]},"601":{"position":[[0,3]]},"627":{"position":[[0,3]]},"666":{"position":[[0,3]]},"714":{"position":[[0,3]]},"730":{"position":[[0,3]]},"750":{"position":[[0,3]]},"773":{"position":[[0,3]]},"789":{"position":[[0,3]]},"844":{"position":[[0,3]]},"852":{"position":[[0,3]]},"872":{"position":[[0,3]]},"906":{"position":[[0,3]]},"952":{"position":[[0,3]]},"979":{"position":[[0,3]]},"1000":{"position":[[0,3]]},"1047":{"position":[[0,3]]},"1071":{"position":[[0,3]]}}}],["02.use",{"_index":234,"t":{"585":{"position":[[0,6]]}}}],["03",{"_index":110,"t":{"202":{"position":[[0,3]]},"352":{"position":[[0,3]]},"451":{"position":[[0,3]]},"466":{"position":[[0,3]]},"587":{"position":[[0,3]]},"603":{"position":[[0,3]]},"668":{"position":[[0,3]]},"732":{"position":[[0,3]]},"752":{"position":[[0,3]]},"791":{"position":[[0,3]]},"846":{"position":[[0,3]]},"854":{"position":[[0,3]]},"874":{"position":[[0,3]]},"908":{"position":[[0,3]]},"954":{"position":[[0,3]]},"981":{"position":[[0,3]]},"1002":{"position":[[0,3]]},"1049":{"position":[[0,3]]},"1073":{"position":[[0,3]]}}}],["04",{"_index":237,"t":{"589":{"position":[[0,3]]},"605":{"position":[[0,3]]},"670":{"position":[[0,3]]},"734":{"position":[[0,3]]},"754":{"position":[[0,3]]},"856":{"position":[[0,3]]},"910":{"position":[[0,3]]},"956":{"position":[[0,3]]},"1004":{"position":[[0,3]]},"1051":{"position":[[0,3]]}}}],["05",{"_index":243,"t":{"607":{"position":[[0,3]]},"672":{"position":[[0,3]]},"756":{"position":[[0,3]]},"958":{"position":[[0,3]]}}}],["06",{"_index":245,"t":{"609":{"position":[[0,3]]}}}],["1",{"_index":202,"t":{"474":{"position":[[7,2]]},"892":{"position":[[0,2]]}}}],["2",{"_index":204,"t":{"476":{"position":[[7,2]]},"894":{"position":[[0,2]]}}}],["2024",{"_index":24,"t":{"30":{"position":[[11,4]]},"38":{"position":[[15,4]]},"56":{"position":[[15,4]]},"74":{"position":[[15,5]]}}}],["3",{"_index":209,"t":{"478":{"position":[[7,2]]}}}],["access",{"_index":78,"t":{"138":{"position":[[19,6]]},"140":{"position":[[24,6]]},"142":{"position":[[21,6]]},"144":{"position":[[27,6]]},"414":{"position":[[26,7]]},"430":{"position":[[7,6]]},"466":{"position":[[36,6]]},"496":{"position":[[7,6]]},"498":{"position":[[16,6]]},"658":{"position":[[7,6]]},"706":{"position":[[7,6]]},"722":{"position":[[7,6]]},"734":{"position":[[36,6]]},"742":{"position":[[7,6]]},"754":{"position":[[20,6]]},"756":{"position":[[13,6]]},"766":{"position":[[15,6]]},"773":{"position":[[44,6]]},"787":{"position":[[50,9]]},"799":{"position":[[7,6]]},"854":{"position":[[20,6]]},"864":{"position":[[7,6]]},"882":{"position":[[7,6]]}}}],["action",{"_index":55,"t":{"88":{"position":[[7,7]]},"688":{"position":[[27,7]]}}}],["ad",{"_index":192,"t":{"435":{"position":[[4,6]]},"462":{"position":[[4,6]]},"464":{"position":[[4,6]]},"503":{"position":[[4,6]]},"505":{"position":[[4,6]]},"750":{"position":[[4,6]]},"752":{"position":[[4,6]]},"852":{"position":[[4,6]]}}}],["add",{"_index":170,"t":{"350":{"position":[[25,3]]},"583":{"position":[[38,3]]},"625":{"position":[[4,3]]},"730":{"position":[[4,3]]},"844":{"position":[[4,3]]},"872":{"position":[[4,3]]}}}],["address",{"_index":317,"t":{"1022":{"position":[[17,7]]}}}],["adopt",{"_index":44,"t":{"60":{"position":[[4,8]]}}}],["advanc",{"_index":287,"t":{"848":{"position":[[0,8]]}}}],["affect",{"_index":296,"t":{"890":{"position":[[7,7]]}}}],["allow",{"_index":250,"t":{"625":{"position":[[36,5]]},"664":{"position":[[38,5]]},"854":{"position":[[30,7]]}}}],["alway",{"_index":160,"t":{"332":{"position":[[0,6]]}}}],["anoth",{"_index":276,"t":{"750":{"position":[[45,7]]}}}],["api",{"_index":111,"t":{"202":{"position":[[32,3]]},"238":{"position":[[26,3]]},"240":{"position":[[18,3]]},"250":{"position":[[26,3]]},"252":{"position":[[25,3]]},"348":{"position":[[26,3]]},"350":{"position":[[18,3]]},"352":{"position":[[18,3]]},"447":{"position":[[26,3]]}}}],["apk",{"_index":117,"t":{"210":{"position":[[20,4]]}}}],["assess",{"_index":63,"t":{"110":{"position":[[17,10]]}}}],["assign",{"_index":275,"t":{"732":{"position":[[4,6]]}}}],["associ",{"_index":236,"t":{"587":{"position":[[31,9]]}}}],["attribut",{"_index":80,"t":{"140":{"position":[[8,9]]}}}],["authent",{"_index":72,"t":{"134":{"position":[[0,14]]},"200":{"position":[[4,12]]},"278":{"position":[[12,14]]},"280":{"position":[[15,14]]},"308":{"position":[[15,14]]},"310":{"position":[[5,14]]},"420":{"position":[[9,14]]},"422":{"position":[[17,14]]}}}],["author",{"_index":73,"t":{"134":{"position":[[19,13]]},"136":{"position":[[21,14]]},"172":{"position":[[10,13]]},"222":{"position":[[16,13]]},"226":{"position":[[26,13]]},"332":{"position":[[15,13]]},"384":{"position":[[11,13]]},"583":{"position":[[15,13]]},"589":{"position":[[20,13]]},"597":{"position":[[23,13]]},"664":{"position":[[15,13]]},"728":{"position":[[43,13]]},"748":{"position":[[11,13]]},"850":{"position":[[11,13]]},"948":{"position":[[16,13]]},"954":{"position":[[17,13]]},"977":{"position":[[25,13]]},"981":{"position":[[17,13]]},"1028":{"position":[[45,13]]},"1071":{"position":[[27,13]]},"1073":{"position":[[17,13]]}}}],["backward",{"_index":297,"t":{"904":{"position":[[13,9]]}}}],["bank",{"_index":319,"t":{"1028":{"position":[[26,5]]}}}],["base",{"_index":77,"t":{"138":{"position":[[13,5]]},"140":{"position":[[18,5]]},"142":{"position":[[15,5]]},"144":{"position":[[21,5]]},"1004":{"position":[[4,4]]}}}],["basic",{"_index":89,"t":{"170":{"position":[[0,5]]}}}],["befor",{"_index":101,"t":{"194":{"position":[[0,6]]},"234":{"position":[[0,6]]},"246":{"position":[[0,6]]},"318":{"position":[[0,6]]},"344":{"position":[[0,6]]},"428":{"position":[[0,6]]},"443":{"position":[[0,6]]},"455":{"position":[[0,6]]},"494":{"position":[[0,6]]},"513":{"position":[[0,6]]},"555":{"position":[[0,6]]},"571":{"position":[[0,6]]},"615":{"position":[[0,6]]},"656":{"position":[[0,6]]},"694":{"position":[[0,6]]},"704":{"position":[[0,6]]},"720":{"position":[[0,6]]},"740":{"position":[[0,6]]},"762":{"position":[[0,6]]},"779":{"position":[[0,6]]},"797":{"position":[[0,6]]},"835":{"position":[[0,6]]},"862":{"position":[[0,6]]},"880":{"position":[[0,6]]},"900":{"position":[[0,6]]},"916":{"position":[[0,6]]},"938":{"position":[[0,6]]},"966":{"position":[[0,6]]},"987":{"position":[[0,6]]},"1010":{"position":[[0,6]]},"1034":{"position":[[0,6]]},"1057":{"position":[[0,6]]}}}],["behavior",{"_index":8,"t":{"16":{"position":[[0,8]]}}}],["benefit",{"_index":84,"t":{"160":{"position":[[0,8]]},"226":{"position":[[0,8]]}}}],["best",{"_index":211,"t":{"480":{"position":[[13,4]]}}}],["between",{"_index":264,"t":{"664":{"position":[[66,7]]}}}],["block",{"_index":282,"t":{"787":{"position":[[37,7]]},"789":{"position":[[38,7]]}}}],["bob",{"_index":268,"t":{"668":{"position":[[53,3]]},"672":{"position":[[20,3]]}}}],["book",{"_index":294,"t":{"870":{"position":[[46,7]]},"872":{"position":[[24,8]]}}}],["bound",{"_index":188,"t":{"414":{"position":[[13,5]]}}}],["brew",{"_index":113,"t":{"208":{"position":[[0,4]]}}}],["build",{"_index":205,"t":{"476":{"position":[[10,5]]},"478":{"position":[[10,5]]},"977":{"position":[[4,8]]}}}],["busi",{"_index":41,"t":{"56":{"position":[[30,5]]}}}],["call",{"_index":128,"t":{"240":{"position":[[4,7]]},"252":{"position":[[4,7]]},"350":{"position":[[4,7]]},"352":{"position":[[4,7]]}}}],["can_delet",{"_index":249,"t":{"625":{"position":[[8,10]]}}}],["canon",{"_index":14,"t":{"20":{"position":[[0,9]]}}}],["cascad",{"_index":266,"t":{"666":{"position":[[74,9]]}}}],["case",{"_index":1,"t":{"4":{"position":[[4,5]]},"228":{"position":[[14,5]]},"488":{"position":[[4,5]]}}}],["caveat",{"_index":284,"t":{"808":{"position":[[0,7]]},"815":{"position":[[0,7]]},"827":{"position":[[0,7]]}}}],["chang",{"_index":194,"t":{"449":{"position":[[8,7]]},"451":{"position":[[8,7]]},"476":{"position":[[35,7]]},"954":{"position":[[58,7]]}}}],["channel",{"_index":325,"t":{"1067":{"position":[[22,8]]},"1073":{"position":[[48,8]]}}}],["check",{"_index":57,"t":{"90":{"position":[[13,5]]},"202":{"position":[[26,5]]},"240":{"position":[[12,5]]},"286":{"position":[[7,5]]},"408":{"position":[[10,5]]},"466":{"position":[[4,8]]},"474":{"position":[[23,5]]},"476":{"position":[[66,5]]},"523":{"position":[[4,5]]},"545":{"position":[[7,5]]},"563":{"position":[[4,5]]},"672":{"position":[[4,5]]},"682":{"position":[[6,5]]},"714":{"position":[[4,5]]},"734":{"position":[[4,8]]},"803":{"position":[[0,5]]},"846":{"position":[[4,5]]},"854":{"position":[[4,5]]},"874":{"position":[[4,8]]},"930":{"position":[[42,6]]},"1024":{"position":[[42,6]]}}}],["child",{"_index":248,"t":{"617":{"position":[[16,5]]},"1002":{"position":[[20,5]]}}}],["choos",{"_index":210,"t":{"480":{"position":[[0,8]]}}}],["cli",{"_index":52,"t":{"80":{"position":[[0,3]]}}}],["client",{"_index":127,"t":{"238":{"position":[[30,6]]},"250":{"position":[[30,6]]},"348":{"position":[[30,6]]},"424":{"position":[[6,6]]},"447":{"position":[[30,6]]}}}],["closer",{"_index":30,"t":{"38":{"position":[[31,7]]}}}],["cncf",{"_index":42,"t":{"58":{"position":[[0,4]]},"119":{"position":[[6,5]]}}}],["cncf'",{"_index":38,"t":{"50":{"position":[[30,6]]},"66":{"position":[[30,6]]},"114":{"position":[[30,6]]}}}],["code",{"_index":20,"t":{"28":{"position":[[3,4]]},"78":{"position":[[14,4]]}}}],["command",{"_index":138,"t":{"270":{"position":[[6,7]]}}}],["commun",{"_index":25,"t":{"32":{"position":[[8,9]]},"48":{"position":[[0,9]]},"62":{"position":[[0,9]]},"92":{"position":[[8,9]]},"119":{"position":[[12,10]]},"129":{"position":[[8,9]]}}}],["compani",{"_index":197,"t":{"462":{"position":[[11,7]]},"464":{"position":[[27,7]]}}}],["compat",{"_index":298,"t":{"904":{"position":[[23,10]]}}}],["concept",{"_index":181,"t":{"374":{"position":[[20,8]]},"432":{"position":[[8,8]]},"459":{"position":[[8,8]]},"500":{"position":[[8,8]]},"517":{"position":[[8,8]]},"557":{"position":[[8,8]]},"579":{"position":[[0,8]]},"621":{"position":[[8,8]]},"633":{"position":[[4,8]]},"660":{"position":[[8,8]]},"708":{"position":[[8,8]]},"724":{"position":[[8,8]]},"728":{"position":[[18,7]]},"744":{"position":[[8,8]]},"768":{"position":[[8,8]]},"783":{"position":[[8,8]]},"801":{"position":[[8,8]]},"839":{"position":[[8,8]]},"866":{"position":[[8,8]]},"884":{"position":[[8,8]]},"918":{"position":[[8,8]]},"940":{"position":[[8,8]]},"968":{"position":[[8,8]]},"989":{"position":[[8,8]]},"1012":{"position":[[8,8]]},"1036":{"position":[[8,8]]},"1059":{"position":[[8,8]]}}}],["concurr",{"_index":133,"t":{"260":{"position":[[0,11]]}}}],["condit",{"_index":184,"t":{"398":{"position":[[10,10]]},"402":{"position":[[10,11]]},"530":{"position":[[9,10]]},"532":{"position":[[8,11]]},"534":{"position":[[13,9]]}}}],["configur",{"_index":88,"t":{"168":{"position":[[0,13]]},"238":{"position":[[4,9]]},"250":{"position":[[4,9]]},"266":{"position":[[8,13]]},"272":{"position":[[0,11]]},"278":{"position":[[0,11]]},"348":{"position":[[4,9]]},"360":{"position":[[14,13]]},"447":{"position":[[4,9]]},"579":{"position":[[11,13]]}}}],["consider",{"_index":304,"t":{"928":{"position":[[31,13]]},"1022":{"position":[[30,13]]}}}],["context",{"_index":222,"t":{"534":{"position":[[23,7]]},"928":{"position":[[18,7]]},"930":{"position":[[26,7]]},"1024":{"position":[[26,7]]}}}],["contextu",{"_index":187,"t":{"412":{"position":[[9,10]]},"926":{"position":[[33,10]]},"930":{"position":[[4,10]]},"1020":{"position":[[33,10]]},"1024":{"position":[[4,10]]}}}],["control",{"_index":79,"t":{"138":{"position":[[26,8]]},"140":{"position":[[31,8]]},"142":{"position":[[28,8]]},"144":{"position":[[34,8]]}}}],["core",{"_index":258,"t":{"642":{"position":[[0,4]]}}}],["creat",{"_index":229,"t":{"561":{"position":[[4,6]]},"668":{"position":[[4,6]]},"670":{"position":[[4,6]]},"712":{"position":[[4,6]]},"842":{"position":[[4,6]]},"850":{"position":[[4,6]]},"904":{"position":[[4,6]]},"906":{"position":[[4,6]]}}}],["credenti",{"_index":190,"t":{"424":{"position":[[13,11]]}}}],["csv",{"_index":97,"t":{"180":{"position":[[0,3]]}}}],["data",{"_index":140,"t":{"272":{"position":[[12,4]]},"926":{"position":[[44,4]]},"1020":{"position":[[44,4]]}}}],["databas",{"_index":131,"t":{"258":{"position":[[0,8]]}}}],["deb",{"_index":115,"t":{"210":{"position":[[6,5]]}}}],["defin",{"_index":220,"t":{"530":{"position":[[0,8]]},"597":{"position":[[14,8]]},"605":{"position":[[4,6]]},"678":{"position":[[0,6]]},"946":{"position":[[0,7]]},"974":{"position":[[0,7]]},"995":{"position":[[0,7]]},"1042":{"position":[[0,7]]},"1065":{"position":[[0,7]]}}}],["definit",{"_index":182,"t":{"382":{"position":[[15,11]]},"394":{"position":[[19,11]]},"666":{"position":[[52,10]]}}}],["delet",{"_index":98,"t":{"182":{"position":[[0,6]]},"352":{"position":[[25,6]]}}}],["develop",{"_index":10,"t":{"16":{"position":[[16,11]]}}}],["devic",{"_index":305,"t":{"948":{"position":[[9,6]]},"950":{"position":[[36,6]]},"956":{"position":[[13,6]]}}}],["differ",{"_index":166,"t":{"338":{"position":[[28,9]]}}}],["direct",{"_index":172,"t":{"362":{"position":[[0,6]]},"406":{"position":[[9,6]]},"430":{"position":[[0,6]]},"435":{"position":[[11,6]]},"437":{"position":[[13,6]]},"496":{"position":[[0,6]]},"658":{"position":[[0,6]]},"706":{"position":[[0,6]]},"722":{"position":[[0,6]]},"742":{"position":[[0,6]]},"799":{"position":[[0,6]]},"854":{"position":[[46,6]]},"864":{"position":[[0,6]]},"882":{"position":[[0,6]]},"886":{"position":[[9,6]]},"888":{"position":[[18,6]]},"892":{"position":[[8,6]]},"894":{"position":[[8,6]]},"958":{"position":[[13,6]]}}}],["directli",{"_index":183,"t":{"396":{"position":[[10,8]]}}}],["directori",{"_index":271,"t":{"696":{"position":[[5,12]]}}}],["disabl",{"_index":168,"t":{"340":{"position":[[0,9]]},"888":{"position":[[10,7]]},"894":{"position":[[29,8]]}}}],["disallow",{"_index":309,"t":{"958":{"position":[[4,8]]}}}],["disassoci",{"_index":289,"t":{"856":{"position":[[4,14]]}}}],["discord",{"_index":37,"t":{"50":{"position":[[19,7]]},"66":{"position":[[19,7]]},"114":{"position":[[19,7]]}}}],["discuss",{"_index":64,"t":{"121":{"position":[[7,11]]}}}],["docker",{"_index":119,"t":{"212":{"position":[[0,6]]}}}],["document",{"_index":31,"t":{"40":{"position":[[0,13]]},"462":{"position":[[26,8]]},"664":{"position":[[85,8]]},"666":{"position":[[38,8]]},"787":{"position":[[62,8]]},"789":{"position":[[69,8]]},"842":{"position":[[31,8]]}}}],["document:meeting_notes.doc",{"_index":270,"t":{"670":{"position":[[81,26]]},"672":{"position":[[40,26]]}}}],["drive'",{"_index":321,"t":{"1044":{"position":[[16,7]]}}}],["driven",{"_index":9,"t":{"16":{"position":[[9,6]]}}}],["ecosystem",{"_index":33,"t":{"42":{"position":[[20,9]]}}}],["edit",{"_index":283,"t":{"789":{"position":[[60,4]]}}}],["editor",{"_index":217,"t":{"521":{"position":[[30,6]]},"523":{"position":[[15,7]]},"666":{"position":[[15,6]]},"668":{"position":[[63,6]]},"672":{"position":[[30,6]]}}}],["employe",{"_index":198,"t":{"464":{"position":[[11,8]]}}}],["enabl",{"_index":156,"t":{"312":{"position":[[0,8]]},"888":{"position":[[0,6]]},"892":{"position":[[29,7]]}}}],["endpoint",{"_index":208,"t":{"476":{"position":[[43,9]]}}}],["enhanc",{"_index":51,"t":{"78":{"position":[[31,12]]}}}],["enlightn",{"_index":46,"t":{"76":{"position":[[8,13]]}}}],["entitl",{"_index":311,"t":{"976":{"position":[[9,12]]}}}],["environ",{"_index":136,"t":{"268":{"position":[[6,11]]}}}],["equival",{"_index":180,"t":{"374":{"position":[[0,10]]}}}],["eu",{"_index":23,"t":{"30":{"position":[[8,2]]}}}],["europ",{"_index":28,"t":{"38":{"position":[[8,6]]},"56":{"position":[[8,6]]},"74":{"position":[[8,6]]}}}],["exampl",{"_index":223,"t":{"536":{"position":[[0,8]]},"640":{"position":[[0,7]]},"698":{"position":[[0,7]]}}}],["exclus",{"_index":179,"t":{"372":{"position":[[4,9]]}}}],["exercis",{"_index":310,"t":{"962":{"position":[[0,9]]},"1077":{"position":[[0,9]]}}}],["exist",{"_index":230,"t":{"563":{"position":[[32,6]]},"714":{"position":[[32,6]]},"908":{"position":[[16,8]]}}}],["expand",{"_index":227,"t":{"547":{"position":[[7,6]]},"817":{"position":[[0,6]]}}}],["experiment",{"_index":151,"t":{"288":{"position":[[0,12]]}}}],["extens",{"_index":21,"t":{"28":{"position":[[8,9]]},"638":{"position":[[5,10]]}}}],["facilit",{"_index":307,"t":{"954":{"position":[[40,10]]}}}],["featur",{"_index":85,"t":{"162":{"position":[[0,8]]},"288":{"position":[[13,8]]},"599":{"position":[[28,7]]},"856":{"position":[[29,7]]}}}],["feedback",{"_index":60,"t":{"102":{"position":[[13,9]]}}}],["fga.mod",{"_index":256,"t":{"634":{"position":[[0,7]]},"648":{"position":[[0,7]]}}}],["file",{"_index":135,"t":{"266":{"position":[[22,4]]},"1051":{"position":[[12,5]]}}}],["fine",{"_index":74,"t":{"136":{"position":[[8,4]]}}}],["flow",{"_index":191,"t":{"424":{"position":[[25,4]]}}}],["folder",{"_index":265,"t":{"664":{"position":[[74,6]]},"666":{"position":[[89,6]]},"846":{"position":[[22,7]]},"1049":{"position":[[4,6]]},"1051":{"position":[[22,7]]}}}],["folder:not",{"_index":269,"t":{"668":{"position":[[73,12]]},"670":{"position":[[53,12]]}}}],["formerli",{"_index":66,"t":{"123":{"position":[[2,9]]}}}],["framework",{"_index":106,"t":{"198":{"position":[[22,9]]}}}],["further",{"_index":318,"t":{"1028":{"position":[[17,8]]}}}],["futur",{"_index":308,"t":{"954":{"position":[[51,6]]}}}],["get",{"_index":29,"t":{"38":{"position":[[23,7]]}}}],["github",{"_index":54,"t":{"88":{"position":[[0,6]]},"121":{"position":[[0,6]]},"688":{"position":[[20,6]]},"976":{"position":[[26,6]]}}}],["github'",{"_index":313,"t":{"997":{"position":[[9,8]]}}}],["go",{"_index":120,"t":{"214":{"position":[[0,2]]}}}],["godaddi",{"_index":12,"t":{"18":{"position":[[0,7]]}}}],["googl",{"_index":320,"t":{"1044":{"position":[[9,6]]}}}],["grain",{"_index":75,"t":{"136":{"position":[[13,7]]}}}],["group",{"_index":196,"t":{"457":{"position":[[14,6]]},"515":{"position":[[14,6]]},"764":{"position":[[14,6]]},"766":{"position":[[9,5]]},"771":{"position":[[13,5]]},"781":{"position":[[14,6]]},"837":{"position":[[14,6]]},"956":{"position":[[20,6]]}}}],["hackathon",{"_index":61,"t":{"108":{"position":[[8,9]]}}}],["health",{"_index":150,"t":{"286":{"position":[[0,6]]}}}],["id",{"_index":109,"t":{"200":{"position":[[30,2]]},"226":{"position":[[46,2]]},"332":{"position":[[35,2]]},"478":{"position":[[26,4]]}}}],["ident",{"_index":272,"t":{"696":{"position":[[18,8]]}}}],["identifi",{"_index":158,"t":{"330":{"position":[[22,12]]}}}],["impli",{"_index":185,"t":{"406":{"position":[[20,7]]},"521":{"position":[[24,5]]},"1071":{"position":[[52,7]]}}}],["import",{"_index":93,"t":{"174":{"position":[[0,6]]},"184":{"position":[[0,6]]},"599":{"position":[[18,9]]}}}],["improv",{"_index":17,"t":{"24":{"position":[[4,12]]},"26":{"position":[[9,12]]},"28":{"position":[[18,12]]},"40":{"position":[[14,12]]},"44":{"position":[[4,12]]},"80":{"position":[[4,12]]},"84":{"position":[[4,12]]},"86":{"position":[[9,12]]}}}],["includ",{"_index":326,"t":{"1073":{"position":[[40,7]]}}}],["incub",{"_index":43,"t":{"58":{"position":[[5,10]]}}}],["index",{"_index":207,"t":{"476":{"position":[[24,5]]}}}],["indic",{"_index":267,"t":{"668":{"position":[[39,8]]},"670":{"position":[[39,8]]}}}],["individu",{"_index":199,"t":{"466":{"position":[[16,10]]},"734":{"position":[[16,10]]},"998":{"position":[[20,11]]},"1045":{"position":[[4,10]]},"1069":{"position":[[4,10]]}}}],["inform",{"_index":159,"t":{"330":{"position":[[35,11]]}}}],["initi",{"_index":231,"t":{"573":{"position":[[0,7]]},"950":{"position":[[16,7]]},"977":{"position":[[17,7]]}}}],["insert",{"_index":306,"t":{"952":{"position":[[4,9]]}}}],["instal",{"_index":104,"t":{"198":{"position":[[4,7]]}}}],["integr",{"_index":50,"t":{"78":{"position":[[19,11]]},"202":{"position":[[4,9]]}}}],["intern",{"_index":228,"t":{"549":{"position":[[0,9]]}}}],["intersect",{"_index":178,"t":{"370":{"position":[[4,12]]}}}],["introduc",{"_index":274,"t":{"728":{"position":[[4,9]]}}}],["introduct",{"_index":239,"t":{"595":{"position":[[0,12]]}}}],["ip",{"_index":316,"t":{"1022":{"position":[[14,2]]}}}],["issu",{"_index":259,"t":{"644":{"position":[[0,5]]}}}],["iter",{"_index":246,"t":{"609":{"position":[[4,7]]}}}],["java",{"_index":32,"t":{"42":{"position":[[15,4]]}}}],["json",{"_index":96,"t":{"178":{"position":[[0,4]]}}}],["key",{"_index":146,"t":{"280":{"position":[[11,3]]},"308":{"position":[[11,3]]},"422":{"position":[[13,3]]},"633":{"position":[[0,3]]}}}],["kubecon",{"_index":22,"t":{"30":{"position":[[0,7]]},"38":{"position":[[0,7]]},"56":{"position":[[0,7]]},"74":{"position":[[0,7]]}}}],["languag",{"_index":18,"t":{"26":{"position":[[0,8]]},"86":{"position":[[0,8]]},"360":{"position":[[28,8]]},"579":{"position":[[25,8]]}}}],["limit",{"_index":134,"t":{"260":{"position":[[12,6]]},"540":{"position":[[0,11]]}}}],["line",{"_index":139,"t":{"270":{"position":[[14,4]]}}}],["linux",{"_index":114,"t":{"210":{"position":[[0,5]]}}}],["list",{"_index":129,"t":{"252":{"position":[[12,4]]},"410":{"position":[[10,4]]},"478":{"position":[[18,4]]},"601":{"position":[[4,4]]},"603":{"position":[[4,4]]},"684":{"position":[[6,4]]}}}],["listobject",{"_index":286,"t":{"822":{"position":[[0,11]]}}}],["local",{"_index":206,"t":{"476":{"position":[[18,5]]}}}],["log",{"_index":155,"t":{"296":{"position":[[0,7]]}}}],["longer",{"_index":281,"t":{"773":{"position":[[33,6]]},"789":{"position":[[53,6]]}}}],["look",{"_index":171,"t":{"360":{"position":[[37,4]]}}}],["manag",{"_index":279,"t":{"766":{"position":[[0,8]]}}}],["manual",{"_index":121,"t":{"216":{"position":[[0,8]]}}}],["mastodon",{"_index":69,"t":{"127":{"position":[[0,8]]}}}],["meet",{"_index":71,"t":{"129":{"position":[[18,8]]}}}],["member",{"_index":252,"t":{"625":{"position":[[59,7]]},"730":{"position":[[17,7]]},"732":{"position":[[20,7]]},"773":{"position":[[23,6]]},"1004":{"position":[[29,7]]}}}],["member'",{"_index":200,"t":{"466":{"position":[[27,8]]},"734":{"position":[[27,8]]}}}],["membership",{"_index":280,"t":{"771":{"position":[[19,10]]}}}],["metric",{"_index":153,"t":{"292":{"position":[[0,7]]}}}],["migrat",{"_index":299,"t":{"908":{"position":[[4,7]]}}}],["model",{"_index":35,"t":{"46":{"position":[[8,6]]},"172":{"position":[[24,5]]},"222":{"position":[[30,6]]},"224":{"position":[[27,5]]},"226":{"position":[[40,5]]},"332":{"position":[[29,5]]},"384":{"position":[[25,6]]},"457":{"position":[[0,8]]},"498":{"position":[[0,8]]},"515":{"position":[[0,8]]},"521":{"position":[[15,5]]},"530":{"position":[[23,6]]},"573":{"position":[[8,5]]},"575":{"position":[[0,8]]},"577":{"position":[[0,8]]},"583":{"position":[[29,5]]},"589":{"position":[[34,5]]},"595":{"position":[[16,8]]},"597":{"position":[[37,6]]},"607":{"position":[[13,5]]},"617":{"position":[[0,8]]},"619":{"position":[[0,8]]},"652":{"position":[[12,5]]},"664":{"position":[[29,5]]},"678":{"position":[[11,5]]},"728":{"position":[[57,5]]},"748":{"position":[[25,5]]},"764":{"position":[[0,8]]},"781":{"position":[[0,8]]},"787":{"position":[[15,5]]},"789":{"position":[[15,5]]},"837":{"position":[[0,8]]},"850":{"position":[[25,5]]},"904":{"position":[[34,5]]},"910":{"position":[[42,5]]},"942":{"position":[[17,8]]},"948":{"position":[[0,8]]},"950":{"position":[[24,5]]},"954":{"position":[[31,5]]},"956":{"position":[[4,8]]},"970":{"position":[[17,8]]},"976":{"position":[[0,8]]},"977":{"position":[[39,5]]},"981":{"position":[[31,5]]},"991":{"position":[[17,8]]},"997":{"position":[[0,8]]},"1038":{"position":[[17,8]]},"1044":{"position":[[0,8]]},"1061":{"position":[[17,8]]},"1067":{"position":[[0,8]]},"1071":{"position":[[41,5]]},"1073":{"position":[[31,5]]}}}],["modifi",{"_index":216,"t":{"521":{"position":[[4,6]]},"748":{"position":[[4,6]]},"787":{"position":[[4,6]]},"789":{"position":[[4,6]]}}}],["modul",{"_index":257,"t":{"636":{"position":[[0,7]]}}}],["modular",{"_index":34,"t":{"46":{"position":[[0,7]]}}}],["month",{"_index":27,"t":{"34":{"position":[[13,6]]},"52":{"position":[[13,6]]},"68":{"position":[[13,6]]},"94":{"position":[[13,6]]},"116":{"position":[[13,6]]}}}],["monthli",{"_index":70,"t":{"129":{"position":[[0,7]]}}}],["multipl",{"_index":215,"t":{"505":{"position":[[11,8]]}}}],["mysql",{"_index":143,"t":{"276":{"position":[[0,5]]},"306":{"position":[[6,5]]}}}],["new",{"_index":7,"t":{"14":{"position":[[5,4]]},"48":{"position":[[10,4]]},"60":{"position":[[0,3]]},"62":{"position":[[10,4]]},"64":{"position":[[0,3]]},"72":{"position":[[5,4]]},"106":{"position":[[0,3]]},"350":{"position":[[29,3]]},"668":{"position":[[13,3]]},"670":{"position":[[13,3]]},"906":{"position":[[13,3]]}}}],["next",{"_index":3,"t":{"8":{"position":[[7,5]]},"34":{"position":[[8,4]]},"52":{"position":[[8,4]]},"68":{"position":[[8,4]]},"90":{"position":[[7,5]]},"94":{"position":[[8,4]]},"100":{"position":[[7,5]]},"112":{"position":[[7,4]]},"116":{"position":[[8,4]]},"152":{"position":[[7,5]]}}}],["object",{"_index":130,"t":{"252":{"position":[[17,7]]},"364":{"position":[[40,6]]},"366":{"position":[[33,7]]},"388":{"position":[[11,7]]},"410":{"position":[[15,7]]},"449":{"position":[[24,6]]},"451":{"position":[[31,6]]},"466":{"position":[[49,6]]},"577":{"position":[[9,6],[19,6]]},"601":{"position":[[13,6]]},"617":{"position":[[22,7]]},"684":{"position":[[11,7]]},"732":{"position":[[45,6]]},"734":{"position":[[49,6]]},"750":{"position":[[53,6]]},"752":{"position":[[44,6]]},"848":{"position":[[9,6],[19,6]]},"850":{"position":[[36,6],[46,6]]}}}],["obsolet",{"_index":300,"t":{"910":{"position":[[11,8]]}}}],["oidc",{"_index":147,"t":{"282":{"position":[[0,4]]},"310":{"position":[[0,4]]}}}],["openfga",{"_index":11,"t":{"16":{"position":[[33,7]]},"18":{"position":[[10,7]]},"20":{"position":[[12,7]]},"22":{"position":[[0,7]]},"32":{"position":[[0,7]]},"42":{"position":[[0,7]]},"76":{"position":[[0,7]]},"82":{"position":[[0,7]]},"92":{"position":[[0,7]]},"108":{"position":[[0,7]]},"110":{"position":[[0,7]]},"202":{"position":[[18,7]]},"238":{"position":[[18,7]]},"250":{"position":[[18,7]]},"348":{"position":[[18,7]]},"432":{"position":[[0,7]]},"447":{"position":[[18,7]]},"459":{"position":[[0,7]]},"500":{"position":[[0,7]]},"517":{"position":[[0,7]]},"557":{"position":[[0,7]]},"621":{"position":[[0,7]]},"660":{"position":[[0,7]]},"708":{"position":[[0,7]]},"724":{"position":[[0,7]]},"744":{"position":[[0,7]]},"768":{"position":[[0,7]]},"783":{"position":[[0,7]]},"801":{"position":[[0,7]]},"839":{"position":[[0,7]]},"866":{"position":[[0,7]]},"884":{"position":[[0,7]]},"918":{"position":[[0,7]]},"940":{"position":[[0,7]]},"968":{"position":[[0,7]]},"989":{"position":[[0,7]]},"1012":{"position":[[0,7]]},"1036":{"position":[[0,7]]},"1059":{"position":[[0,7]]}}}],["oper",{"_index":90,"t":{"170":{"position":[[6,10]]},"368":{"position":[[10,8]]},"370":{"position":[[17,8]]},"372":{"position":[[14,8]]}}}],["option",{"_index":201,"t":{"472":{"position":[[9,7]]},"474":{"position":[[0,6]]},"476":{"position":[[0,6]]},"478":{"position":[[0,6]]},"480":{"position":[[18,6]]}}}],["org",{"_index":314,"t":{"998":{"position":[[38,3]]},"1000":{"position":[[32,3]]},"1002":{"position":[[38,3]]},"1004":{"position":[[25,3]]}}}],["organ",{"_index":254,"t":{"625":{"position":[[84,12]]},"928":{"position":[[5,12]]},"1047":{"position":[[4,12]]}}}],["out",{"_index":5,"t":{"10":{"position":[[6,4]]},"154":{"position":[[6,4]]}}}],["overview",{"_index":219,"t":{"528":{"position":[[0,8]]}}}],["ownership",{"_index":253,"t":{"625":{"position":[[74,9]]}}}],["packag",{"_index":118,"t":{"210":{"position":[[25,8]]}}}],["paramet",{"_index":225,"t":{"538":{"position":[[10,9]]}}}],["parent",{"_index":247,"t":{"617":{"position":[[9,6]]},"664":{"position":[[46,6]]},"670":{"position":[[71,6]]},"842":{"position":[[11,6]]},"844":{"position":[[8,6]]},"846":{"position":[[15,6]]}}}],["particular",{"_index":124,"t":{"224":{"position":[[16,10]]}}}],["pass",{"_index":125,"t":{"226":{"position":[[12,7]]}}}],["pattern",{"_index":213,"t":{"490":{"position":[[0,8]]}}}],["permiss",{"_index":232,"t":{"575":{"position":[[19,11]]},"587":{"position":[[41,11]]},"619":{"position":[[19,11]]},"846":{"position":[[35,11]]},"872":{"position":[[8,11]]},"874":{"position":[[34,11]]},"997":{"position":[[18,11]]},"998":{"position":[[4,11]]},"1000":{"position":[[4,11]]},"1002":{"position":[[4,11]]},"1004":{"position":[[9,11]]},"1044":{"position":[[24,11]]},"1045":{"position":[[15,11]]},"1047":{"position":[[17,11]]},"1049":{"position":[[11,10]]},"1069":{"position":[[15,11]]}}}],["person",{"_index":157,"t":{"330":{"position":[[13,8]]}}}],["pick",{"_index":241,"t":{"599":{"position":[[4,4]]}}}],["plan",{"_index":290,"t":{"856":{"position":[[19,4]]}}}],["playground",{"_index":165,"t":{"338":{"position":[[12,10]]},"340":{"position":[[14,10]]}}}],["polici",{"_index":81,"t":{"142":{"position":[[8,6]]}}}],["popul",{"_index":312,"t":{"979":{"position":[[4,10]]}}}],["port",{"_index":167,"t":{"338":{"position":[[38,4]]}}}],["possibl",{"_index":163,"t":{"332":{"position":[[47,8]]},"472":{"position":[[0,8]]}}}],["postgr",{"_index":142,"t":{"274":{"position":[[0,8]]},"304":{"position":[[6,8]]}}}],["potenti",{"_index":126,"t":{"228":{"position":[[0,9]]}}}],["pprof",{"_index":149,"t":{"284":{"position":[[9,7]]}}}],["pre",{"_index":144,"t":{"280":{"position":[[0,3]]},"308":{"position":[[0,3]]}}}],["process",{"_index":240,"t":{"597":{"position":[[2,7]]}}}],["profil",{"_index":148,"t":{"284":{"position":[[0,8]]},"312":{"position":[[9,9]]}}}],["propag",{"_index":322,"t":{"1049":{"position":[[22,11]]}}}],["public",{"_index":189,"t":{"414":{"position":[[19,6]]},"498":{"position":[[9,6]]}}}],["publicli",{"_index":323,"t":{"1051":{"position":[[30,8]]}}}],["put",{"_index":262,"t":{"650":{"position":[[0,7]]}}}],["queri",{"_index":221,"t":{"534":{"position":[[0,7]]}}}],["reach",{"_index":4,"t":{"10":{"position":[[0,5]]},"154":{"position":[[0,5]]}}}],["read",{"_index":285,"t":{"810":{"position":[[0,4]]}}}],["recommend",{"_index":132,"t":{"258":{"position":[[9,15]]}}}],["referenc",{"_index":175,"t":{"364":{"position":[[0,11]]},"366":{"position":[[0,11]]}}}],["relat",{"_index":86,"t":{"164":{"position":[[0,7]]},"186":{"position":[[0,7]]},"204":{"position":[[0,7]]},"218":{"position":[[0,7]]},"230":{"position":[[0,7]]},"242":{"position":[[0,7]]},"254":{"position":[[0,7]]},"262":{"position":[[0,7]]},"298":{"position":[[0,7]]},"314":{"position":[[0,7]]},"322":{"position":[[0,7]]},"334":{"position":[[0,7]]},"354":{"position":[[0,7]]},"364":{"position":[[18,9]]},"366":{"position":[[12,9],[25,7]]},"376":{"position":[[0,7]]},"392":{"position":[[10,9]]},"394":{"position":[[10,8]]},"396":{"position":[[19,7]]},"416":{"position":[[0,7]]},"439":{"position":[[0,7]]},"468":{"position":[[0,7]]},"505":{"position":[[20,7]]},"507":{"position":[[0,7]]},"525":{"position":[[0,7]]},"551":{"position":[[0,7]]},"565":{"position":[[0,7]]},"591":{"position":[[0,7]]},"603":{"position":[[9,9]]},"605":{"position":[[11,9]]},"611":{"position":[[0,7]]},"625":{"position":[[19,8]]},"629":{"position":[[0,7]]},"666":{"position":[[22,8]]},"674":{"position":[[0,7]]},"690":{"position":[[0,7]]},"700":{"position":[[0,7]]},"716":{"position":[[0,7]]},"732":{"position":[[30,8]]},"736":{"position":[[0,7]]},"758":{"position":[[0,7]]},"775":{"position":[[0,7]]},"793":{"position":[[0,7]]},"831":{"position":[[0,7]]},"842":{"position":[[18,9]]},"858":{"position":[[0,7]]},"876":{"position":[[0,7]]},"896":{"position":[[0,7]]},"912":{"position":[[0,7]]},"930":{"position":[[34,7]]},"934":{"position":[[0,7]]},"1024":{"position":[[34,7]]},"1030":{"position":[[0,7]]},"1053":{"position":[[0,7]]},"1071":{"position":[[60,9]]}}}],["relationship",{"_index":82,"t":{"144":{"position":[[8,12]]},"350":{"position":[[33,12]]},"352":{"position":[[32,12]]},"362":{"position":[[7,12]]},"400":{"position":[[10,12]]},"402":{"position":[[22,12]]},"404":{"position":[[10,13]]},"406":{"position":[[28,14]]},"435":{"position":[[18,12]]},"437":{"position":[[20,12]]},"503":{"position":[[24,12]]},"505":{"position":[[28,12]]},"532":{"position":[[20,12]]},"561":{"position":[[13,12]]},"563":{"position":[[19,12]]},"577":{"position":[[26,13]]},"585":{"position":[[7,12]]},"587":{"position":[[8,12]]},"664":{"position":[[53,12]]},"668":{"position":[[17,12]]},"670":{"position":[[17,12]]},"696":{"position":[[39,13]]},"712":{"position":[[13,12]]},"714":{"position":[[19,12]]},"750":{"position":[[11,12]]},"752":{"position":[[11,12]]},"844":{"position":[[15,12]]},"848":{"position":[[26,13]]},"850":{"position":[[53,13]]},"852":{"position":[[11,12]]},"854":{"position":[[53,12]]},"886":{"position":[[16,14]]},"888":{"position":[[25,13]]},"892":{"position":[[15,13]]},"894":{"position":[[15,13]]},"906":{"position":[[17,12]]},"908":{"position":[[25,12]]},"910":{"position":[[20,12]]},"926":{"position":[[11,13]]},"952":{"position":[[19,12]]},"958":{"position":[[20,13]]},"977":{"position":[[49,12]]},"979":{"position":[[19,12]]},"1020":{"position":[[11,13]]}}}],["releas",{"_index":45,"t":{"64":{"position":[[4,8]]},"106":{"position":[[4,9]]}}}],["remov",{"_index":193,"t":{"437":{"position":[[4,8]]},"503":{"position":[[15,8]]},"910":{"position":[[4,6]]}}}],["request",{"_index":186,"t":{"408":{"position":[[16,8]]},"410":{"position":[[23,8]]},"545":{"position":[[13,8]]},"547":{"position":[[14,8]]}}}],["requir",{"_index":302,"t":{"922":{"position":[[0,12]]},"944":{"position":[[0,12]]},"972":{"position":[[0,12]]},"993":{"position":[[0,12]]},"1016":{"position":[[0,12]]},"1040":{"position":[[0,12]]},"1063":{"position":[[0,12]]}}}],["restrict",{"_index":174,"t":{"362":{"position":[[25,12]]}}}],["revok",{"_index":278,"t":{"756":{"position":[[4,8]]},"771":{"position":[[4,8]]},"773":{"position":[[15,7]]}}}],["rfc",{"_index":58,"t":{"90":{"position":[[23,5]]}}}],["role",{"_index":76,"t":{"138":{"position":[[8,4]]},"575":{"position":[[9,5]]},"583":{"position":[[44,4]]},"585":{"position":[[51,5]]},"587":{"position":[[62,5]]},"619":{"position":[[9,5]]},"870":{"position":[[19,5]]},"874":{"position":[[18,5]]}}}],["rpm",{"_index":116,"t":{"210":{"position":[[12,3]]}}}],["run",{"_index":164,"t":{"338":{"position":[[0,7]]},"686":{"position":[[0,7]]},"688":{"position":[[0,7]]}}}],["same",{"_index":176,"t":{"364":{"position":[[35,4]]},"503":{"position":[[51,4]]},"505":{"position":[[55,4]]}}}],["scenario",{"_index":301,"t":{"920":{"position":[[0,8]]},"946":{"position":[[8,9]]},"974":{"position":[[8,9]]},"995":{"position":[[8,9]]},"1014":{"position":[[0,8]]},"1042":{"position":[[8,9]]},"1065":{"position":[[8,9]]}}}],["sdk",{"_index":16,"t":{"24":{"position":[[0,3]]},"44":{"position":[[0,3]]},"84":{"position":[[0,3]]}}}],["search",{"_index":203,"t":{"474":{"position":[[10,7]]},"476":{"position":[[53,7]]},"478":{"position":[[36,6]]}}}],["section",{"_index":87,"t":{"164":{"position":[[8,8]]},"186":{"position":[[8,8]]},"204":{"position":[[8,8]]},"218":{"position":[[8,8]]},"230":{"position":[[8,8]]},"242":{"position":[[8,8]]},"254":{"position":[[8,8]]},"262":{"position":[[8,8]]},"298":{"position":[[8,8]]},"314":{"position":[[8,8]]},"322":{"position":[[8,8]]},"334":{"position":[[8,8]]},"354":{"position":[[8,8]]},"376":{"position":[[8,8]]},"416":{"position":[[8,8]]},"439":{"position":[[8,8]]},"468":{"position":[[8,8]]},"507":{"position":[[8,8]]},"525":{"position":[[8,8]]},"551":{"position":[[8,8]]},"565":{"position":[[8,8]]},"591":{"position":[[8,8]]},"611":{"position":[[8,8]]},"629":{"position":[[8,8]]},"674":{"position":[[8,8]]},"690":{"position":[[8,8]]},"700":{"position":[[8,8]]},"716":{"position":[[8,8]]},"736":{"position":[[8,8]]},"758":{"position":[[8,8]]},"775":{"position":[[8,8]]},"793":{"position":[[8,8]]},"831":{"position":[[8,8]]},"858":{"position":[[8,8]]},"876":{"position":[[8,8]]},"896":{"position":[[8,8]]},"912":{"position":[[8,8]]},"934":{"position":[[8,8]]},"1030":{"position":[[8,8]]},"1053":{"position":[[8,8]]}}}],["secur",{"_index":62,"t":{"110":{"position":[[8,8]]}}}],["see",{"_index":26,"t":{"34":{"position":[[0,3]]},"52":{"position":[[0,3]]},"68":{"position":[[0,3]]},"94":{"position":[[0,3]]},"116":{"position":[[0,3]]},"672":{"position":[[13,3]]},"854":{"position":[[13,3]]}}}],["servic",{"_index":112,"t":{"202":{"position":[[45,7]]},"1028":{"position":[[37,7]]}}}],["session",{"_index":47,"t":{"76":{"position":[[22,8]]}}}],["setup",{"_index":105,"t":{"198":{"position":[[16,5]]}}}],["share",{"_index":145,"t":{"280":{"position":[[4,6]]},"308":{"position":[[4,6]]},"422":{"position":[[6,6]]},"1051":{"position":[[4,7]]}}}],["slack",{"_index":39,"t":{"50":{"position":[[37,5]]},"66":{"position":[[37,5]]},"114":{"position":[[37,5]]},"119":{"position":[[0,5]]}}}],["solut",{"_index":255,"t":{"627":{"position":[[20,9]]},"791":{"position":[[15,8]]}}}],["specif",{"_index":195,"t":{"451":{"position":[[22,8]]}}}],["specifi",{"_index":161,"t":{"332":{"position":[[7,7]]}}}],["start",{"_index":102,"t":{"194":{"position":[[11,5]]},"234":{"position":[[11,5]]},"246":{"position":[[11,5]]},"318":{"position":[[11,5]]},"344":{"position":[[11,5]]},"428":{"position":[[11,5]]},"443":{"position":[[11,5]]},"455":{"position":[[11,5]]},"494":{"position":[[11,5]]},"513":{"position":[[11,5]]},"555":{"position":[[11,5]]},"571":{"position":[[11,5]]},"615":{"position":[[11,5]]},"656":{"position":[[11,5]]},"694":{"position":[[11,5]]},"704":{"position":[[11,5]]},"720":{"position":[[11,5]]},"740":{"position":[[11,5]]},"762":{"position":[[11,5]]},"779":{"position":[[11,5]]},"797":{"position":[[11,5]]},"835":{"position":[[11,5]]},"862":{"position":[[11,5]]},"880":{"position":[[11,5]]},"900":{"position":[[11,5]]},"916":{"position":[[11,5]]},"938":{"position":[[11,5]]},"966":{"position":[[11,5]]},"987":{"position":[[11,5]]},"1010":{"position":[[11,5]]},"1034":{"position":[[11,5]]},"1057":{"position":[[11,5]]}}}],["step",{"_index":100,"t":{"190":{"position":[[0,4],[8,4]]},"196":{"position":[[0,4],[8,4]]},"236":{"position":[[0,4],[8,4]]},"248":{"position":[[0,4],[8,4]]},"302":{"position":[[0,4],[8,4]]},"320":{"position":[[0,4],[8,4]]},"346":{"position":[[0,4],[8,4]]},"434":{"position":[[0,4],[8,4]]},"445":{"position":[[0,4],[8,4]]},"461":{"position":[[0,4],[8,4]]},"502":{"position":[[0,4],[8,4]]},"519":{"position":[[0,4],[8,4]]},"559":{"position":[[0,4],[8,4]]},"581":{"position":[[0,4],[8,4]]},"623":{"position":[[0,4],[8,4]]},"662":{"position":[[0,4],[8,4]]},"710":{"position":[[0,4],[8,4]]},"726":{"position":[[0,4],[8,4]]},"746":{"position":[[0,4],[8,4]]},"770":{"position":[[0,4],[8,4]]},"785":{"position":[[0,4],[8,4]]},"841":{"position":[[0,4],[8,4]]},"868":{"position":[[0,4],[8,4]]},"902":{"position":[[0,4],[8,4]]},"924":{"position":[[0,4],[8,4]]},"1018":{"position":[[0,4],[8,4]]},"1028":{"position":[[12,4]]}}}],["storag",{"_index":141,"t":{"272":{"position":[[17,7]]}}}],["store",{"_index":99,"t":{"184":{"position":[[7,6]]},"330":{"position":[[7,5]]},"386":{"position":[[10,6]]}}}],["studio",{"_index":49,"t":{"78":{"position":[[7,6]]}}}],["summari",{"_index":212,"t":{"482":{"position":[[0,7]]},"829":{"position":[[0,7]]},"932":{"position":[[0,7]]},"960":{"position":[[0,7]]},"983":{"position":[[0,7]]},"1006":{"position":[[0,7]]},"1026":{"position":[[0,7]]},"1075":{"position":[[0,7]]}}}],["super",{"_index":40,"t":{"56":{"position":[[24,5]]}}}],["support",{"_index":224,"t":{"538":{"position":[[0,9]]},"666":{"position":[[66,7]]}}}],["system",{"_index":295,"t":{"870":{"position":[[54,6]]},"890":{"position":[[20,6]]}}}],["take",{"_index":303,"t":{"928":{"position":[[0,4]]},"1022":{"position":[[0,4]]},"1028":{"position":[[0,6]]}}}],["target",{"_index":123,"t":{"224":{"position":[[7,6]]}}}],["team",{"_index":6,"t":{"14":{"position":[[0,4]]},"72":{"position":[[0,4]]},"728":{"position":[[31,4]]},"730":{"position":[[32,4]]},"732":{"position":[[15,4]]},"1000":{"position":[[20,5]]},"1002":{"position":[[26,5]]}}}],["telemetri",{"_index":152,"t":{"290":{"position":[[0,9]]}}}],["test",{"_index":244,"t":{"607":{"position":[[4,4]]},"680":{"position":[[6,5]]},"682":{"position":[[12,5]]},"684":{"position":[[19,5]]},"686":{"position":[[8,5]]},"688":{"position":[[8,5]]}}}],["those",{"_index":242,"t":{"603":{"position":[[23,5]]}}}],["tie",{"_index":235,"t":{"585":{"position":[[30,3]]}}}],["time",{"_index":315,"t":{"1022":{"position":[[5,4]]}}}],["togeth",{"_index":263,"t":{"650":{"position":[[15,8]]}}}],["token",{"_index":273,"t":{"696":{"position":[[27,7]]}}}],["trace",{"_index":154,"t":{"294":{"position":[[0,7]]}}}],["track",{"_index":260,"t":{"644":{"position":[[6,8]]}}}],["transact",{"_index":214,"t":{"503":{"position":[[56,11]]},"505":{"position":[[60,11]]}}}],["transit",{"_index":36,"t":{"50":{"position":[[0,13]]},"66":{"position":[[0,13]]},"114":{"position":[[0,13]]}}}],["trip",{"_index":293,"t":{"870":{"position":[[41,4]]}}}],["tupl",{"_index":94,"t":{"174":{"position":[[7,6]]},"182":{"position":[[7,6]]},"330":{"position":[[50,6]]},"350":{"position":[[46,6]]},"352":{"position":[[45,6]]},"400":{"position":[[23,6]]},"402":{"position":[[35,6]]},"412":{"position":[[20,7]]},"503":{"position":[[37,6]]},"505":{"position":[[41,6]]},"532":{"position":[[33,6]]},"561":{"position":[[26,5]]},"585":{"position":[[20,6]]},"587":{"position":[[21,6]]},"668":{"position":[[30,5]]},"670":{"position":[[30,5]]},"678":{"position":[[21,6]]},"712":{"position":[[26,5]]},"750":{"position":[[24,6]]},"752":{"position":[[24,6]]},"844":{"position":[[28,6]]},"852":{"position":[[24,6]]},"906":{"position":[[30,5]]},"908":{"position":[[38,6]]},"930":{"position":[[15,6]]},"952":{"position":[[32,6]]},"977":{"position":[[62,6]]},"979":{"position":[[32,6]]},"1024":{"position":[[15,6]]}}}],["twitter",{"_index":67,"t":{"123":{"position":[[12,8]]}}}],["type",{"_index":173,"t":{"362":{"position":[[20,4]]},"380":{"position":[[10,5]]},"382":{"position":[[10,4]]},"396":{"position":[[32,5]]},"414":{"position":[[8,4]]},"449":{"position":[[31,5]]},"451":{"position":[[38,4]]},"538":{"position":[[20,5]]},"583":{"position":[[49,4]]},"601":{"position":[[20,5]]},"603":{"position":[[29,5]]},"638":{"position":[[0,4]]},"666":{"position":[[47,4]]}}}],["understand",{"_index":291,"t":{"870":{"position":[[4,10]]},"926":{"position":[[0,10]]},"1020":{"position":[[0,10]]}}}],["union",{"_index":177,"t":{"368":{"position":[[4,5]]}}}],["updat",{"_index":233,"t":{"583":{"position":[[4,6]]},"664":{"position":[[4,6]]},"666":{"position":[[4,6]]},"954":{"position":[[4,8]]},"981":{"position":[[4,8]]},"1071":{"position":[[4,8]]},"1073":{"position":[[4,8]]}}}],["us",{"_index":0,"t":{"4":{"position":[[0,3]]},"6":{"position":[[7,3]]},"98":{"position":[[7,3]]},"150":{"position":[[7,3]]},"228":{"position":[[10,3]]},"266":{"position":[[0,5]]},"268":{"position":[[0,5]]},"270":{"position":[[0,5]]},"304":{"position":[[0,5]]},"306":{"position":[[0,5]]},"420":{"position":[[0,5]]},"422":{"position":[[0,5]]},"424":{"position":[[0,5]]},"488":{"position":[[0,3]]},"587":{"position":[[4,3]]},"688":{"position":[[14,5]]},"806":{"position":[[8,4]]},"808":{"position":[[24,3]]},"813":{"position":[[8,4]]},"815":{"position":[[24,3]]},"820":{"position":[[8,4]]},"825":{"position":[[8,4]]},"930":{"position":[[0,3]]},"1024":{"position":[[0,3]]}}}],["user",{"_index":108,"t":{"200":{"position":[[25,4]]},"390":{"position":[[10,5]]},"396":{"position":[[27,4]]},"457":{"position":[[9,4]]},"515":{"position":[[9,4]]},"585":{"position":[[38,5]]},"696":{"position":[[0,4]]},"730":{"position":[[8,5]]},"750":{"position":[[37,4]]},"754":{"position":[[15,4]]},"764":{"position":[[9,4]]},"781":{"position":[[9,4]]},"787":{"position":[[24,5]]},"789":{"position":[[24,5]]},"837":{"position":[[9,4]]},"874":{"position":[[13,4]]},"958":{"position":[[37,5]]}}}],["userset",{"_index":226,"t":{"543":{"position":[[10,8]]},"545":{"position":[[32,9]]},"547":{"position":[[33,9]]}}}],["v1.4",{"_index":15,"t":{"22":{"position":[[8,5]]}}}],["v1.4.3",{"_index":53,"t":{"82":{"position":[[8,6]]}}}],["valid",{"_index":277,"t":{"754":{"position":[[4,10]]},"773":{"position":[[4,10]]}}}],["variabl",{"_index":137,"t":{"268":{"position":[[18,9]]},"270":{"position":[[19,9]]}}}],["verifi",{"_index":238,"t":{"589":{"position":[[4,6]]},"627":{"position":[[4,6]]},"791":{"position":[[4,6]]}}}],["version",{"_index":92,"t":{"172":{"position":[[30,8]]}}}],["view",{"_index":122,"t":{"222":{"position":[[0,7]]},"652":{"position":[[0,7]]}}}],["viewer",{"_index":218,"t":{"521":{"position":[[40,6]]},"523":{"position":[[27,7]]}}}],["visual",{"_index":48,"t":{"78":{"position":[[0,6]]}}}],["vs",{"_index":19,"t":{"28":{"position":[[0,2]]}}}],["want",{"_index":59,"t":{"102":{"position":[[3,4]]}}}],["what'",{"_index":56,"t":{"90":{"position":[[0,6]]},"100":{"position":[[0,6]]},"112":{"position":[[0,6]]},"152":{"position":[[0,6]]}}}],["what’",{"_index":2,"t":{"8":{"position":[[0,6]]}}}],["whenev",{"_index":162,"t":{"332":{"position":[[38,8]]}}}],["wiki",{"_index":261,"t":{"646":{"position":[[0,4]]}}}],["within",{"_index":292,"t":{"870":{"position":[[30,6]]}}}],["without",{"_index":288,"t":{"854":{"position":[[38,7]]},"926":{"position":[[25,7]]},"1020":{"position":[[25,7]]}}}],["work",{"_index":91,"t":{"172":{"position":[[0,4]]},"545":{"position":[[22,4]]},"547":{"position":[[23,4]]},"589":{"position":[[40,5]]},"627":{"position":[[30,4]]},"791":{"position":[[24,5]]},"870":{"position":[[25,4]]}}}],["workspac",{"_index":324,"t":{"1067":{"position":[[9,10]]},"1071":{"position":[[17,9]]}}}],["write",{"_index":169,"t":{"350":{"position":[[12,5]]},"352":{"position":[[12,5]]},"532":{"position":[[0,7]]},"680":{"position":[[0,5]]},"682":{"position":[[0,5]]},"684":{"position":[[0,5]]},"950":{"position":[[4,7]]}}}],["writer",{"_index":251,"t":{"625":{"position":[[42,7]]}}}],["x",{"_index":65,"t":{"123":{"position":[[0,1]]}}}],["yaml",{"_index":95,"t":{"176":{"position":[[0,4]]}}}],["youtub",{"_index":68,"t":{"125":{"position":[[0,7]]}}}],["zanzibar",{"_index":83,"t":{"146":{"position":[[8,9]]},"374":{"position":[[11,8]]}}}]],"pipeline":["stemmer"]}},{"documents":[{"i":3,"t":"Relationship Tuples are the facts that the OpenFGA evaluates to determine whether a user is permitted to access a resource. The way tuples are considered when making authorization decisions in OpenFGA is guided by an authorization model, which employs concepts from Relationship-Based Access Control (ReBAC) to establish authorization policies. For instance, you might declare that users are allowed to view a document if they have permission to view its parent folder. Although ReBAC offers a highly flexible method for structuring permissions, it encounters difficulties with defining permissions based on attributes that are not easily represented as relationships. Attributes such as “parent folder,” “department,” “region,” and “country” can be conceptualized as relationships between two entities. However, attributes like “IP address,” “time of day,” “team size limit,” or “maximum amount for a bank transfer” cannot be easily handled. In our ongoing efforts to expand OpenFGA’s capacity for articulating a broader range of authorization policies, we are introducing Conditional Relationship Tuples. These allow for the specification of conditions under which a particular tuple is relevant when evaluating an authorization query. Consider the following example, where we utilize Conditional Tuples to grant access for a user over a specified time duration. We stipulate that a user may be granted either unconditional access or access constrained to a certain time period: model schema 1.1 type user type document relations define viewer: [user, user with non_expired_grant] condition non_expired_grant(current_time: timestamp, grant_time: timestamp, grant_duration: duration) { current_time < grant_time + grant_duration } If we write the following tuples: user relation object condition user:bob viewer document:1 user:anne viewer document:1 name : non_expired_grant, context : { grant_time : 2023-01-01T00:00:00Z, grant_duration : 1h } You'll get the following results for the Check operations below: user relation object context result user:bob viewer document:1 allowed : true user:anne viewer document:1 current_time : 2023-01-01T00:10:00Z allowed : true user:anne viewer document:1 current_time : 2023-01-01T02:00:00Z allowed : false user:anne viewer document:1 error : \"failed to evaluate relationship condition 'non_expired_grant': context is missing parameters '[current_time]' You'll get the following results for the ListObjects operations below: user relation object context result user:anne viewer document:1 current_time : 2023-01-01T00:10:00Z objects: [ \"document:1\"] user:anne viewer document:1 error: \"failed to evaluate relationship condition 'non_expired_grant': tuple 'document:1#viewer@user:anne' is missing context parameters '[current_time]' Note that: user:bob will always get allowed:true as we have assigned as viewer unconditionally. user:anne will get allowed:true if the current_time is before the grant_time + grant_duration and allowed:false otherwise. If you don't provide the current_time in the context, the Check and ListObjects operations will fail.","s":"Conditional Relationship Tuples for OpenFGA","u":"/pr-preview/pr-728/blog/conditional-tuples-announcement","h":"","p":2},{"i":5,"t":"The OpenFGA Sample Stores repository has several examples that take advantage of this new feature: Granting access during a specific period of time (the use case explained above). Allow access based on the user’s IP Address. Granting access based on group membership and resource attributes. Allow access to specific features based on usage. Determine if a user can make a bank transfer based .on the transaction amount. Data types and operations supported in conditions.","s":"Use Cases","u":"/pr-preview/pr-728/blog/conditional-tuples-announcement","h":"#use-cases","p":2},{"i":7,"t":"Conditional Relationship Tuples are included in OpenFGA 1.4.0-rc1 version. You can run it by pulling it from docker: docker pull openfga/openfga:v1.4.0-rc1 docker run -p 8080:8080 -p 8081:8081 -p 3000:3000 openfga/openfga:v1.4.0-rc1 run` OpenFGA has a rich ecosystem of developer tools. The following have been updated to support Conditional Relationship Tuples: Visual Studio Code integration which provides syntax highlighting and model validations for conditions. Beta versions of the Javascript SDK and the Go SDK, which allows using the additional parameters. The OpenFGA CLI allows validating models and runing tests that use conditional tuples. You can use it to test the new features by pointing to a “.fga.yaml” file that defines the tests you want to run, without having to deploy OpenFGA.","s":"How to use it?","u":"/pr-preview/pr-728/blog/conditional-tuples-announcement","h":"#how-to-use-it","p":2},{"i":9,"t":"We’ll address some limitations of the current implementation: The Expand API does not consider conditions. The Visual Studio Code integration is not validating the expressions in conditions. The Playground does not let you add context for tuples and assertions. You should use the VS Code Extension + the FGA CLI to test your models for now. We'll also improve ListObjects scenarios when it's called with missing context. For example, consider the following model that enables access only to documents with a specific status: model schema 1.1 type user type document relations define can_access: [user with docs_in_draft_status] condition docs_in_draft_status(status: string) { status == \"draft\" } If you want to list all the documents a user can view, you'll need to know the status of all of those documents. Given you don't know the documents the user has access too, you can't send the status of those as a parameter to ListObjects. Our goal is to return a structure that you can use to filter documents on your side, similar to: (document.id = ‘1’ and document.status = ‘draft’) or (document.id = ‘2’ and.status = draft) This won’t scale to a large number of documents, but would be useful in some scenarios.","s":"What’s Next?","u":"/pr-preview/pr-728/blog/conditional-tuples-announcement","h":"#whats-next","p":2},{"i":11,"t":"We want to learn how you use this feature and how we can improve it! Please reach out through our community channels with any questions or feedback.","s":"Reach out!","u":"/pr-preview/pr-728/blog/conditional-tuples-announcement","h":"#reach-out","p":2},{"i":13,"t":"Hi Everyone! We've been publishing a monthly internal newsletter we called Fine Grained News since the beginning on 2023, and we just thought it would be a good idea to share it with the community. Yeah, we are slow thinkers! You can expect to find here a summary of what we've been up to, what we are planning to do, and some other random stuff we think you might find interesting.","s":"Fine Grained News - December 2023","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"","p":12},{"i":15,"t":"We always start our Monthly Community Meetings presenting the team. If you attended the last one, you've seen that the size of the team has grown quite a bit! We are pretty excited about the impact it will have in OpenFGA and the authorization space in general.","s":"Team News","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"#team-news","p":12},{"i":17,"t":"In our last Community Meeting, the Agicap team (Pauline and Yann) demoed how they are using OpenFGA to implement Behavior Driven Development (BDD) in their authorization system. The screenshot below might be enough to understand what they are doing, but if you want to know more, you can watch the full presentation here.","s":"Behavior Driven Development with OpenFGA","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"#behavior-driven-development-with-openfga","p":12},{"i":19,"t":"GoDaddy has been working with OpenFGA for a few months. They just published a document explaining why they picked OpenFGA, and how they used to address the authorization challenges they were facing. Some interesting tidbits: They implemented their own DynamoDB Storage Adapter, as they were heavy Dynamo DB users and liked the eventual consistency model it provided. They needed Contextual Tuples to fully support their use case. Read the full article here.","s":"GoDaddy & OpenFGA","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"#godaddy--openfga","p":12},{"i":21,"t":"Canonical has also been working with OpenFGA for a while, and it's adding OpenFGA to different layers in their stack. They just announced that OpenFGA support is included in LXD and MicroCloud. Pretty soon, if you are using Ubuntu Pro, you will be using OpenFGA :).","s":"Canonical & OpenFGA","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"#canonical--openfga","p":12},{"i":23,"t":"Last week we released OpenFGA v1.4! This release includes our support for Conditional Relationship Tuples, which helps implementing additional Attribute-Based Access Control scenarios like temporal access, IP based access, bank transfer limits, SaaS application plans, and much more! You can read more about it here.","s":"OpenFGA v1.4!","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"#openfga-v14","p":12},{"i":25,"t":"The Java SDK has now feature parity with the rest of the our SDKs. It can be used from any language for the Java VM. You can see examples on Kotlin, Groovy and Scala here. The Python SDK was updated to support synchronous clients, support custom SSL certificates, and better performance in batch checks.","s":"SDK Improvements","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"#sdk-improvements","p":12},{"i":27,"t":"We've been working on the OpenFGA language with some long-due improvements. Soon, you'll be able to use parentheses to group expressions when defining relations: The syntax is still not supported in the FGA CLI, but we are pretty close. Daniel demoed it in our latest community meeting, you can see the full demo here.","s":"Language Improvements","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"#language-improvements","p":12},{"i":29,"t":"We have also been improving tuple validation when writing fga.yaml files, and it's pretty cool! Works on Daniel's machine for now :). Daniel also demoed it in our latest community meeting, watch it here.","s":"VS Code Extension Improvements","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"#vs-code-extension-improvements","p":12},{"i":31,"t":"We are getting ready for KubeCon Europe 2024, in Paris. We'll have a Project Kiosk, and we have submitted a few talks. We'll keep you posted!","s":"KubeCon EU 2024","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"#kubecon-eu-2024","p":12},{"i":33,"t":"We have a very welcoming community, and we'd love to have you there! You can join us in different ways: Join our community meetings, the second Thursday of every month. All the recordings are here. Join our community channels in Slack or GitHub. Stay up to date by following us on X. Ask questions, submit ideas, or just say hi in our GitHub Discussions.","s":"OpenFGA Community","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"#openfga-community","p":12},{"i":35,"t":"We'll keep publishing our Fine Grained News each month, after the OpenFGA community meeting. If you have any feedback, you want to share your OpenFGA story, or know about something that you think is worth mentioning, please let us know!","s":"See you next month!","u":"/pr-preview/pr-728/blog/fine-grained-news-2023-12","h":"#see-you-next-month","p":12},{"i":37,"t":"Welcome to the 3rd edition of Fine Grained News!","s":"Fine Grained News - February 2024","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-02","h":"","p":36},{"i":39,"t":"We'll be pretty busy during KubeCon Europe 2024: Jonathan Whitaker from Okta will talk about Federated IAM for Kubernetes with OpenFGA Pauline Jamin from Agicap and Andres Aguiar from Okta will present on Implementing Modern Cloud Native Authorization Using OpenFGA OpenFGA will be present in Canonical's Operator's day, co-located at KubeCon EU. Andres Aguiar and Massimilano Gori from Canonical, will talk about how Canonical adopted OpenFGA for implementing authorization in Juju. Andres Aguiar will also be delivering a Lightning Talk titled OpenFGA - The Cloud Native way to implement Fine Grained Authorization (link not available yet :) ). We'll also have a kiosk in the CNCF Project Pavilion, so if you plan to attend let us know and we can schedule some time together!","s":"KubeCon Europe 2024 is getting closer!","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-02","h":"#kubecon-europe-2024-is-getting-closer","p":36},{"i":41,"t":"We keep improving our documentation, and added a few new documents that you might find interesting: Learn how to use the FGA CLI to perform every possible operation on OpenFGA and simplify most common workflows. Learn how you can test FGA models as part of your development flow or CI/CD pipelines, without the need to run an OpenFGA server. Learn how you can include identity token claims contextual tuples to model ABAC-like scenarios or simplify data integrations with OpenFGA.","s":"Documentation Improvements","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-02","h":"#documentation-improvements","p":36},{"i":43,"t":"OpenFGA is getting bigger on the Java world! We are working with the Spring Security team to build an Spring Security integration for OpenFGA. You can check the ideas we are exploring in this repository. Also, the Testcontainers team added an OpenFGA integration for Java to make it simple to write integration tests for applications using OpenFGA. We'd love to hear your feedback!","s":"OpenFGA in the Java Ecosystem","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-02","h":"#openfga-in-the-java-ecosystem","p":36},{"i":45,"t":"New releases with bug fixes and improvements: Javascript SDK 0.3.3. Go SDK v0.3.5 Python SDK v0.4.1","s":"SDK Improvements","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-02","h":"#sdk-improvements","p":36},{"i":47,"t":"We wrapped up the RFC for Modular Models, which will enable multiple teams to work on different parts of the model independently and we are now working on the implementation. We'd love feedback on the RFC. Wait for a demo on our next Community Meeting!","s":"Modular Models","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-02","h":"#modular-models","p":36},{"i":49,"t":"Learn how stacklok is using OpenFGA to implement authorization in Minder, an open source project that makes it easier to apply and automate the enforcement of security checks and policies across multiple GitHub repositories. Check this OpenFGA tutorial by Alberto Coronado (in Spanish!). Raghd Hamzeh joined Whitney Lee in an in-depth Tanzu ⚡️Enlightning session about OpenFGA.","s":"Community News","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-02","h":"#community-news","p":36},{"i":51,"t":"As you may know, we've been using Discord for the OpenFGA community. We’ll transition it to the CNCF OpenFGA Slack channel. If you are not part of the CNCF Slack workspace, you need to join the CNCF Slack first.","s":"Transitioning from Discord to CNCF's Slack","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-02","h":"#transitioning-from-discord-to-cncfs-slack","p":36},{"i":53,"t":"Fine Grained News are published every month, after the OpenFGA community meeting. If you have any feedback, you want to share your OpenFGA story, or know about something that you think is worth mentioning, please let us know!","s":"See you next month!","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-02","h":"#see-you-next-month","p":36},{"i":55,"t":"Welcome to Fine Grained News, KubeCon Edition!","s":"Fine Grained News - March 2024","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-03","h":"","p":54},{"i":57,"t":"You can now watch online: An AppDeveloperCon session about Implementing Modern Cloud Native Authorization Using OpenFGA where Pauline Jamin and Andres Aguiar go over how OpenFGA is helping Agicap to implement fine-grained authorization. A 7-min Lightning Talk about OpenFGA: The Cloud Native way to implement Fine Grained Authorization. Jonathan Whitaker's talk about Federated IAM for Kubernetes with OpenFGA, demoing how to use OpenFGA and KeyCloak to implement fine-grained authorization in a Kubernetes cluster, in ways it's not possible today, like giving access to a user for 90 seconds. We also participated in Canonical's Operator Day sharing how Canonical is using OpenFGA, but the presentation is not online yet. Also, thanks to everyone who stopped by the OpenFGA Kiosk in the Project Pavilion to share their feedback about the project or learn more about it!","s":"KubeCon Europe 2024 was super-busy!","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-03","h":"#kubecon-europe-2024-was-super-busy","p":54},{"i":59,"t":"As you may know, the CNCF has three stages for projects: Sandbox, Incubation, and Graduation. OpenFGA is currently a Sandbox project. We are very happy to announce that we just applied for Incubation! We are excited about this step and will keep you posted on the progress.","s":"CNCF incubation","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-03","h":"#cncf-incubation","p":54},{"i":61,"t":"The OpenFGA community maintains a list of products/projects/companies that are using OpenFGA in production. We'd like to thank thank the following adopters for adding themselves to the list in the last month: Instill AI Zuplo OpenObserve Datum If you are using OpenFGA in production, please consider adding your company/project to the list.","s":"New Adopters","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-03","h":"#new-adopters","p":54},{"i":63,"t":"Raghd Hamzeh represented OpenFGA in an episode on Authorizing Access within a series called \"You Choose - Choose Your Own Adventure: The Treacherous Trek to Security”. This episode was comparing OpenFGA with Hexa and Paralus. OpenFGA was the project viewers voted for as most interested in being featured in a demo. Sam Bellen published a Google Drive example using OpenFGA. It's a Next.js project, written in TypeScript and ready to deploy on Vercel. Philipp Wagner is working on a .NET example inspired by the Github model. Pauline Jamin and Geoffroy Braun will present about Infuser du métier dans les autorisations avec ReBAC at Devoxx France 2024 in April 17th.","s":"Community News","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-03","h":"#community-news","p":54},{"i":65,"t":"We just shipped a release candidate of Modular Models, that makes it easy for multiple teams to collaborate in a single OpenFGA model. It requires the following components: OpenFGA v.1.5.1 CLI v0.3.0 Visual Studio Code Extension v0.2.20 We also shipped new version of our SDKs with several fixes: Javascript SDK 0.3.5. Go SDK v0.3.5 Java SDK v0.4.0","s":"New Releases","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-03","h":"#new-releases","p":54},{"i":67,"t":"As we mentioned in the last edition, we transitioned out from Discord for OpenFGA and are now using the CNCF #openfga Slack channel. If you are not part of the CNCF Slack workspace, you need to join the CNCF Slack first.","s":"Transitioning from Discord to CNCF's Slack","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-03","h":"#transitioning-from-discord-to-cncfs-slack","p":54},{"i":69,"t":"Fine Grained News are published every month. If you have any feedback, want to share your OpenFGA story, or know about something that you think is worth mentioning, please let us know!","s":"See you next month!","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-03","h":"#see-you-next-month","p":54},{"i":71,"t":"Welcome to the 2nd edition of Fine Grained News!","s":"Fine Grained News - January 2024","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"","p":70},{"i":73,"t":"The OpenFGA team got bigger, and we met in person in Toronto for the first time! We got to know each other better, helped new team members to get familiar with the project, hacked some code, had some fun with ax throwing, and loved Toronto's weather!","s":"Team News","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#team-news","p":70},{"i":75,"t":"We got two presentations accepted in KubeCon Europe! Jonathan Whitaker from Okta will talk about Federated IAM for Kubernetes with OpenFGA Pauline Jamin from Agicap and Andres Aguiar from Okta will present on Implementing Modern Cloud Native Authorization Using OpenFGA We'll also have a Project Kiosk, so if you plan to attend let us know and we can schedule some time together!","s":"KubeCon Europe 2024!","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#kubecon-europe-2024","p":70},{"i":77,"t":"Our own Raghd Hamzeh will join Whitney Lee in a Tanzu ⚡️Enlightning session on February 8th at 9am PT. Join their Youtube stream here.","s":"OpenFGA ⚡️Enlightning Session!","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#openfga-️enlightning-session","p":70},{"i":79,"t":"We keep investing in improving our VS Code experience. The video below shows how, in addition to validating the model, we can validate the tuple content and the tests. We are identifying: Invalid object types, user types, and relations when defining tuples. Invalid object types, user types, and relations when defining tests. User id or object id that was not included in any tuple in check tests. This helps authoring/testing models, making the whole process less error prone and more fun!","s":"Visual Studio Code Integration Enhancements","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#visual-studio-code-integration-enhancements","p":70},{"i":81,"t":"We love the FGA CLI and we keep making it even better. We had a few of contributions from new team members and the community :). You can now import tuples from a CSV file. We supported JSON/YAML, but if you are exporting data from a database, producing to CSV is way simpler. You can take a .fga.yaml file with a model and tuples, and get it imported in OpenFGA. Added support for specifying an external tuple_file in .fga.yaml files. Added support for specifying a continuation_token when calling fga tuple changes. Support for configuring OAuth scopes to authenticate to OIDC servers. Check the updated documentation in our CLI repository Thanks to Yann D'Isanto for all your help on this!","s":"CLI improvements","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#cli-improvements","p":70},{"i":83,"t":"We just shipped OpenFGA v1.4.3, with performance improvements and one security issue fixed. We recommend everyone to upgrade to the latest release.","s":"OpenFGA v1.4.3","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#openfga-v143","p":70},{"i":85,"t":"New releases with bug fixes and improvements: Java SDK v0.3.2. If you are using the Java SDK please upgrade to this version. Go SDK v0.3.4 Python SDK v0.4.0, which has breaking changes. Thanks again to Yann D'Isanto for your help on the Java SDK!","s":"SDK Improvements","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#sdk-improvements","p":70},{"i":87,"t":"The DSL language now has better support for comments and mixed operator support, where you can use parentheses to group expressions when defining relations: It's available in the VS Code extension, the CLI and the Playground.","s":"Language Improvements","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#language-improvements","p":70},{"i":89,"t":"We shipped a couple of Github Actions that help you deploy FGA models, and run model tests as part of your CI/CD build. Find them here.","s":"Github Actions","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#github-actions","p":70},{"i":91,"t":"We've been discussing with the OpenFGA community a couple of RFCs that we are planning to implement in the next few weeks: Support for modular models. ListUsers API. Please take a look at them and let us know what you think!","s":"What's Next? Check our RFCs!","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#whats-next-check-our-rfcs","p":70},{"i":93,"t":"We have a very welcoming community, and we'd love to have you there! You can join us in different ways: Join our community meetings, the second Thursday of every month. All the recordings are here. Stay up to date by following us on X. Join our community channels in Slack or GitHub.","s":"OpenFGA Community","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#openfga-community","p":70},{"i":95,"t":"Fine Grained News are published every month, after the OpenFGA community meeting. If you have any feedback, you want to share your OpenFGA story, or know about something that you think is worth mentioning, please let us know!","s":"See you next month!","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-01","h":"#see-you-next-month","p":70},{"i":97,"t":"Today we are launching a new API for OpenFGA: ListUsers. This API will answer the question \"what users have relation X with object Y?\". This will be useful, for example, in UIs that want to display the list of users that a resource has been shared with, e.g. the \"share\" dialog in Google Docs. You can read more about this API here.","s":"List Users API","u":"/pr-preview/pr-728/blog/list-users-announcement","h":"","p":96},{"i":99,"t":"ListUsers is available in the latest Release Candidate version of OpenFGA: v1.5.4-rc1. To be able to call this API, you must turn on this flag on the server: --experimentals enable-list-users. Be sure to also check out the various configuration flags that were added to control its behavior. You can also call this API via the SDKs: Java v0.4.2 .NET v0.3.2 Go v0.3.6 Javascript v0.4.0","s":"How to use it?","u":"/pr-preview/pr-728/blog/list-users-announcement","h":"#how-to-use-it","p":96},{"i":101,"t":"Our next steps look as follows: Release candidate with experimental flag (now) Any bug fixes Stable release with experimental flag Any performance improvements Stable release without experimental flag","s":"What's next?","u":"/pr-preview/pr-728/blog/list-users-announcement","h":"#whats-next","p":96},{"i":103,"t":"We want to learn how you use this API and how we can improve it! Please reach out through our community channels with any questions or feedback.","s":"We want your feedback!","u":"/pr-preview/pr-728/blog/list-users-announcement","h":"#we-want-your-feedback","p":96},{"i":105,"t":"Welcome to Fine Grained News, April edition!","s":"Fine Grained News - April 2024","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-04","h":"","p":104},{"i":107,"t":"Modular Models is now part of the OpenFGA core, making it easy for multiple teams to collaborate on a single OpenFGA model. Check it out, we love the feature! :) Thanks to the help provided by the Spring Security team there's now a Spring Boot Starter for OpenFGA! We shipped an OpenFGA Release Candidate with a new ListUsers API, that can be enabled with an experimental flag. ListUsers allows you to retrieve all the users that have a specific relation with a resource, for example, all users that can view a document.","s":"New Releases!","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-04","h":"#new-releases","p":104},{"i":109,"t":"A few weeks ago we hosted a Hackathon where multiple team members experimented new ideas around OpenFGA. You'll need to wait until the next community meeting to learn more :).","s":"OpenFGA Hackathon","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-04","h":"#openfga-hackathon","p":104},{"i":111,"t":"We are working with the CNCF Tag-Security team on a joint security assessment, which is a step required to get accepted as a CNCF Incubation project.","s":"OpenFGA Security Assessment","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-04","h":"#openfga-security-assessment","p":104},{"i":113,"t":"In collaboration with Yann D'Isanto we are building a plugin for JetBrain's IDEs to allow syntax coloring and validation of OpenFGA models. Together with the Visual Studio Code integration and the Tree sitter grammar from Matouš Dzivjak OpenFGA will get great coverage for major IDEs and editors. We'll be instrumenting our SDKs to provide metrics / tracing and logging through OpenTelemetry APIs. We'll be adding additional consistency options for OpenFGA query APIs. We'll be working on adding authorization for OpenFGA APIs. Please check the items above and let us know if you have any feedback or idea.","s":"What's Next","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-04","h":"#whats-next","p":104},{"i":115,"t":"As we mentioned in the last edition, we transitioned out from Discord for OpenFGA and are now using the CNCF #openfga Slack channel. If you are not part of the CNCF Slack workspace, you need to join the CNCF Slack first.","s":"Transitioning from Discord to CNCF's Slack","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-04","h":"#transitioning-from-discord-to-cncfs-slack","p":104},{"i":117,"t":"Fine Grained News are published every month. If you have any feedback, want to share your OpenFGA story, or know about something that you think is worth mentioning, please let us know!","s":"See you next month!","u":"/pr-preview/pr-728/blog/fine-grained-news-2024-04","h":"#see-you-next-month","p":104},{"i":120,"t":"The OpenFGA community has a channel in the CNCF Slack. If you don't have access to the CNCF Slack you can request an invitation here. You can join the community in the #openfga channel.","s":"Slack (CNCF Community)","u":"/pr-preview/pr-728/docs/community","h":"#slack-cncf-community","p":118},{"i":122,"t":"You can also use GitHub discussions to ask questions and submit product ideas.","s":"GitHub Discussions","u":"/pr-preview/pr-728/docs/community","h":"#github-discussions","p":118},{"i":124,"t":"Follow us on X to get the latest updates on all things OpenFGA. @OpenFGA.","s":"X (formerly Twitter)","u":"/pr-preview/pr-728/docs/community","h":"#x-formerly-twitter","p":118},{"i":126,"t":"Subscribe to the OpenFGA YouTube Channel to see our latest videos and recordings.","s":"YouTube","u":"/pr-preview/pr-728/docs/community","h":"#youtube","p":118},{"i":128,"t":"For the Fediverse fans among you, follow us on Mastodon at @openfga@mastodon.social!","s":"Mastodon","u":"/pr-preview/pr-728/docs/community","h":"#mastodon","p":118},{"i":130,"t":"We hold a monthly community meeting on the second Thursday of every month @ 11am Eastern Time (US). Agenda Zoom Link Recordings of Previous Meetings Web Link | ics file Read more details here","s":"Monthly Community Meetings","u":"/pr-preview/pr-728/docs/community","h":"#monthly-community-meetings","p":118},{"i":132,"t":"As you'd expect, the OpenFGA team will be at KubeCon NA 2023 in Chicago, IL! We'll have a packed agenda for the week: Jonathan Whitaker and Lucas Käldström will be presenting in Could_Native Rejects on how to use OpenFGA to manage and extend authorization in Kubernetes. Learn more here. Maria Ines Parnisari and Andres Aguiar will be presenting in AppDeveloperCon about modernizing authorization for cloud native applications using OpenFGA. Learn more here. We'll host a Project Meeting on Monday 9.30 AM in the Hudson room at the Hilton Garden Inn. We'll share how the product is being used, demo the latests features like our new CLI, the VS Code Extension, Conditional Relationships, the Java SDK... and more! We'll be in the CNCF Project Pavilion during the afternoons. We'll host our OpenFGA community meeting directly from KubeCon on Thursday 9th at 3PM UTC (8AM PST/11AM EST). If you want to meet with the team outside of these events, please pick any spot that works for you in our calendar. See you in Chicago!","s":"Join the OpenFGA team at KubeCon NA 2023","u":"/pr-preview/pr-728/blog/kubecon-na-2023","h":"","p":131},{"i":135,"t":"Authentication ensures a user's identity. Authorization determines if a user can perform a certain action on a particular resource. For example, when you log in to Google, Authentication is the process of verifying that your username and password are correct. Authorization is the process of ensuring that you can access a given Google service or feature.","s":"Authentication and Authorization","u":"/pr-preview/pr-728/docs/authorization-concepts","h":"#authentication-and-authorization","p":133},{"i":137,"t":"Fine-Grained Authorization (FGA) implies the ability to grant specific users permission to perform certain actions in specific resources. Well-designed FGA systems allow you to manage permissions for millions of objects and users. These permissions can change rapidly as a system continually adds objects and updates access permissions for its users. A notable example of FGA is Google Drive: access can be granted either to documents or to folders, as well as to individual users or users as a group, and access rights regularly change as new documents are created and shared with specific users or groups.","s":"What is Fine-Grained Authorization?","u":"/pr-preview/pr-728/docs/authorization-concepts","h":"#what-is-fine-grained-authorization","p":133},{"i":139,"t":"In Role-Based Access Control (RBAC), permissions are assigned to users based on their role in a system. For example, a user needs the editor role to edit content. RBAC systems enable you to define users, groups, roles, and permissions, then store them in a centralized location. Applications access that information to make authorization decisions.","s":"What is Role-Based Access Control?","u":"/pr-preview/pr-728/docs/authorization-concepts","h":"#what-is-role-based-access-control","p":133},{"i":141,"t":"In Attribute-Based Access Control (ABAC), permissions are granted based on a set of attributes that a user or resource possesses. For example, a user assigned both marketing and manager attributes is entitled to publish and delete posts that have a marketing attribute. Applications implementing ABAC need to retrieve information stored in multiple data sources - like RBAC services, user directories, and application-specific data sources - to make authorization decisions.","s":"What is Attribute-Based Access Control?","u":"/pr-preview/pr-728/docs/authorization-concepts","h":"#what-is-attribute-based-access-control","p":133},{"i":143,"t":"Policy-Based Access Control (PBAC) is the ability to manage authorization policies in a centralized way that’s external to the application code. Most implementations of ABAC are also PBAC.","s":"What is Policy-Based Access Control?","u":"/pr-preview/pr-728/docs/authorization-concepts","h":"#what-is-policy-based-access-control","p":133},{"i":145,"t":"Relationship-Based Access Control (ReBAC) enables user access rules to be conditional on relations that a given user has with a given object and that object's relationship with other objects. For example, a given user can view a given document if the user has access to the document's parent folder. ReBAC is a superset of RBAC: you can fully implement RBAC with ReBAC. ReBAC also lets you natively solve for ABAC when attributes can be expressed in the form of relationships. For example ‘a user’s manager’, ‘the parent folder’, ‘the owner of a document’, ‘the user’s department’ can be defined as relationships. OpenFGA extends ReBAC by making it simpler to express additional ABAC scenarios using Conditions or Contextual Tuples. ReBAC can also be considered PBAC, as authorization policies are centralized.","s":"What is Relationship-Based Access Control?","u":"/pr-preview/pr-728/docs/authorization-concepts","h":"#what-is-relationship-based-access-control","p":133},{"i":147,"t":"Zanzibar is Google's global authorization system across Google's product suite. It’s based on ReBAC and uses object-relation-user tuples to store relationship data, then checks those relations for a match between a user and an object. For more information, see Zanzibar Academy. ReBAC systems based on Zanzibar store the data necessary to make authorization decisions in a centralized database. Applications only need to call an API to make authorization decisions. OpenFGA is an example of a Zanzibar-based authorization system. Learn about OpenFGA. OpenFGA Concepts Learn about the OpenFGA Concepts More Modeling: Getting Started Learn about how to get started with modeling your permission system in OpenFGA. More","s":"What is Zanzibar?","u":"/pr-preview/pr-728/docs/authorization-concepts","h":"#what-is-zanzibar","p":133},{"i":149,"t":"Modular models aims to improve the model authoring experience when multiple teams are maintaining a model, such as: A model can grow large and difficult to understand As more teams begin to contribute to a model, the ownership boundaries may not be clear and code review processes might not scale With modular models, a single model can be separated across multiple files allow grouping of types and conditions into modules. This means that a model can be organized more easily in terms of team or organizational structure. Used in conjunction with features such as GitHub, GitLab or Gitea's code owners, it should become easier to ensure the owners of a portion of your model are correctly assigned to review it.","s":"Modular Models","u":"/pr-preview/pr-728/blog/modular-models-announcement","h":"","p":148},{"i":151,"t":"Modular models is available in the latest version of OpenFGA. To use it you need to: Update to the v0.3.0 release of the CLI Update to v0.2.21 of the VS Code Extension Download v1.5.3 of OpenFGA Check out the modular models sample store in the sample-stores repo Review the documentation for this feature Check a demo video in Youtube","s":"How to use it?","u":"/pr-preview/pr-728/blog/modular-models-announcement","h":"#how-to-use-it","p":148},{"i":153,"t":"Looking beyond the near term, modular models allows us to implement additional API authorization options for OpenFGA.","s":"What's next?","u":"/pr-preview/pr-728/blog/modular-models-announcement","h":"#whats-next","p":148},{"i":155,"t":"We want to learn how you use this feature and how we can improve it! Please reach out through our community channels with any questions or feedback.","s":"Reach out!","u":"/pr-preview/pr-728/blog/modular-models-announcement","h":"#reach-out","p":148},{"i":157,"t":"Setup OpenFGA How to setup an OpenFGA server. Click to navigate Install SDK Client Install the SDK for the language of your choice. Click to navigate Create a Store Creating an OpenFGA entity that owns an authorization model and relationship tuples. Click to navigate Setup SDK Client for Store Configure the SDK client for your store. Click to navigate Configure Authorization Model Programmatically configure authorization model for an OpenFGA store. Click to navigate Update Relationship Tuples Programmatically write authorization data to an OpenFGA store. Click to navigate Perform a Check Programmatically perform an authorization check against an OpenFGA store. Click to navigate Perform a List Objects Request Programmatically perform a list objects request against an OpenFGA store. Click to navigate Integrate Within a Framework Integrate authorization checks with a framework. Click to navigate Immutable Authorization Models Learn how to take advantage of the immutable properties of Authorization Models in OpenFGA. Click to navigate Production Best Practices Best Practices of Running OpenFGA in Production Environment. Click to navigate Implementation Best Practices Best Practices of Managing Tuples and Invoking OpenFGA APIs. Click to navigate","s":"Content","u":"/pr-preview/pr-728/docs/getting-started","h":"","p":156},{"i":159,"t":"OpenFGA is a scalable open source authorization system for developers that allows implementing authorization for any kind of application and smoothly evolve as complexity increases over time. It is owned by the Cloud Native Foundation. Inspired by Google’s Zanzibar, Google’s internal authorization system, OpenFGA relies on Relationship-Based Access Control, which allows developers to easily implement Role-Based Access Control and provides additional capabilities to implement Attribute-Based Access Control. You can learn more about different authorization concepts here.","s":"Introduction to OpenFGA","u":"/pr-preview/pr-728/docs/fga","h":"","p":158},{"i":161,"t":"OpenFGA provides developer the following benefits: Move authorization logic outside of application code, making it easier to write, change and audit Increase velocity by standardizing on a single authorization solution Centralize authorization decisions and audit logs making it simpler to comply with security and compliance requirements Help their products to move faster because it is simpler to evolve authorization policies","s":"Benefits","u":"/pr-preview/pr-728/docs/fga","h":"#benefits","p":158},{"i":163,"t":"OpenFGA helps developers achieve those benefits with features as: A Playground to learn how to use the product effectively Support for multiple stores that allow authorization management in different environments (prod/testing/dev), use cases (internal apps, external apps, infrastructure) Support for ABAC scenarios with Contextual Tuples and Conditional Relationship Tuples SDKs for Java, .NET, Javascript, Go, and Python. An HTTP and gRPC API A Command Line Interface tool for managing OpenFGA environments, test models, import/export models, and data. Github Actions for testing and deploying models A Visual Studio Code Extension with syntax highlighting and validation of FGA models and tests Helm Charts to easily deploy to Kubernetes OpenTelemetry support to integrate it with your monitoring infrastructure","s":"Features","u":"/pr-preview/pr-728/docs/fga","h":"#features","p":158},{"i":165,"t":"Check the following sections to learn more about OpenFGA. Authorization Concepts Learn about Authorization. More Product Concepts Learn about OpenFGA. More Modeling: Getting Started Learn about how to get started with modeling your permission system in OpenFGA. More","s":"Related Sections","u":"/pr-preview/pr-728/docs/fga","h":"#related-sections","p":158},{"i":167,"t":"The OpenFGA Command Line Interface (CLI) enables you to interact with an FGA store, where you can manage tasks, create stores, and update FGA models, among other actions. For more information on FGA stores, see What Is A Store. For instructions on installing it, visit the OpenFGA CLI Github repository.","s":"Use the FGA CLI","u":"/pr-preview/pr-728/docs/getting-started/cli","h":"","p":166},{"i":169,"t":"The CLI is configured to use a specific FGA server in one of three ways: Using CLI flags. Using environment variables. Storing configuration values in a .fga.yaml located in the user’s root directory. The API Url setting needs to point to the OpenFGA server: Name Flag Environment ~/.fga.yaml Default Value API Url --api-url FGA_API_URL api-url http://localhost:8080 If you use pre-shared key authentication, configure the following parameters based on the OIDC server that’s used to issue tokens: Name Flag Environment ~/.fga.yaml Client ID --client-id FGA_CLIENT_ID client-id Client Secret --client-secret FGA_CLIENT_SECRET client-secret Scopes --api-scopes FGA_API_SCOPES api-scopes Token Issuer --api-token-issuer FGA_API_TOKEN_ISSUER api-token-issuer Token Audience --api-audience FGA_API_AUDIENCE api-audience A default store Id and authorization model Id can also be configured: Name Flag Environment ~/.fga.yaml Store ID --store-id FGA_STORE_ID store-id Authorization Model ID --model-id FGA_MODEL_ID model-id All of the examples in this document assume the CLI is properly configured and that the Store ID is set either in an environment variable or the ~/.fga.yaml file.","s":"Configuration","u":"/pr-preview/pr-728/docs/getting-started/cli","h":"#configuration","p":166},{"i":171,"t":"The CLI commands below show you how to create a store and run your application’s most common operations, including how to write a model and write/delete/read tuples, and run queries. # Create a store with a model $ fga store create --model docs.fga { \"store\": { \"created_at\":\"2024-02-09T23:20:28.637533296Z\", \"id\":\"01HP82R96XEJX1Q9YWA9XRQ4PM\", \"name\":\"docs\", \"updated_at\":\"2024-02-09T23:20:28.637533296Z\" }, \"model\": { \"authorization_model_id\":\"01HP82R97B448K89R45PW7NXD8\" } } # Keep the returned store id in an environment variable $ export FGA_STORE_ID=01HP82R96XEJX1Q9YWA9XRQ4PM # Get the latest model $ fga model get model schema 1.1 type user type organization relations define admin: [user with non_expired_grant] define member: [user] type document relations define editor: admin from organization define organization: [organization] define viewer: editor or member from organization condition non_expired_grant(current_time: timestamp, grant_duration: duration, grant_time: timestamp) { current_time < grant_time + grant_duration } # Write a tuple $ fga tuple write user:anne member organization:acme { \"successful\": [ { \"object\":\"organization:acme\", \"relation\":\"member\", \"user\":\"user:anne\" } ] } # Read all tuples. It returns the one added above $ fga tuple read { \"continuation_token\":\"\", \"tuples\": [ { \"key\": { \"object\":\"organization:acme\", \"relation\":\"member\", \"user\":\"user:anne\" }, \"timestamp\":\"2024-02-09T23:05:43.586Z\" } ] } # Write another tuple, adding a document for the acme organization $ fga tuple write organization:acme organization document:readme { \"successful\": [ { \"object\":\"document:readme\", \"relation\":\"organization\", \"user\":\"organization:acme\" } ] } # Check if anne can view the document. # Anne can view it as she's a member of organization:acme, which is the organization that owns the document $ fga query check user:anne viewer document:readme { \"allowed\":true, \"resolution\":\"\" } # List all the documents user:anne can view $ fga query list-objects user:anne viewer document { \"objects\": [ \"document:readme\" ] } # List all the relations that user:anne has with document:readme $ fga query list-relations user:anne document:readme { \"relations\": [ \"viewer\" ] } # Delete user:anne as a member of organization:acme $ fga tuple delete user:anne member organization:acme {} # Verify that user:anne is no longer a viewer of document:readme $ fga query check user:anne viewer document:readme { \"allowed\":false, \"resolution\":\"\" }","s":"Basic Operations","u":"/pr-preview/pr-728/docs/getting-started/cli","h":"#basic-operations","p":166},{"i":173,"t":"OpenFGA models are immutable; each time a model is written to a store, a new version of the model is created. All OpenFGA API endpoints receive an optional authorization model ID that points to a specific version of the model and defaults to the latest model version. Always use a specific model ID and update it each time a new model version is used in production. The following CLI commands lists the model Ids and find the latest one: # List all the authorization models $ fga model list { \"authorization_models\": [ { \"id\":\"01HPJ8JZV091THNTDFE2SFYNNJ\", \"created_at\":\"2024-02-13T22:14:50Z\" }, { \"id\":\"01HPJ808Q8J56QMK4WNT7MG7P7\", \"created_at\":\"2024-02-13T22:04:37Z\" }, { \"id\":\"01HPJ7YKNV0QT0S6CFRJMK231P\", \"created_at\":\"2024-02-13T22:03:43Z\" } ] } # List the last model, displaying just the model ID $ fga model get --field id # Model ID: 01HPJ8JZV091THNTDFE2SFYNNJ # List the last model, displaying just the model ID, in JSON format, to make it simpler to parse $ fga model get --field id --format json { \"id\":\"01HPJ8JZV091THNTDFE2SFYNNJ\" } When using the CLI, the model ID can be specified as a --model-id parameter or as part of the configuration.","s":"Work with Authorization Model versions","u":"/pr-preview/pr-728/docs/getting-started/cli","h":"#work-with-authorization-model-versions","p":166},{"i":175,"t":"To import tuples, use thefga tuple write command. It has the following parameters: Parameter Description --file Specifies the file name json, yaml and csv files are supported --max-tuples-per-write (optional, default=1, max=40) Maximum number of tuples to send in a single write --max-parallel-requests (optional, default=4) Maximum number of requests to send in parallel. Make it larger if you want to import a large number of tuples faster The CLI returns a list of tuples that were successfully written and a list of tuples that were not, with details of the write failure. If you specify -max-tuples-per-write greater than one, an error in one of the tuples implies none of the tuples get written. $ fga tuple write --file tuples.yaml { \"successful\": [ { \"object\":\"organization:acme\", \"relation\":\"member\", \"user\":\"user:anne\" } ], \"failed\":null } $ fga tuple write --file tuples.yaml { \"successful\":null, \"failed\": [ { \"tuple_key\": { \"object\":\"organization:acme\", \"relation\":\"member\", \"user\":\"user:anne\" }, \"reason\":\"Write validation error for POST Write with body {\\\"code\\\":\\\"write_failed_due_to_invalid_input\\\",\\\"message\\\":\\\"cannot write a tuple which already exists: user: 'user:anne', relation: 'member', object: 'organization:acme': invalid write input\\\"}\\n with error code write_failed_due_to_invalid_input error message: cannot write a tuple which already exists: user: 'user:anne', relation: 'member', object: 'organization:acme': invalid write input\" } } Below are examples of the different file formats the CLI accepts when writing tuples:","s":"Import tuples","u":"/pr-preview/pr-728/docs/getting-started/cli","h":"#import-tuples","p":166},{"i":177,"t":"- user: user:peter relation: admin object: organization:acme condition: name: non_expired_grant context: grant_time : \"2024-02-01T00:00:00Z\" grant_duration : 1h - user: user:anne relation: member object: organization:acme","s":"yaml","u":"/pr-preview/pr-728/docs/getting-started/cli","h":"#yaml","p":166},{"i":179,"t":"[ { \"user\": \"user:peter\", \"relation\": \"admin\", \"object\": \"organization:acme\", \"condition\": { \"context\": { \"grant_duration\": \"1h\", \"grant_time\": \"2024-02-01T00:00:00Z\" }, \"name\": \"non_expired_grant\" } }, { \"user\": \"user:anne\", \"relation\": \"member\", \"object\": \"organization:acme\" } ]","s":"JSON","u":"/pr-preview/pr-728/docs/getting-started/cli","h":"#json","p":166},{"i":181,"t":"user_type,user_id,user_relation,relation,object_type,object_id,condition_name,condition_context user,anne,member,,organization,acme,, user,peter1,admin,,organization,acme,non_expired_grant,\"{\"\"grant_duration\"\": \"\"1h\"\", \"\"grant_time\"\": \"\"2024-02-01T00:00:00Z\"\"}\" When using the CSV format, you can omit certain headers, and you don’t need to specify the value for those fields.","s":"CSV","u":"/pr-preview/pr-728/docs/getting-started/cli","h":"#csv","p":166},{"i":183,"t":"To delete a tuple, specify the user/relation/object you want to delete. To delete a group of tuples, specify a file that contains those tuples. $ fga tuple delete --file tuples.yaml { \"successful\": [ { \"object\":\"organization:acme\", \"relation\":\"admin\", \"user\":\"user:peter\" }, { \"object\":\"organization:acme\", \"relation\":\"member\", \"user\":\"user:anne\" } ], \"failed\":null } Delete all tuples from a store by reading all the tuples first and then deleting them: # Reads all the tuples and outputs them in a json format that can be used by 'fga tuple delete' and 'fga tuple write'. $ fga tuple read --output-format=simple-json --max-pages 0 > tuples.json $ fga tuple delete --file tuples.json","s":"Delete Tuples","u":"/pr-preview/pr-728/docs/getting-started/cli","h":"#delete-tuples","p":166},{"i":185,"t":"The CLI can import an FGA Test file in a store. It writes the model included and imports the tuples in the fga test file. Given the following .fga.yaml file: model: | model schema 1.1 type user type organization relations define member : [user] } tuples: # Anne is a member of the Acme organization - user: user:anne relation: member object: organization:acme The following command is used to import the file contents in a store: $ fga store import --file .fga.yaml Use the fga model get command is used to verify that the model was correctly written, and the fga tuple read command is used to verify that the tuples were properly imported.","s":"Import Stores","u":"/pr-preview/pr-728/docs/getting-started/cli","h":"#import-stores","p":166},{"i":187,"t":"Check the following sections for more on how to learn how to write tests. Testing Models Learn how to test FGA models using the FGA CLI. More","s":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/cli","h":"#related-sections","p":166},{"i":189,"t":"A store is a OpenFGA entity that contains your authorization data. You will need to create a store in OpenFGA before adding an authorization model and relationship tuples to it. This article explains how to set up an OpenFGA store.","s":"Create a Store","u":"/pr-preview/pr-728/docs/getting-started/create-store","h":"","p":188},{"i":191,"t":"Node.js Go .NET Python Java CLI curl const { OpenFgaClient } = require('@openfga/sdk'); // OR import { OpenFgaClient } from '@openfga/sdk'; const openFga = new OpenFgaClient({ apiUrl: process.env.FGA_API_URL, // required, e.g. https://api.fga.example }); const { id: storeId } = await openFga.createStore({ name: \"FGA Demo Store\", }); import ( \"context\" \"os\" . \"github.com/openfga/go-sdk/client\" ) func main() { fgaClient, err := NewSdkClient(&ClientConfiguration{ ApiUrl: os.Getenv(\"FGA_API_URL\"), // required, e.g. https://api.fga.example StoreId: os.Getenv(\"FGA_STORE_ID\"), // optional, not needed for \\`CreateStore\\` and \\`ListStores\\`, required before calling for all other methods AuthorizationModelId: os.Getenv(\"FGA_MODEL_ID\"), // Optional, can be overridden per request }) if err != nil { // .. Handle error } resp, err := fgaClient.CreateStore(context.Background()).Body(ClientCreateStoreRequest{Name: \"FGA Demo\"}).Execute() if err != nil { // .. Handle error } } using OpenFga.Sdk.Client; using OpenFga.Sdk.Client.Model; using OpenFga.Sdk.Model; using Environment = System.Environment; namespace ExampleApp; class MyProgram { static async Task Main() { var configuration = new ClientConfiguration() { ApiUrl = Environment.GetEnvironmentVariable(\"FGA_API_URL\") ?? \"http://localhost:8080\", // required, e.g. https://api.fga.example StoreId = Environment.GetEnvironmentVariable(\"FGA_STORE_ID\"), // optional, not needed for \\`CreateStore\\` and \\`ListStores\\`, required before calling for all other methods AuthorizationModelId = Environment.GetEnvironmentVariable(\"FGA_MODEL_ID\"), // optional, can be overridden per request }; var fgaClient = new OpenFgaClient(configuration); var store = await fgaClient.CreateStore(new ClientCreateStoreRequest(){Name = \"FGA Demo Store\"}); } } import asyncio import os import openfga_sdk from openfga_sdk.client import OpenFgaClient from openfga_sdk.models.create_store_request import CreateStoreRequest async def main(): configuration = openfga_sdk.ClientConfiguration( api_url = os.environ.get('FGA_API_URL'), # required, e.g. https://api.fga.example ) async with OpenFgaClient(configuration) as fga_client: body = CreateStoreRequest( name = \"FGA Demo Store\", ) response = await fga_client.create_store(body) asyncio.run(main()) import dev.openfga.sdk.api.client.OpenFgaClient; import dev.openfga.sdk.api.configuration.ClientConfiguration; import dev.openfga.sdk.api.model.CreateStoreRequest; public class Example { public static void main(String[] args) { var config = new ClientConfiguration() .apiUrl(System.getenv(\"FGA_API_URL\")) // If not specified, will default to \"https://localhost:8080\" .storeId(System.getenv(\"FGA_STORE_ID\")) // Not required when calling createStore() or listStores() .authorizationModelId(System.getenv(\"FGA_AUTHORIZATION_MODEL_ID\")); // Optional, can be overridden per request var fgaClient = new OpenFgaClient(config); var body = new CreateStoreRequest().name(\"FGA Demo Store\"); var store = fgaClient.createStore(body).get(); } } fga store create --name \"FGA Demo Store\" # To create the store and directly put the Store ID into an env variable: # export FGA_STORE_ID=$(fga store create --name \"FGA Demo Store\" | jq -r .store.id) curl -X POST $FGA_API_URL/stores \\ -H \"content-type: application/json\" \\ -d '{\"name\": \"FGA Demo Store\"}'","s":"Step By Step","u":"/pr-preview/pr-728/docs/getting-started/create-store","h":"#step-by-step","p":188},{"i":193,"t":"This section will illustrate how to integrate OpenFGA within a framework, such as Fastify or Fiber.","s":"Integrate Within a Framework","u":"/pr-preview/pr-728/docs/getting-started/framework","h":"","p":192},{"i":195,"t":"Node.js Go Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have installed the OpenFGA SDK. You have configured the authorization model and updated the relationship tuples. You know how to perform a Check. You have loaded FGA_API_URL and FGA_STORE_ID as environment variables. Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have installed the OpenFGA SDK. You have configured the authorization model and updated the relationship tuples. You know how to perform a Check. You have loaded FGA_API_URL and FGA_STORE_ID as environment variables.","s":"Before You Start","u":"/pr-preview/pr-728/docs/getting-started/framework","h":"#before-you-start","p":192},{"i":197,"t":"Assume that you want to have a web service for documents using one of the frameworks mentioned above. The service will authenticate users via JWT tokens, which contain the user ID. Note The reader should set up their own login method based on their OpenID connect provider's documentation. Assume that you want to provide a route GET /read/{document} to return documents depending on whether the authenticated user has access to it.","s":"Step By Step","u":"/pr-preview/pr-728/docs/getting-started/framework","h":"#step-by-step","p":192},{"i":199,"t":"The first step is to install the framework. Node.js Go For the context of this example, we will use the Fastify framework. For that we need to install the following packages: the fastify package that provides the framework itself the fastify-plugin package that allows integrating plugins with Fastify the fastify-jwt package for processing JWT tokens Using npm: npm install fastify fastify-plugin fastify-jwt Using yarn: yarn add fastify fastify-plugin fastify-jwt Next, we setup the web service with the GET /read/{document} route in file app.js. // Require the framework and instantiate it const fastify = require('fastify')({ logger: true }); // Declare the route fastify.get('/read/:document', async (request, reply) => { return { read: request.params.document }; }); // Run the server const start = async () => { try { await fastify.listen(3000); } catch (err) { fastify.log.error(err); process.exit(1); } }; start(); For the context of this example, we will use the Fiber framework. For that we need to install the following Go packages: the gofiber/fiber package that provides the Fiber framework itself the gofiber/jwt middleware authentication layer for JWT the golang-jwt package that provides Go support for JWT go get -u github.com/gofiber/fiber/v2 github.com/gofiber/jwt/v3 github.com/golang-jwt/jwt/v4 Next, we setup the web service with the GET /read/{document} route. package main import \"github.com/gofiber/fiber/v2\" func main() { app := fiber.New() app.Get(\"/read/:document\", read) app.Listen(\":3000\") } func read(c *fiber.Ctx) error { return c.SendString(c.Params(\"document\")) }","s":"01. Install And Setup Framework","u":"/pr-preview/pr-728/docs/getting-started/framework","h":"#01-install-and-setup-framework","p":192},{"i":201,"t":"Before we can call OpenFGA to protect the /read/{document} route, we need to validate the user's JWT. Node.js Go The fastify-jwt package allows validation of JWT tokens, as well as providing access to the user's identity. In jwt-authenticate.js: const fp = require('fastify-plugin'); module.exports = fp(async function (fastify, opts) { fastify.register(require('fastify-jwt'), { secret: { private: readFileSync(`${path.join(__dirname, 'certs')}/private.key`, 'utf8'), public: readFileSync(`${path.join(__dirname, 'certs')}/public.key`, 'utf8'), }, sign: { algorithm: 'RS256' }, }); fastify.decorate('authenticate', async function (request, reply) { try { await request.jwtVerify(); } catch (err) { reply.send(err); } }); }); Then, use the preValidation hook of a route to protect it and access the user information inside the JWT: In route-read.js: module.exports = async function (fastify, opts) { fastify.get( '/read/:document', { preValidation: [fastify.authenticate], }, async function (request, reply) { // the user's id is in request.user return { read: request.params.document }; }, ); }; Finally, update app.js to register the newly added hooks. const fastify = require('fastify')({ logger: true }); const jwtAuthenticate = require('./jwt-authenticate'); const routeread = require('./route-read'); fastify.register(jwtAuthenticate); fastify.register(routeread); // Run the server! const start = async () => { try { await fastify.listen(3000); } catch (err) { fastify.log.error(err); process.exit(1); } } start(); We will now setup middleware to authenticate the incoming JWTs. package main import ( \"crypto/rand\" \"crypto/rsa\" \"log\" \"github.com/gofiber/fiber/v2\" jwtware \"github.com/gofiber/jwt/v3\" \"github.com/golang-jwt/jwt/v4\" ) var ( // Do not do this in production. // In production, you would have the private key and public key pair generated // in advance. NEVER add a private key to any GitHub repo. privateKey *rsa.PrivateKey ) func main() { app := fiber.New() // Just as a demo, generate a new private/public key pair on each run. rng := rand.Reader var err error privateKey, err = rsa.GenerateKey(rng, 2048) if err != nil { log.Fatalf(\"rsa.GenerateKey: %v\", err) } // JWT Middleware app.Use(jwtware.New(jwtware.Config{ SigningMethod: \"RS256\", SigningKey: privateKey.Public(), })) app.Get(\"/read/:document\", read) app.Listen(\":3000\") } func read(c *fiber.Ctx) error { user := c.Locals(\"user\").(*jwt.Token) claims := user.Claims.(jwt.MapClaims) name := claims[\"name\"].(string) return c.SendString(name + \" read \" + c.Params(\"document\")) }","s":"02. Authenticate And Get User ID","u":"/pr-preview/pr-728/docs/getting-started/framework","h":"#02-authenticate-and-get-user-id","p":192},{"i":203,"t":"Node.js Go First, we will create a decorator preauthorize to parse the incoming HTTP method as well as name of the document, and set the appropriate relation and object that we will call Check on. In preauthorize.js: const fp = require('fastify-plugin'); module.exports = fp(async function (fastify, opts) { fastify.decorate('preauthorize', async function (request, reply) { try { switch (request.method) { case 'GET': request.relation = 'reader'; break; case 'POST': request.relation = 'writer'; break; case 'DELETE': default: request.relation = 'owner'; break; } request.object = `document:${request.params.document}`; } catch (err) { reply.send(err); } }); }); Next, we will create a decorator called authorize. This decorator will invoke the Check API to see if the user has a relationship with the specified document. In authorize.js: const fp = require('fastify-plugin'); const { OpenFgaClient } = require('@openfga/sdk'); // OR import { OpenFgaClient } from '@openfga/sdk'; module.exports = fp(async function (fastify, opts) { fastify.decorate('authorize', async function (request, reply) { try { // configure the openfga api client const fgaClient = new OpenFgaClient({ apiUrl: process.env.FGA_API_URL, // required, e.g. https://api.fga.example storeId: process.env.FGA_STORE_ID, }); const { allowed } = await fgaClient.check({ user: request.user, relation: request.relation, object: request.object, }); if (!allowed) { reply.code(401).send(`Not authenticated`); } } catch (err) { reply.send(err); } }); }); We can now update the GET /read/{document} route to check for user permissions. In route-read.js: module.exports = async function (fastify, opts) { fastify.get( '/read/:document', { preValidation: [fastify.authenticate, fastify.preauthorize, fastify.authorize], }, async function (request, reply) { // the user's id is in request.user return { read: request.params.document }; }, ); }; Finally, we will register the new hooks in app.js: const fastify = require('fastify')({ logger: true }); const jwtAuthenticate = require('./jwt-authenticate'); const preauthorize = require('./preauthorize'); const authorize = require('./authorize'); const routeread = require('./route-read'); fastify.register(jwtAuthenticate); fastify.register(preauthorize); fastify.register(authorize); fastify.register(routeread); const start = async () => { try { await fastify.listen(3000); } catch (err) { fastify.log.error(err); process.exit(1); } } start(); We will create two middlewares: preauthorize will parse the user's JWT and prepare variables needed to call Check API. checkAuthorization will call the Check API to see if the user has a relationship with the specified document. package main import ( \"context\" \"crypto/rand\" \"crypto/rsa\" \"log\" \"os\" \"github.com/gofiber/fiber/v2\" jwtware \"github.com/gofiber/jwt/v3\" \"github.com/golang-jwt/jwt/v4\" . \"github.com/openfga/go-sdk/client\" ) var ( // Do not do this in production. // In production, you would have the private key and public key pair generated // in advance. NEVER add a private key to any GitHub repo. privateKey *rsa.PrivateKey ) func main() { app := fiber.New() // Just as a demo, generate a new private/public key pair on each run. rng := rand.Reader var err error privateKey, err = rsa.GenerateKey(rng, 2048) if err != nil { log.Fatalf(\"rsa.GenerateKey: %v\", err) } // JWT Middleware app.Use(jwtware.New(jwtware.Config{ SigningMethod: \"RS256\", SigningKey: privateKey.Public(), })) app.Use(\"/read/:document\", preauthorize) app.Use(checkAuthorization) app.Get(\"/read/:document\", read) app.Listen(\":3000\") } func read(c *fiber.Ctx) error { user := c.Locals(\"user\").(*jwt.Token) claims := user.Claims.(jwt.MapClaims) name := claims[\"name\"].(string) return c.SendString(name + \" read \" + c.Params(\"document\")) } func preauthorize(c *fiber.Ctx) error { // get the user name from JWT user := c.Locals(\"user\").(*jwt.Token) claims := user.Claims.(jwt.MapClaims) name := claims[\"name\"].(string) c.Locals(\"username\", name) // parse the HTTP method switch (c.Method()) { case \"GET\": c.Locals(\"relation\", \"reader\") case \"POST\": c.Locals(\"relation\", \"writer\") case \"DELETE\": c.Locals(\"relation\", \"owner\") default: c.Locals(\"relation\", \"owner\") } // get the object name and prepend with type name \"document:\" c.Locals(\"object\", \"document:\" + c.Params(\"document\")) return c.Next() } // Middleware to check whether user is authorized to access document func checkAuthorization(c *fiber.Ctx) error { fgaClient, err := NewSdkClient(&ClientConfiguration{ ApiUrl: os.Getenv(\"FGA_API_URL\"), // required, e.g. https://api.fga.example StoreId: os.Getenv(\"FGA_STORE_ID\"), // optional, not needed for \\`CreateStore\\` and \\`ListStores\\`, required before calling for all other methods AuthorizationModelId: os.Getenv(\"FGA_MODEL_ID\"), // optional, can be overridden per request }) if err != nil { return fiber.NewError(fiber.StatusServiceUnavailable, \"Unable to build OpenFGA client\") } body := ClientCheckRequest{ User: c.Locals(\"username\").(string), Relation: c.Locals(\"relation\").(string), Object: c.Locals(\"object\").(string), } data, err := fgaClient.Check(context.Background()).Body(body).Execute() if err != nil { return fiber.NewError(fiber.StatusServiceUnavailable, \"Unable to check for authorization\") } if !(*data.Allowed) { return fiber.NewError(fiber.StatusUnauthorized, \"Unauthorized to access document\") } // Go to the next middleware return c.Next() }","s":"03. Integrate The OpenFGA Check API Into The Service","u":"/pr-preview/pr-728/docs/getting-started/framework","h":"#03-integrate-the--check-api-into-the-service","p":192},{"i":205,"t":"Take a look at the following sections for examples that you can try when integrating with SDK. Entitlements Modeling Entitlements for a System in OpenFGA. More IoT Modeling Fine Grained Authorization for an IoT Security Camera System with OpenFGA. More Slack Modeling Authorization for Slack with OpenFGA. More","s":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/framework","h":"#related-sections","p":192},{"i":207,"t":"To get started, install the OpenFGA SDK packages. Node.js Go .NET Python Java CLI You can find the Node.js package on npm at: @openfga/sdk. Using npm: npm install @openfga/sdk Using yarn: yarn add @openfga/sdk You can find the Go package on GitHub at: @openfga/go-sdk. To install: go get -u github.com/openfga/go-sdk In your code, import the module and use it: import ( openfga \"github.com/openfga/go-sdk\" ) func main() { configuration, err := openfga.NewConfiguration(openfga.Configuration{ ApiUrl: os.Getenv(\"FGA_API_URL\"), // required, e.g. https://api.fga.example }) if err != nil { // .. Handle error } } You can then run go mod tidy to update go.mod and go.sum if you are using them. The OpenFGA .NET SDK is available on NuGet. You can install it using: The dotnet CLI: dotnet add package OpenFGA.Sdk The Package Manager Console inside Visual Studio: Install-Package OpenFGA.Sdk Visual Studio, Visual Studio for Mac and IntelliJ Rider: Search for and install OpenFGA.Sdk in each of their respective package manager UIs. The OpenFGA Python SDK is available on PyPI. To install: pip3 install openfga_sdk In your code, import the module and use it: import openfga_sdk You can find the Java package on Maven Central. Using Maven: dev.openfga openfga-sdk 0.3.1 Using Gradle: implementation 'dev.openfga:openfga-sdk:0.3.1' The OpenFGA CLI is available on GitHub. To install: Brew​ brew install openfga/tap/fga Linux (deb, rpm and apk) packages​ Download the .deb, .rpm or .apk packages from the releases page. Debian: sudo apt install ./fga__linux_.deb Fedora: sudo dnf install ./fga__linux_.rpm Alpine Linux: sudo apk add --allow-untrusted ./fga__linux_.apk Docker​ docker pull openfga/cli; docker run -it openfga/cli Go​ note that the command will be named cli go install github.com/openfga/cli@latest Manually​ Download the pre-compiled binaries from the releases page. check API","s":"Install SDK Client","u":"/pr-preview/pr-728/docs/getting-started/install-sdk","h":"","p":206},{"i":209,"t":"brew install openfga/tap/fga","s":"Brew","u":"/pr-preview/pr-728/docs/getting-started/install-sdk","h":"#brew","p":206},{"i":211,"t":"Download the .deb, .rpm or .apk packages from the releases page. Debian: sudo apt install ./fga__linux_.deb Fedora: sudo dnf install ./fga__linux_.rpm Alpine Linux: sudo apk add --allow-untrusted ./fga__linux_.apk","s":"Linux (deb, rpm and apk) packages","u":"/pr-preview/pr-728/docs/getting-started/install-sdk","h":"#linux-deb-rpm-and-apk-packages","p":206},{"i":213,"t":"docker pull openfga/cli; docker run -it openfga/cli","s":"Docker","u":"/pr-preview/pr-728/docs/getting-started/install-sdk","h":"#docker","p":206},{"i":215,"t":"note that the command will be named cli go install github.com/openfga/cli@latest","s":"Go","u":"/pr-preview/pr-728/docs/getting-started/install-sdk","h":"#go","p":206},{"i":217,"t":"Download the pre-compiled binaries from the releases page.","s":"Manually","u":"/pr-preview/pr-728/docs/getting-started/install-sdk","h":"#manually","p":206},{"i":219,"t":"Get OpenFGA's SDKs to add authorization to your API. OpenFGA Node.js SDK Install our Node.js & JavaScript SDK to get started. More OpenFGA Go SDK Use our Go SDK to easily connect your Go application to the OpenFGA API More OpenFGA .NET SDK Connect your .NET service with OpenFGA using our .NET SDK More OpenFGA Python SDK Connect your Python service with OpenFGA using our Python SDK More OpenFGA Java SDK Connect your Java service with OpenFGA using our Java SDK More","s":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/install-sdk","h":"#related-sections","p":206},{"i":221,"t":"Authorization Models in OpenFGA are immutable, they are created once and then can no longer be deleted or modified. Each time you write an authorization model, a new version is created.","s":"Immutable Authorization Models","u":"/pr-preview/pr-728/docs/getting-started/immutable-models","h":"","p":220},{"i":223,"t":"You can list all the authorization models for a store using the ReadAuthorizationModels API. This endpoint returns the results sorted in reverse chronological order, as in the first model in the list is the latest model. By default, only the last 50 models are returned, but you can paginate across by passing in the appropriate continuation_token.","s":"Viewing All the Authorization Models","u":"/pr-preview/pr-728/docs/getting-started/immutable-models","h":"#viewing-all-the-authorization-models","p":220},{"i":225,"t":"Some endpoints relating to tuples (Check, ListObjects, Expand, Write) accept an authorization_model_id, which we strongly recommend passing, especially in production. In practice, you would pin the authorization model ID alongside the store ID in your configuration management system. Your services would read this value and use it in their requests to FGA. This helps you ensure that your services are using the same consistent ID across all your applications, and that rollouts can be seamless.","s":"How to Target a Particular Model","u":"/pr-preview/pr-728/docs/getting-started/immutable-models","h":"#how-to-target-a-particular-model","p":220},{"i":227,"t":"Targeting a specific model ID would ensure that you don't accidentally break your authorization checks in production because a mistake was made when updating the authorization model. It would also slightly improve the latency on your check requests. If that field is passed, evaluation and validation will happen for that particular authorization model ID. If this field is not passed, OpenFGA will use the last created Authorization Model for that store.","s":"Benefits of Passing in an Authorization Model ID","u":"/pr-preview/pr-728/docs/getting-started/immutable-models","h":"#benefits-of-passing-in-an-authorization-model-id","p":220},{"i":229,"t":"Being able to target multiple versions of the authorization model enables you to progressively roll out model changes, which is something you should consider doing if the changes are significant. You could: Do shadow checks where you would perform checks against both your existing model and the new upcoming model you are hoping to replace it with.This will help you detect and resolve any accidental discrepancies you may be introducing, and ensure that your new model is at least as good as your old one. When you are confident with your model, you could implement gradual rollouts that would allow you to monitor and check if any users are having access issues before you go ahead and increase the rollout to 100% of your user base. Getting an Authorization Model's Creation Date The Authorization Model ID is a ULID which includes the date created. You can extract the creation date using a library for your particular language. For example, in JavaScript you can do the following: import ulid = require('ulid'); const time = ulid.decodeTime(id);","s":"Potential Use-cases","u":"/pr-preview/pr-728/docs/getting-started/immutable-models","h":"#potential-use-cases","p":220},{"i":231,"t":"Learn more about modeling and production usage in OpenFGA. Configuration Language Learn about the OpenFGA Configuration Language. More Getting Started with Modeling Read how to get started with modeling. More Data and API Best Practices Learn the best practices for managing data and invoking APIs in production environment More","s":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/immutable-models","h":"#related-sections","p":220},{"i":233,"t":"This section will illustrate how to perform a check request to determine whether a user has a certain relationship with an object.","s":"Perform a Check","u":"/pr-preview/pr-728/docs/getting-started/perform-check","h":"","p":232},{"i":235,"t":"Node.js Go .NET Python Java CLI curl Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have installed the SDK. You have configured the authorization model and updated the relationship tuples. You have loaded FGA_STORE_ID and FGA_API_URL as environment variables. Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have installed the SDK. You have configured the authorization model and updated the relationship tuples. You have loaded FGA_STORE_ID and FGA_API_URL as environment variables. Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have installed the SDK. You have configured the authorization model and updated the relationship tuples. You have loaded FGA_STORE_ID and FGA_API_URL as environment variables. Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have installed the SDK. You have configured the authorization model and updated the relationship tuples. You have loaded FGA_STORE_ID and FGA_API_URL as environment variables. Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have installed the SDK. You have configured the authorization model and updated the relationship tuples. You have loaded FGA_STORE_ID and FGA_API_URL as environment variables. Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have configured the authorization model. You have loaded FGA_STORE_ID and FGA_API_URL as environment variables. Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have configured the authorization model and updated the relationship tuples. You have loaded FGA_STORE_ID and FGA_API_URL as environment variables.","s":"Before You Start","u":"/pr-preview/pr-728/docs/getting-started/perform-check","h":"#before-you-start","p":232},{"i":237,"t":"Assume that you want to check whether user anne has relationship reader with object document:Z","s":"Step By Step","u":"/pr-preview/pr-728/docs/getting-started/perform-check","h":"#step-by-step","p":232},{"i":239,"t":"Before calling the check API, you will need to configure the API client. Node.js Go .NET Python Java CLI curl // import the SDK const { OpenFgaClient } = require('@openfga/sdk'); // Initialize the SDK with no auth - see \"How to setup SDK client\" for more options const fgaClient = new OpenFgaClient({ apiUrl: process.env.FGA_API_URL, // required, e.g. https://api.fga.example storeId: process.env.FGA_STORE_ID, authorizationModelId: process.env.FGA_MODEL_ID, // Optional, can be overridden per request }); import ( \"os\" . \"github.com/openfga/go-sdk\" . \"github.com/openfga/go-sdk/client\" ) func main() { // Initialize the SDK with no auth - see \"How to setup SDK client\" for more options fgaClient, err := NewSdkClient(&ClientConfiguration{ ApiUrl: os.Getenv(\"FGA_API_URL\"), // required, e.g. https://api.fga.example StoreId: os.Getenv(\"FGA_STORE_ID\"), // optional, not needed for `CreateStore` and `ListStores`, required before calling for all other methods AuthorizationModelId: os.Getenv(\"FGA_MODEL_ID\"), // Optional, can be overridden per request }) if err != nil { // .. Handle error } } // import the SDK using OpenFga.Sdk.Client; using OpenFga.Sdk.Client.Model; using OpenFga.Sdk.Model; using Environment = System.Environment; namespace Example; class Example { public static async Task Main() { // Initialize the SDK with no auth - see \"How to setup SDK client\" for more options var configuration = new ClientConfiguration() { ApiUrl = Environment.GetEnvironmentVariable(\"FGA_API_URL\"), ?? \"http://localhost:8080\", // required, e.g. https://api.fga.example StoreId = Environment.GetEnvironmentVariable(\"FGA_STORE_ID\"), // optional, not needed for `CreateStore` and `ListStores`, required before calling for all other methods AuthorizationModelId = Environment.GetEnvironmentVariable(\"FGA_MODEL_ID\"), // Optional, can be overridden per request }; var fgaClient = new OpenFgaClient(configuration); } } import asyncio import os import json from openfga_sdk.client import ClientConfiguration, OpenFgaClient async def main(): configuration = ClientConfiguration( api_url = os.environ.get('FGA_API_URL'), # required, e.g. https://api.fga.example store_id = os.environ.get('FGA_STORE_ID'), # optional, not needed for `CreateStore` and `ListStores`, required before calling for all other methods authorization_model_id = os.environ.get('FGA_MODEL_ID'), # Optional, can be overridden per request ) # Enter a context with an instance of the OpenFgaClient async with OpenFgaClient(configuration) as fga_client: api_response = await fga_client.read_authorization_models() await fga_client.close() asyncio.run(main()) import dev.openfga.sdk.api.client.OpenFgaClient; import dev.openfga.sdk.api.configuration.ClientConfiguration; public class Example { public static void main(String[] args) throws Exception { var config = new ClientConfiguration() .apiUrl(System.getenv(\"FGA_API_URL\")) // If not specified, will default to \"https://localhost:8080\" .storeId(System.getenv(\"FGA_STORE_ID\")) // Not required when calling createStore() or listStores() .authorizationModelId(System.getenv(\"FGA_AUTHORIZATION_MODEL_ID\")); // Optional, can be overridden per request var fgaClient = new OpenFgaClient(config); } } Set FGA_API_URL according to the service you are using (e.g. https://api.fga.example) To obtain the access token: Set FGA_API_URL according to the service you are using (e.g. https://api.fga.example)","s":"01. Configure the OpenFGA API Client","u":"/pr-preview/pr-728/docs/getting-started/perform-check","h":"#01-configure-the--api-client","p":232},{"i":241,"t":"To check whether user user:anne has relationship reader with object document:Z Node.js Go .NET Python Java CLI curl // Run a check const { allowed } = await fgaClient.check({ user: 'user:anne', relation: 'reader', object: 'document:Z', }, { authorization_model_id: '01HVMMBCMGZNT3SED4Z17ECXCA', }); // allowed = true options := ClientCheckOptions{ AuthorizationModelId: PtrString(\"01HVMMBCMGZNT3SED4Z17ECXCA\"), } body := ClientCheckRequest{ User: \"user:anne\", Relation: \"reader\", Object: \"document:Z\", } data, err := fgaClient.Check(context.Background()). Body(body). Options(options). Execute() // data = { allowed: true } var options = new ClientCheckOptions { AuthorizationModelId = \"01HVMMBCMGZNT3SED4Z17ECXCA\", }; var body = new ClientCheckRequest { User = \"user:anne\", Relation = \"reader\", Object = \"document:Z\", }; var response = await fgaClient.Check(body, options); // response.Allowed = true options = { \"authorization_model_id\": \"01HVMMBCMGZNT3SED4Z17ECXCA\" } body = ClientCheckRequest( user=\"user:anne\", relation=\"reader\", object=\"document:Z\", ) response = await fga_client.check(body, options) # response.allowed = true var options = new ClientCheckOptions() .authorizationModelId(\"01HVMMBCMGZNT3SED4Z17ECXCA\"); var body = new ClientCheckRequest() .user(\"user:anne\") .relation(\"reader\") ._object(\"document:Z\"); var response = fgaClient.check(body, options).get(); // response.getAllowed() = true fga query check --store-id=$FGA_STORE_ID --model-id=01HVMMBCMGZNT3SED4Z17ECXCA user:anne reader document:Z # Response: {\"allowed\":true} curl -X POST $FGA_API_URL/stores/$FGA_STORE_ID/check \\ -H \"Authorization: Bearer $FGA_API_TOKEN\" \\ # Not needed if service does not require authorization -H \"content-type: application/json\" \\ -d '{\"authorization_model_id\": \"01HVMMBCMGZNT3SED4Z17ECXCA\", \"tuple_key\":{\"user\":\"user:anne\",\"relation\":\"reader\",\"object\":\"document:Z\"}}' # Response: {\"allowed\":true} The result's allowed field will return true if the relationship exists and false if the relationship does not exist.","s":"02. Calling Check API","u":"/pr-preview/pr-728/docs/getting-started/perform-check","h":"#02-calling-check-api","p":232},{"i":243,"t":"Take a look at the following section for more on how to perform authorization checks in your system OpenFGA Check API Read the Check API documentation and see how it works. More","s":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/perform-check","h":"#related-sections","p":232},{"i":245,"t":"This section will illustrate how to perform a list objects request to determine all the objects of a given type a user has a specified relationship with.","s":"Perform a List Objects call","u":"/pr-preview/pr-728/docs/getting-started/perform-list-objects","h":"","p":244},{"i":247,"t":"Node.js Go .NET Python Java CLI curl Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have installed the SDK. You have configured the authorization model and updated the relationship tuples. You have loaded FGA_STORE_ID and FGA_API_URL as environment variables. Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have installed the SDK. You have configured the authorization model and updated the relationship tuples. You have loaded FGA_STORE_ID and FGA_API_URL as environment variables. Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have installed the SDK. You have configured the authorization model and updated the relationship tuples. You have loaded FGA_STORE_ID and FGA_API_URL as environment variables. Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have installed the SDK. You have configured the authorization model and updated the relationship tuples. You have loaded FGA_STORE_ID and FGA_API_URL as environment variables. Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have installed the SDK. You have configured the authorization model and updated the relationship tuples. You have loaded FGA_STORE_ID and FGA_API_URL as environment variables. Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have configured the authorization model. You have loaded FGA_STORE_ID and FGA_API_URL as environment variables. Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have configured the authorization model and updated the relationship tuples. You have loaded FGA_STORE_ID and FGA_API_URL as environment variables.","s":"Before You Start","u":"/pr-preview/pr-728/docs/getting-started/perform-list-objects","h":"#before-you-start","p":244},{"i":249,"t":"Assume that you want to list all objects of type document that user anne has reader relationship with:","s":"Step By Step","u":"/pr-preview/pr-728/docs/getting-started/perform-list-objects","h":"#step-by-step","p":244},{"i":251,"t":"Before calling the check API, you will need to configure the API client. Node.js Go .NET Python Java CLI curl // import the SDK const { OpenFgaClient } = require('@openfga/sdk'); // Initialize the SDK with no auth - see \"How to setup SDK client\" for more options const fgaClient = new OpenFgaClient({ apiUrl: process.env.FGA_API_URL, // required, e.g. https://api.fga.example storeId: process.env.FGA_STORE_ID, authorizationModelId: process.env.FGA_MODEL_ID, // Optional, can be overridden per request }); import ( \"os\" . \"github.com/openfga/go-sdk\" . \"github.com/openfga/go-sdk/client\" ) func main() { // Initialize the SDK with no auth - see \"How to setup SDK client\" for more options fgaClient, err := NewSdkClient(&ClientConfiguration{ ApiUrl: os.Getenv(\"FGA_API_URL\"), // required, e.g. https://api.fga.example StoreId: os.Getenv(\"FGA_STORE_ID\"), // optional, not needed for `CreateStore` and `ListStores`, required before calling for all other methods AuthorizationModelId: os.Getenv(\"FGA_MODEL_ID\"), // Optional, can be overridden per request }) if err != nil { // .. Handle error } } // import the SDK using OpenFga.Sdk.Client; using OpenFga.Sdk.Client.Model; using OpenFga.Sdk.Model; using Environment = System.Environment; namespace Example; class Example { public static async Task Main() { // Initialize the SDK with no auth - see \"How to setup SDK client\" for more options var configuration = new ClientConfiguration() { ApiUrl = Environment.GetEnvironmentVariable(\"FGA_API_URL\"), ?? \"http://localhost:8080\", // required, e.g. https://api.fga.example StoreId = Environment.GetEnvironmentVariable(\"FGA_STORE_ID\"), // optional, not needed for `CreateStore` and `ListStores`, required before calling for all other methods AuthorizationModelId = Environment.GetEnvironmentVariable(\"FGA_MODEL_ID\"), // Optional, can be overridden per request }; var fgaClient = new OpenFgaClient(configuration); } } import asyncio import os import json from openfga_sdk.client import ClientConfiguration, OpenFgaClient async def main(): configuration = ClientConfiguration( api_url = os.environ.get('FGA_API_URL'), # required, e.g. https://api.fga.example store_id = os.environ.get('FGA_STORE_ID'), # optional, not needed for `CreateStore` and `ListStores`, required before calling for all other methods authorization_model_id = os.environ.get('FGA_MODEL_ID'), # Optional, can be overridden per request ) # Enter a context with an instance of the OpenFgaClient async with OpenFgaClient(configuration) as fga_client: api_response = await fga_client.read_authorization_models() await fga_client.close() asyncio.run(main()) import dev.openfga.sdk.api.client.OpenFgaClient; import dev.openfga.sdk.api.configuration.ClientConfiguration; public class Example { public static void main(String[] args) throws Exception { var config = new ClientConfiguration() .apiUrl(System.getenv(\"FGA_API_URL\")) // If not specified, will default to \"https://localhost:8080\" .storeId(System.getenv(\"FGA_STORE_ID\")) // Not required when calling createStore() or listStores() .authorizationModelId(System.getenv(\"FGA_AUTHORIZATION_MODEL_ID\")); // Optional, can be overridden per request var fgaClient = new OpenFgaClient(config); } } Set FGA_API_URL according to the service you are using (e.g. https://api.fga.example) To obtain the access token: Set FGA_API_URL according to the service you are using (e.g. https://api.fga.example)","s":"01. Configure the OpenFGA API Client","u":"/pr-preview/pr-728/docs/getting-started/perform-list-objects","h":"#01-configure-the--api-client","p":244},{"i":253,"t":"To return all documents that user user:anne has relationship reader with: Node.js Go .NET Python Java CLI curl const response = await fgaClient.listObjects({ user: \"user:anne\", relation: \"reader\", type: \"document\", }, { authorization_model_id: \"01HVMMBCMGZNT3SED4Z17ECXCA\", }); // response.objects = [\"document:otherdoc\", \"document:planning\"] options := ClientListObjectsOptions{ AuthorizationModelId: PtrString(\"01HVMMBCMGZNT3SED4Z17ECXCA\"), } body := ClientListObjectsRequest{ User: \"user:anne\", Relation: \"reader\", Type: \"document\", } data, err := fgaClient.ListObjects(context.Background()). Body(body). Options(options). Execute() // data = { \"objects\": [\"document:otherdoc\", \"document:planning\"] } var options = new ClientCheckOptions { AuthorizationModelId = \"01HVMMBCMGZNT3SED4Z17ECXCA\", }; var body = new ClientListObjectsRequest { User = \"user:anne\", Relation = \"reader\", Type = \"document\", }; var response = await fgaClient.ListObjects(body, options); // response.Objects = [\"document:otherdoc\", \"document:planning\"] options = { \"authorization_model_id\": \"01HVMMBCMGZNT3SED4Z17ECXCA\" } body = ClientListObjectsRequest( user=\"user:anne\", relation=\"reader\", type=\"document\", ) response = await fga_client.list_objects(body, options) # response.objects = [\"document:otherdoc\", \"document:planning\"] var options = new ClientListObjectsOptions() .authorizationModelId(\"01HVMMBCMGZNT3SED4Z17ECXCA\"); var body = new ClientListObjectsRequest() .user(\"user:anne\") .relation(\"reader\") .type(\"document\"); var response = fgaClient.listObjects(body, options).get(); // response.getObjects() = [\"document:otherdoc\", \"document:planning\"] fga query list-objects --store-id=${FGA_STORE_ID} --model-id=01HVMMBCMGZNT3SED4Z17ECXCA user:anne reader document # Response: {\"objects\": [\"document:otherdoc\", \"document:planning\"]} curl -X POST $FGA_API_URL/stores/$FGA_STORE_ID/list-objects \\ -H \"Authorization: Bearer $FGA_API_TOKEN\" \\ # Not needed if service does not require authorization -H \"content-type: application/json\" \\ -d '{ \"authorization_model_id\": \"01HVMMBCMGZNT3SED4Z17ECXCA\", \"type\": \"document\", \"relation\": \"reader\", \"user\":\"user:anne\" }' # Response: {\"objects\": [\"document:otherdoc\", \"document:planning\"]} The result document:otherdoc and document:planning are the document objects that user:anne has reader relationship with. Warning The performance characteristics of the ListObjects endpoint vary drastically depending on the model complexity, number of tuples, and the relations it needs to evaluate. Relations with 'and' or 'but not' are more expensive to evaluate than relations with 'or'.","s":"02. Calling List Objects API","u":"/pr-preview/pr-728/docs/getting-started/perform-list-objects","h":"#02-calling-list-objects-api","p":244},{"i":255,"t":"Take a look at the following section for more on how to perform authorization checks in your system OpenFGA List Objects API Read the List Objects API documentation and see how it works. More","s":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/perform-list-objects","h":"#related-sections","p":244},{"i":257,"t":"The following list outlines some guidelines and best practices for running OpenFGA in a production environment: Configure Authentication Enable HTTP TLS or gRPC TLS or both Set the log.format to \"json\" Set the log.level to \"info\" Disable the Playground. Set Database Options Set Concurrency Limits","s":"Running OpenFGA in Production","u":"/pr-preview/pr-728/docs/getting-started/running-in-production","h":"","p":256},{"i":259,"t":"To ensure good performance for OpenFGA, it is recommended that the database be: Co-located in the same physical datacenter and network as your OpenFGA servers. This will minimize latency of database calls. Used exclusively for OpenFGA and not shared with other applications. This allows scaling the database independently and avoiding contention with your database. Bootstrapped and managed with the openfga migrate command. This will ensure the appropriate database indexes are created. It's strongly recommended to fine-tune your server database connection settings to avoid having to re-establish database connections frequently. Establishing database connections is slow and will negatively impact performance, and so here are some guidelines for managing database connection settings: The server setting OPENFGA_DATASTORE_MAX_OPEN_CONNS should be set to be equal to your database's max connections. For example, in Postgres, you can see this value via running the SQL query SHOW max_connections;. If you are running multiple instances of the OpenFGA server, you should divide this setting equally among the instances. For example, if your database's max_connections is 100, and you have 2 OpenFGA instances, OPENFGA_DATASTORE_MAX_OPEN_CONNS should be set to 50 for each instance. The OPENFGA_DATASTORE_MAX_IDLE_CONNS should be set to a value no greater than the maximum open connections (see the bullet point above), but it should be set sufficiently high enough to avoid having to recreate connections on each request. If, when monitoring your database stats, you see a lot of database connections being closed and subsequently reopened, then you should consider increasing the maximum number of idle connections. If idle connections are getting reaped frequently, then consider increasing the OPENFGA_DATASTORE_CONN_MAX_IDLE_TIME to a large value. When in doubt, prioritize keeping connections around for longer rather than shorter, because doing so will drastically improve performance.","s":"Database Recommendations","u":"/pr-preview/pr-728/docs/getting-started/running-in-production","h":"#database-recommendations","p":256},{"i":261,"t":"note Before modifying concurrency limits please make sure you've followed the guidance for Database Recommendations OpenFGA queries such as Check and ListObjects can be quite database and CPU intensive in some cases. If you notice that a single request is consuming a lot of CPU or creating a high degree of database contention, then you may consider setting some concurrency limits to protect other requests from being negatively impacted by overly aggressive queries. The following table enumerates the server's concurrency specific settings: flag env config --max-concurrent-reads-for-list-objects OPENFGA_MAX_CONCURRENT_READS_FOR_LIST_OBJECTS maxConcurrentReadsForListObjects --max-concurrent-reads-for-check OPENFGA_MAX_CONCURRENT_READS_FOR_CHECK maxConcurrentReadsForCheck --resolve-node-limit OPENFGA_RESOLVE_NODE_LIMIT resolveNodeLimit --resolve-node-breadth-limit OPENFGA_RESOLVE_NODE_BREADTH_LIMIT resolveNodeBreadthLimit Determining the right values for these settings will be based on a variety of factors including, but not limited to, the database specific deployment topology, the FGA model(s) involved, and the relationship tuples in the system. However, here are some high-level guidelines: If a single ListObjects query is negatively impacting other query endpoints by increasing their latency or their error rate, then consider setting a lower value for OPENFGA_MAX_CONCURRENT_READS_FOR_LIST_OBJECTS. If a single Check query is negatively impacting other query endpoints by increasing their latency or their error rate, then consider setting a lower value for OPENFGA_MAX_CONCURRENT_READS_FOR_CHECK. If you still see high request latencies despite the guidance above, then you may additionally consider setting stricter limits on the query resolution behavior by limiting the resolution depth and resolution breadth. These can be controlled with the OPENFGA_RESOLVE_NODE_LIMIT and OPENFGA_RESOLVE_NODE_BREADTH_LIMIT settings, respectively. Consider these guidelines: OPENFGA_RESOLVE_NODE_LIMIT limits the resolution depth of a single query, and thus it sets an upper bound on how deep a relationship hierarchy may be. A high value will allow a single query to involve more hierarchical resolution and therefore more database queries, while a low value will reduce the number of hierarchical resolutions that will be allowed and thus reduce the number of database queries. OPENFGA_RESOLVE_NODE_BREADTH_LIMIT limits the resolution breadth. It sets an upper bound on the number of in-flight resolutions that can be taking place on one or more usersets. A high value will allow a single query to involve more concurrent evaluations to take place and therefore more database queries and server processes, while a low value will reduce the overall number of concurrent resolutions that will be allowed and thus reduce the number of database queries and server processes.","s":"Concurrency Limits","u":"/pr-preview/pr-728/docs/getting-started/running-in-production","h":"#concurrency-limits","p":256},{"i":263,"t":"Check the following sections for more on how to run OpenFGA in production environment. Data and API Best Practices Learn the best practices for managing data and invoking APIs in production environment More Migrating Relations Learn how to migrate relations in a production environment More","s":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/running-in-production","h":"#related-sections","p":256},{"i":265,"t":"You can configure the OpenFGA server in three ways: Using a configuration file. Using environment variables. Using command line parameters. If the same option is configured in multiple ways the command line parameters will take precedence over environment variables, which will take precedence over the configuration file. The configuration options and their default values are defined in config-schema.json.","s":"Configuring OpenFGA","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"","p":264},{"i":267,"t":"You can configure the OpenFGA server with a config.yaml file, which can be specified in either: /etc/openfga $HOME/.openfga . (i.e., the current working directory). The OpenFGA server will search for the configuration file in the above order. Here is a sample configuration to run OpenFGA with a Postgres database and using a preshared key for authentication: datastore: engine: postgres uri: postgres://user:password@localhost:5432/mydatabase authn: method: preshared preshared: keys: [\"key1\", \"key2\"]","s":"Using a configuration file","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#using-a-configuration-file","p":264},{"i":269,"t":"The OpenFGA server supports environment variables for configuration, and they will take priority over your configuration file. Each variable must be prefixed with OPENFGA_ and followed by your option in uppercase (e.g. --grpc-tls-key becomes OPENFGA_GRPC_TLS_KEY).","s":"Using environment variables","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#using-environment-variables","p":264},{"i":271,"t":"Command line parameters take precedence over environment variables and options in the configuration file. They are prefixed with -- , e.g. openfga run --datastore-engine postgres \\ --datastore-uri 'postgres://postgres:password@postgres:5432/postgres?sslmode=disable'","s":"Using command line variables","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#using-command-line-variables","p":264},{"i":273,"t":"OpenFGA supports multiple storage engine options, including: memory - A memory storage engine, which is the default. Data is lost between server restarts. postgres - A Postgres storage engine. mysql - A MySQL storage engine. The first time you run OpenFGA, or when you install a new version, you need to run the openfga migrate command. This will create the required database tables or perform the database migration required for a new version.","s":"Configuring Data Storage","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#configuring-data-storage","p":264},{"i":275,"t":"openfga migrate --datastore-engine postgres \\ --datastore-uri 'postgres://postgres:password@postgres:5432/postgres?sslmode=disable' openfga run --datastore-engine postgres \\ --datastore-uri 'postgres://postgres:password@postgres:5432/postgres?sslmode=disable' To learn how to run in Docker, check our Docker documentation.","s":"Postgres","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#postgres","p":264},{"i":277,"t":"The MySQL datastore has stricter limits for the max length of some fields for tuples compared to other datastore engines, in particular: object type is at most 128 characters (down from 256) object id is at most 128 characters (down from 256) user is at most 256 characters (down from 512) The connection URI needs to specify the query parseTime=true. openfga migrate \\ --datastore-engine mysql \\ --datastore-uri 'root:secret@tcp(mysql:3306)/openfga?parseTime=true' openfga run \\ --datastore-engine mysql \\ --datastore-uri 'root:secret@tcp(mysql:3306)/openfga?parseTime=true' To learn how to run in Docker, check our Docker documentation.","s":"MySQL","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#mysql","p":264},{"i":279,"t":"You can configure authentication in three ways: no authentication (default) pre-shared key authentication OIDC","s":"Configuring Authentication","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#configuring-authentication","p":264},{"i":281,"t":"If using Pre-shared key authentication, you will configure OpenFGA with a secret key and your application calling OpenFGA will have to set an Authorization: Bearer header. You can configure multiple keys. Warning If you are going to use this setup in production, you should enable HTTP TLS in your OpenFGA server. You will need to configure the TLS certificate and key. Configuration File Environment Variables Update the config.yaml file to authn: method: preshared preshared: keys: [\"key1\", \"key2\"] http: tls: enabled: true cert: /Users/myuser/key/server.crt key: /Users/myuser/key/server.key Configure the authentication method to preshared: export OPENFGA_AUTHN_METHOD=preshared. Configure the authentication keys: export OPENFGA_AUTHN_PRESHARED_KEYS=\"key1,key2\" Enable the HTTP TLS configuration: export OPENFGA_HTTP_TLS_ENABLED=true Configure the HTTP TLS certificate location: export OPENFGA_HTTP_TLS_CERT=/Users/myuser/key/server.crt Configure the HTTP TLS key location: export OPENFGA_HTTP_TLS_KEY=/Users/myuser/key/server.key To learn how to run in Docker, check our Docker documentation.","s":"Pre-shared Key Authentication","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#pre-shared-key-authentication","p":264},{"i":283,"t":"To configure with OIDC authentication, you will first need to obtain the OIDC issuer and audience from your provider. Warning If you are going to use this setup in production, you should enable HTTP TLS in your OpenFGA server. You will need to configure the TLS certificate and key. Configuration File Environment Variables Update the config.yaml file to authn: method: oidc oidc: issuer: \"oidc-issuer\" audience: \"oidc-audience\" http: tls: enabled: true cert: /Users/myuser/key/server.crt key: /Users/myuser/key/server.key Configure the authentication method to preshared: export OPENFGA_AUTHN_METHOD=oidc. Configure the authentication keys: export OPENFGA_AUTHN_OIDC_ISSUER=oidc-issuer Configure the authentication keys: export OPENFGA_AUTHN_OIDC_audience=oidc-audience Enable the HTTP TLS configuration: export OPENFGA_HTTP_TLS_ENABLED=true Configure the HTTP TLS certificate location: export OPENFGA_HTTP_TLS_CERT=/Users/myuser/key/server.crt Configure the HTTP TLS key location: export OPENFGA_HTTP_TLS_KEY=/Users/myuser/key/server.key To learn how to run in Docker, check our Docker documentation.","s":"OIDC","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#oidc","p":264},{"i":285,"t":"Warning Continuous profiling can be used in production deployments, but we recommend disabling it unless it is needed to troubleshoot specific performance or memory problems. Profiling through pprof can be enabled on the OpenFGA server by providing the --profiler-enabled flag. For example: openfga run --profiler-enabled If you need to serve the profiler on a different port than the default 3001, you can do so by specifying the --profiler-addr flag. For example: openfga/openfga run --profiler-enabled --profiler-addr :3002 If you want to run it in docker: docker run -p 8080:8080 -p 8081:8081 -p 3000:3000 -p 3002:3002 openfga/openfga run --profiler-enabled --profiler-addr :3002","s":"Profiler (pprof)","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#profiler-pprof","p":264},{"i":287,"t":"OpenFGA is configured with an HTTP health check endpoint /healthz and a gRPC health check grpc.health.v1.Health/Check, which is wired to datastore testing. Possible response values are UNKNOWN SERVING NOT_SERVING SERVICE_UNKNOWN cURL gRPC curl -X GET $FGA_API_URL/healthz # {\"status\":\"SERVING\"} # See https://github.com/fullstorydev/grpcurl#installation grpcurl -plaintext $FGA_API_URL grpc.health.v1.Health/Check # {\"status\":\"SERVING\"}","s":"Health Check","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#health-check","p":264},{"i":289,"t":"Various releases of OpenFGA may have experimental features that can be enabled by providing the --experimentals flag or the experimentals config. openfga run --experimentals=\"feature1, feature2\" or if you're using environment variables, openfga -e OPENFGA_EXPERIMENTALS=\"feature1, feature2\" run The following table enumerates the experimental flags, a description of what they do, and the versions of OpenFGA the flag is supported in: Name Description OpenFGA Version otel-metrics Enables support for exposing OpenFGA metrics through OpenTelemetry 0.3.2 <= v < v0.3.5 list-objects Enables ListObjects API 0.2.0 <= v < v0.3.3 check-query-cache Enables caching of check subproblem result 1.3.1 <= v < v1.3.6 enable-conditions Enables conditional relationship tuples 1.3.8 <= v < v1.4.0 Warning Experimental features are not guaranteed to be stable and may lead to server instabilities. It is not recommended to enable experimental features for anything other than experimentation. Experimental feature flags are also not considered part of API compatibility and are subject to change, so please refer to each OpenFGA specific release for a list of the experimental feature flags that can be enabled for that release.","s":"Experimental Features","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#experimental-features","p":264},{"i":291,"t":"OpenFGA telemetry data is collected by default starting on version v0.3.5. The telemetry information that is captured includes Metrics, Traces, and Logs. note Please refer to the docker-compose.yaml file as an example of how to collect Metrics and Tracing in OpenFGA in a Docker environment using the OpenTelemetry Collector. This should serve as a good example that you can adjust for your specific deployment scenario.","s":"Telemetry","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#telemetry","p":264},{"i":293,"t":"OpenFGA metrics are collected with the Prometheus data format and exposed on address 0.0.0.0:2112/metrics. Metrics are exposed by default, but you can disable this with --metrics-enabled=false (or OPENFGA_METRICS_ENABLED=false environment variable). To set an alternative address, you can provide the --metrics-addr flag (OPENFGA_METRICS_ADDR environment variable). For example: openfga run --metrics-addr=0.0.0.0:2114 To see the request latency per endpoint of your OpenFGA deployment, you can provide the --metrics-enable-rpc-histograms flag (OPENFGA_METRICS_ENABLE_RPC_HISTOGRAMS environment variable).","s":"Metrics","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#metrics","p":264},{"i":295,"t":"OpenFGA traces can be collected with the OTLP data format. Tracing is disabled by default, but you can enable this with the --trace-enabled=true (OPENFGA_TRACE_ENABLED=true environment variable). Traces will be exported by default to address 0.0.0.0:4317. You can change this address with the --trace-otlp-endpoint flag (OPENFGA_TRACE_OTLP_ENDPOINT environment variable). To increase or decrease the trace sampling ratio, you can provide the --trace-sample-ratio flag (OPENFGA_TRACE_SAMPLE_RATIO env variable). Tracing by default uses a insecure connection. You can enable TLS by using --trace-otlp-tls-enabled=true flag or the environment variable OPENFGA_TRACE_OTLP_TLS_ENABLED. Warning It is not recommended to sample all traces (e.g. --trace-sample-ratio=1). You will need to adjust your sampling ratio based on the amount of traffic your deployment receives. Higher traffic will require less sampling and lower traffic can tolerate higher sampling ratios.","s":"Tracing","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#tracing","p":264},{"i":297,"t":"OpenFGA generates structured logs by default, and it can be configured with the following flags: --log-format: sets the log format. Today we support text and json format. --log-level: sets the minimum log level (defaults to info). It can be set to none to turn off logging.","s":"Logging","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#logging","p":264},{"i":299,"t":"Check the following sections for more on how to use OpenFGA. Production Best Practices Learn the best practices of running OpenFGA in a production environment More","s":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/configure-openfga","h":"#related-sections","p":264},{"i":301,"t":"This article explains how to run your own OpenFGA server using Docker. To learn the different ways to configure OpenFGA check Configuring OpenFGA.","s":"🐳 Setup OpenFGA with Docker","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/docker","h":"","p":300},{"i":303,"t":"If you want to run OpenFGA locally as a Docker container, follow these steps: Install Docker (if not already installed). Run docker pull openfga/openfga to get the latest docker image. Run docker run -p 8080:8080 -p 8081:8081 -p 3000:3000 openfga/openfga run. This will start an HTTP server and gRPC server with the default configuration options. Port 8080 is used to serve the HTTP API, 8081 is used to serve the gRPC API, and 3000 is used for the Playground.","s":"Step By Step","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/docker","h":"#step-by-step","p":300},{"i":305,"t":"Docker Docker Compose To run OpenFGA and Postgres in containers, you can create a new network to make communication between containers simpler: docker network create openfga You can then start Postgres in the network you created above: docker run -d --name postgres --network=openfga -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=password postgres:14 You should now have Postgres running in a container in the openfga network. However, it will not have the tables required for running OpenFGA. You can use the migrate command to create the tables. Using the OpenFGA container, this will look like: docker run --rm --network=openfga openfga/openfga migrate \\ --datastore-engine postgres \\ --datastore-uri \"postgres://postgres:password@postgres:5432/postgres?sslmode=disable\" Finally, start OpenFGA: docker run --name openfga --network=openfga -p 3000:3000 -p 8080:8080 -p 8081:8081 openfga/openfga run \\ --datastore-engine postgres \\ --datastore-uri 'postgres://postgres:password@postgres:5432/postgres?sslmode=disable' Copy the below code block into a local file named: docker-compose.yaml version: '3.8' networks: openfga: services: postgres: image: postgres:14 container_name: postgres networks: - openfga ports: - \"5432:5432\" environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=password healthcheck: test: [ \"CMD-SHELL\", \"pg_isready -U postgres\" ] interval: 5s timeout: 5s retries: 5 migrate: depends_on: postgres: condition: service_healthy image: openfga/openfga:latest container_name: migrate command: migrate environment: - OPENFGA_DATASTORE_ENGINE=postgres - OPENFGA_DATASTORE_URI=postgres://postgres:password@postgres:5432/postgres?sslmode=disable networks: - openfga openfga: depends_on: migrate: condition: service_completed_successfully image: openfga/openfga:latest container_name: openfga environment: - OPENFGA_DATASTORE_ENGINE=postgres - OPENFGA_DATASTORE_URI=postgres://postgres:password@postgres:5432/postgres?sslmode=disable - OPENFGA_LOG_FORMAT=json command: run networks: - openfga ports: # Needed for the http server - \"8080:8080\" # Needed for the grpc server (if used) - \"8081:8081\" # Needed for the playground (Do not enable in prod!) - \"3000:3000\" In a terminal, navigate to that directory and run: docker-compose up This will start the Postgres database, run openfga migrate to configure the database and finally start the OpenFGA server.","s":"Using Postgres","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/docker","h":"#using-postgres","p":300},{"i":307,"t":"Docker Docker Compose We first make a network: docker network create openfga Then, start MySQL in the network you created above: docker run -d --name mysql --network=openfga -e MYSQL_ROOT_PASSWORD=secret -e MYSQL_DATABASE=openfga mysql:8 You should now have MySQL running in a container in the openfga network. But we still have to migrate all the tables to be able to run OpenFGA. You can use the migrate command to create the tables. Using the OpenFGA container, this will look like: docker run --rm --network=openfga openfga/openfga migrate \\ --datastore-engine mysql \\ --datastore-uri 'root:secret@tcp(mysql:3306)/openfga?parseTime=true' Finally, start OpenFGA: docker run --name openfga --network=openfga -p 3000:3000 -p 8080:8080 -p 8081:8081 openfga/openfga run \\ --datastore-engine mysql \\ --datastore-uri 'root:secret@tcp(mysql:3306)/openfga?parseTime=true' Copy the below code block into a local file named: docker-compose.yaml version: '3.8' networks: openfga: services: mysql: image: mysql:8 container_name: mysql networks: - openfga ports: - \"3306:3306\" environment: - MYSQL_ROOT_PASSWORD=secret - MYSQL_DATABASE=openfga healthcheck: test: [\"CMD\", 'mysqladmin', 'ping', '-h', 'localhost', '-u', 'root', '-p$$MYSQL_ROOT_PASSWORD' ] timeout: 20s retries: 5 migrate: depends_on: mysql: condition: service_healthy image: openfga/openfga:latest container_name: migrate command: migrate environment: - OPENFGA_DATASTORE_ENGINE=mysql - OPENFGA_DATASTORE_URI=root:secret@tcp(mysql:3306)/openfga?parseTime=true networks: - openfga openfga: depends_on: migrate: condition: service_completed_successfully image: openfga/openfga:latest container_name: openfga environment: - OPENFGA_DATASTORE_ENGINE=mysql - OPENFGA_DATASTORE_URI=root:secret@tcp(mysql:3306)/openfga?parseTime=true - OPENFGA_LOG_FORMAT=json command: run networks: - openfga ports: # Needed for the http server - \"8080:8080\" # Needed for the grpc server (if used) - \"8081:8081\" # Needed for the playground (Do not enable in prod!) - \"3000:3000\" In a terminal, navigate to that directory and run: docker-compose up This will start the MySQL database, run openfga migrate to configure the database and finally start the OpenFGA server.","s":"Using MySQL","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/docker","h":"#using-mysql","p":300},{"i":309,"t":"To configure with pre-shared authentication and enabling TLS in http server with Docker. Copy the certificate and key files to your Docker container. Run with the following command: docker run --name openfga --network=openfga -p 3000:3000 -p 8080:8080 -p 8081:8081 openfga/openfga run \\ --authn-method=preshared \\ --authn-preshared-keys=\"key1,key2\" \\ --http-tls-enabled=true \\ --http-tls-cert=\"/Users/myuser/key/server.crt\" \\ --http-tls-key=\"/Users/myuser/key/server.key\"","s":"Pre-shared Key Authentication","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/docker","h":"#pre-shared-key-authentication","p":300},{"i":311,"t":"To configure with pre-shared authentication and enabling TLS in http server with Docker. Copy the certificate and key files to your docker container. Run the following command docker run --name openfga --network=openfga -p 3000:3000 -p 8080:8080 -p 8081:8081 openfga/openfga run \\ --authn-method=oidc \\ --authn-oidc-issuer=\"oidc-issuer\" \\ --authn-oidc-audience=\"oidc-audience\" \\ --http-tls-enabled=true \\ --http-tls-cert=\"/Users/myuser/key/server.crt\" \\ --http-tls-key=\"/Users/myuser/key/server.key\"","s":"OIDC Authentication","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/docker","h":"#oidc-authentication","p":300},{"i":313,"t":"If you are enabling profiling, make sure you enable the corresponding port in docker. The default port is 3001, but if you need to serve the profiler on a different port, you can do so by specifying the --profiler-addr flag. For example: docker run -p 8080:8080 -p 8081:8081 -p 3000:3000 -p 3002:3002 openfga/openfga run --profiler-enabled --profiler-addr :3002","s":"Enabling Profiling","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/docker","h":"#enabling-profiling","p":300},{"i":315,"t":"Check the following sections for more on how to use OpenFGA. Production Best Practices Learn the best practices of running OpenFGA in a production environment More","s":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/docker","h":"#related-sections","p":300},{"i":317,"t":"This article explains how to configure an authorization model for a store in an OpenFGA server.","s":"Configure Authorization Model for a Store","u":"/pr-preview/pr-728/docs/getting-started/configure-model","h":"","p":316},{"i":319,"t":"Node.js Go .NET Python Java CLI curl Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have installed the SDK, created the store and setup the SDK client. You have loaded FGA_STORE_ID and FGA_API_URL as environment variables. Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have installed the SDK, created the store and setup the SDK client. You have loaded FGA_STORE_ID and FGA_API_URL as environment variables. Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have installed the SDK, created the store and setup the SDK client. You have loaded FGA_STORE_ID and FGA_API_URL as environment variables. Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have installed the SDK, created the store and setup the SDK client. You have loaded FGA_STORE_ID and FGA_API_URL as environment variables. Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have installed the SDK, created the store and setup the SDK client. You have loaded FGA_STORE_ID and FGA_API_URL as environment variables. Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have installed the CLI, created the store and setup your environment variables. You have loaded FGA_STORE_ID and FGA_API_URL as environment variables. Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_URL and, if needed, FGA_API_TOKEN. You have created the store and have loaded FGA_STORE_ID and FGA_API_URL as environment variables.","s":"Before You Start","u":"/pr-preview/pr-728/docs/getting-started/configure-model","h":"#before-you-start","p":316},{"i":321,"t":"Assume that you want to configure your store with the following model. DSL JSON model schema 1.1 type user type document relations define reader: [user] define writer: [user] define owner: [user] { \"schema_version\": \"1.1\", \"type_definitions\": [ { \"type\": \"user\" }, { \"type\": \"document\", \"relations\": { \"reader\": { \"this\": {} }, \"writer\": { \"this\": {} }, \"owner\": { \"this\": {} } }, \"metadata\": { \"relations\": { \"reader\": { \"directly_related_user_types\": [ { \"type\": \"user\" } ] }, \"writer\": { \"directly_related_user_types\": [ { \"type\": \"user\" } ] }, \"owner\": { \"directly_related_user_types\": [ { \"type\": \"user\" } ] } } } } ] } To configure authorization model, we can invoke the write authorization models API. Node.js Go .NET Python Java CLI curl Initialize the SDK // ApiTokenIssuer, ApiAudience, ClientId and ClientSecret are optional. // import the SDK const { OpenFgaClient } = require('@openfga/sdk'); // Initialize the SDK with no auth - see \"How to setup SDK client\" for more options const fgaClient = new OpenFgaClient({ apiUrl: process.env.FGA_API_URL, // required, e.g. https://api.fga.example storeId: process.env.FGA_STORE_ID, authorizationModelId: process.env.FGA_MODEL_ID, // Optional, can be overridden per request }); const { authorization_model_id: id } = await fgaClient.writeAuthorizationModel({ \"schema_version\": \"1.1\", \"type_definitions\": [ { \"type\": \"user\" }, { \"type\": \"document\", \"relations\": { \"reader\": { \"this\": {} }, \"writer\": { \"this\": {} }, \"owner\": { \"this\": {} } }, \"metadata\": { \"relations\": { \"reader\": { \"directly_related_user_types\": [ { \"type\": \"user\" } ] }, \"writer\": { \"directly_related_user_types\": [ { \"type\": \"user\" } ] }, \"owner\": { \"directly_related_user_types\": [ { \"type\": \"user\" } ] } } } } ] }); // id = \"01HVMMBCMGZNT3SED4Z17ECXCA\" Initialize the SDK // ApiTokenIssuer, ApiAudience, ClientId and ClientSecret are optional. import ( \"os\" . \"github.com/openfga/go-sdk\" . \"github.com/openfga/go-sdk/client\" ) func main() { // Initialize the SDK with no auth - see \"How to setup SDK client\" for more options fgaClient, err := NewSdkClient(&ClientConfiguration{ ApiUrl: os.Getenv(\"FGA_API_URL\"), // required, e.g. https://api.fga.example StoreId: os.Getenv(\"FGA_STORE_ID\"), // optional, not needed for `CreateStore` and `ListStores`, required before calling for all other methods AuthorizationModelId: os.Getenv(\"FGA_MODEL_ID\"), // Optional, can be overridden per request }) if err != nil { // .. Handle error } } var writeAuthorizationModelRequestString = \"{\\\"schema_version\\\":\\\"1.1\\\",\\\"type_definitions\\\":[{\\\"type\\\":\\\"user\\\"},{\\\"type\\\":\\\"document\\\",\\\"relations\\\":{\\\"reader\\\":{\\\"this\\\":{}},\\\"writer\\\":{\\\"this\\\":{}},\\\"owner\\\":{\\\"this\\\":{}}},\\\"metadata\\\":{\\\"relations\\\":{\\\"reader\\\":{\\\"directly_related_user_types\\\":[{\\\"type\\\":\\\"user\\\"}]},\\\"writer\\\":{\\\"directly_related_user_types\\\":[{\\\"type\\\":\\\"user\\\"}]},\\\"owner\\\":{\\\"directly_related_user_types\\\":[{\\\"type\\\":\\\"user\\\"}]}}}}]}\" var body WriteAuthorizationModelRequest if err := json.Unmarshal([]byte(writeAuthorizationModelRequestString), &body); err != nil { // .. Handle error return } data, err := fgaClient.WriteAuthorizationModel(context.Background()). Body(body). Execute() if err != nil { // .. Handle error } // data.AuthorizationModelId = \"01HVMMBCMGZNT3SED4Z17ECXCA\" Initialize the SDK // ApiTokenIssuer, ApiAudience, ClientId and ClientSecret are optional. // import the SDK using OpenFga.Sdk.Client; using OpenFga.Sdk.Client.Model; using OpenFga.Sdk.Model; using Environment = System.Environment; namespace Example; class Example { public static async Task Main() { // Initialize the SDK with no auth - see \"How to setup SDK client\" for more options var configuration = new ClientConfiguration() { ApiUrl = Environment.GetEnvironmentVariable(\"FGA_API_URL\"), ?? \"http://localhost:8080\", // required, e.g. https://api.fga.example StoreId = Environment.GetEnvironmentVariable(\"FGA_STORE_ID\"), // optional, not needed for `CreateStore` and `ListStores`, required before calling for all other methods AuthorizationModelId = Environment.GetEnvironmentVariable(\"FGA_MODEL_ID\"), // Optional, can be overridden per request }; var fgaClient = new OpenFgaClient(configuration); } } var modelJson = \"{\\\"schema_version\\\":\\\"1.1\\\",\\\"type_definitions\\\":[{\\\"type\\\":\\\"user\\\"},{\\\"type\\\":\\\"document\\\",\\\"relations\\\":{\\\"reader\\\":{\\\"this\\\":{}},\\\"writer\\\":{\\\"this\\\":{}},\\\"owner\\\":{\\\"this\\\":{}}},\\\"metadata\\\":{\\\"relations\\\":{\\\"reader\\\":{\\\"directly_related_user_types\\\":[{\\\"type\\\":\\\"user\\\"}]},\\\"writer\\\":{\\\"directly_related_user_types\\\":[{\\\"type\\\":\\\"user\\\"}]},\\\"owner\\\":{\\\"directly_related_user_types\\\":[{\\\"type\\\":\\\"user\\\"}]}}}}]}\"; var body = JsonSerializer.Deserialize(modelJson); var response = await fgaClient.WriteAuthorizationModel(body); // response.AuthorizationModelId = \"01HVMMBCMGZNT3SED4Z17ECXCA\" Initialize the SDK # ApiTokenIssuer, ApiAudience, ClientId and ClientSecret are optional. import asyncio import os import json from openfga_sdk.client import ClientConfiguration, OpenFgaClient async def main(): configuration = ClientConfiguration( api_url = os.environ.get('FGA_API_URL'), # required, e.g. https://api.fga.example store_id = os.environ.get('FGA_STORE_ID'), # optional, not needed for `CreateStore` and `ListStores`, required before calling for all other methods authorization_model_id = os.environ.get('FGA_MODEL_ID'), # Optional, can be overridden per request ) # Enter a context with an instance of the OpenFgaClient async with OpenFgaClient(configuration) as fga_client: api_response = await fga_client.read_authorization_models() await fga_client.close() asyncio.run(main()) # from openfga_sdk.models.write_authorization_model_request import WriteAuthorizationModelRequest async def write_authorization_model(): body_string = \"{\\\"schema_version\\\":\\\"1.1\\\",\\\"type_definitions\\\":[{\\\"type\\\":\\\"user\\\"},{\\\"type\\\":\\\"document\\\",\\\"relations\\\":{\\\"reader\\\":{\\\"this\\\":{}},\\\"writer\\\":{\\\"this\\\":{}},\\\"owner\\\":{\\\"this\\\":{}}},\\\"metadata\\\":{\\\"relations\\\":{\\\"reader\\\":{\\\"directly_related_user_types\\\":[{\\\"type\\\":\\\"user\\\"}]},\\\"writer\\\":{\\\"directly_related_user_types\\\":[{\\\"type\\\":\\\"user\\\"}]},\\\"owner\\\":{\\\"directly_related_user_types\\\":[{\\\"type\\\":\\\"user\\\"}]}}}}]}\" response = await fga_client_instance.write_authorization_model(json.loads(body)) # response.authorization_model_id = \"01HVMMBCMGZNT3SED4Z17ECXCA\" Initialize the SDK // ApiTokenIssuer, ApiAudience, ClientId and ClientSecret are optional. import dev.openfga.sdk.api.client.OpenFgaClient; import dev.openfga.sdk.api.configuration.ClientConfiguration; public class Example { public static void main(String[] args) throws Exception { var config = new ClientConfiguration() .apiUrl(System.getenv(\"FGA_API_URL\")) // If not specified, will default to \"https://localhost:8080\" .storeId(System.getenv(\"FGA_STORE_ID\")) // Not required when calling createStore() or listStores() .authorizationModelId(System.getenv(\"FGA_AUTHORIZATION_MODEL_ID\")); // Optional, can be overridden per request var fgaClient = new OpenFgaClient(config); } } // import com.fasterxml.jackson.databind.ObjectMapper; // import dev.openfga.sdk.api.model.WriteAuthorizationModelRequest; var mapper = new ObjectMapper().findAndRegisterModules(); var authorizationModel = fgaClient .writeAuthorizationModel(mapper.readValue(\"{\\\"schema_version\\\":\\\"1.1\\\",\\\"type_definitions\\\":[{\\\"type\\\":\\\"user\\\"},{\\\"type\\\":\\\"document\\\",\\\"relations\\\":{\\\"reader\\\":{\\\"this\\\":{}},\\\"writer\\\":{\\\"this\\\":{}},\\\"owner\\\":{\\\"this\\\":{}}},\\\"metadata\\\":{\\\"relations\\\":{\\\"reader\\\":{\\\"directly_related_user_types\\\":[{\\\"type\\\":\\\"user\\\"}]},\\\"writer\\\":{\\\"directly_related_user_types\\\":[{\\\"type\\\":\\\"user\\\"}]},\\\"owner\\\":{\\\"directly_related_user_types\\\":[{\\\"type\\\":\\\"user\\\"}]}}}}]}\", WriteAuthorizationModelRequest.class)) .get(); Set FGA_API_URL according to the service you are using (e.g. https://api.fga.example) Set FGA_API_URL according to the service you are using (e.g. https://api.fga.example) fga model write --store-id=${FGA_STORE_ID} {\"schema_version\":\"1.1\",\"type_definitions\":[{\"type\":\"user\"},{\"type\":\"document\",\"relations\":{\"reader\":{\"this\":{}},\"writer\":{\"this\":{}},\"owner\":{\"this\":{}}},\"metadata\":{\"relations\":{\"reader\":{\"directly_related_user_types\":[{\"type\":\"user\"}]},\"writer\":{\"directly_related_user_types\":[{\"type\":\"user\"}]},\"owner\":{\"directly_related_user_types\":[{\"type\":\"user\"}]}}}}]} Set FGA_API_URL according to the service you are using (e.g. https://api.fga.example) Set FGA_API_URL according to the service you are using (e.g. https://api.fga.example) curl -X POST $FGA_API_URL/stores/$FGA_STORE_ID/authorization-models \\ -H \"Authorization: Bearer $FGA_API_TOKEN\" \\ # Not needed if service does not require authorization -H \"content-type: application/json\" \\ -d '{\"schema_version\":\"1.1\",\"type_definitions\":[{\"type\":\"user\"},{\"type\":\"document\",\"relations\":{\"reader\":{\"this\":{}},\"writer\":{\"this\":{}},\"owner\":{\"this\":{}}},\"metadata\":{\"relations\":{\"reader\":{\"directly_related_user_types\":[{\"type\":\"user\"}]},\"writer\":{\"directly_related_user_types\":[{\"type\":\"user\"}]},\"owner\":{\"directly_related_user_types\":[{\"type\":\"user\"}]}}}}]}' The API will then return the authorization model ID. Note The OpenFGA API only accepts an authorization model in the API's JSON syntax. To convert between the API Syntax and the friendly DSL, you can use the FGA CLI.","s":"Step By Step","u":"/pr-preview/pr-728/docs/getting-started/configure-model","h":"#step-by-step","p":316},{"i":323,"t":"Take a look at the following sections for more information on how to configure authorization model in your store. Getting Started with Modeling Read how to get started with modeling. More Modeling: Direct Relationships Read the basics of modeling authorization and granting access to users. More","s":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/configure-model","h":"#related-sections","p":316},{"i":325,"t":"To deploy OpenFGA into a Kubernetes environment you can use the official OpenFGA Helm chart. Please refer to the official documentation on Artifact Hub for the Helm chart for more instructions.","s":"☸️ Setup OpenFGA with Kubernetes","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/kubernetes","h":"","p":324},{"i":327,"t":"Follow the guides below to set up an OpenFGA server. Configure an OpenFGA Server How to setup an OpenFGA server. Click to navigate Docker Setup Guide How to setup an OpenFGA server with Docker. Click to navigate Kubernetes Setup Guide How to setup an OpenFGA server with Kubernetes. Click to navigate","s":"Setup OpenFGA","u":"/pr-preview/pr-728/docs/getting-started/setup-openfga/overview","h":"","p":326},{"i":329,"t":"The following list outlines some guidelines and best practices for using OpenFGA: Do not store Personal Identifiable Information in tuples Always specify authorization model ID whenever possible","s":"Best Practices of Managing Tuples and Invoking APIs","u":"/pr-preview/pr-728/docs/getting-started/tuples-api-best-practices","h":"","p":328},{"i":331,"t":"You can use any string for user and object identifiers, however you should not input or assign identifiers that include Personal Data or any other sensitive data, such as data that may be restricted under regulatory requirements. Note The documentation and samples uses first names and simple ids to illustrate easy-to-follow examples.","s":"Do Not Store Personal Identifiable Information in Tuples","u":"/pr-preview/pr-728/docs/getting-started/tuples-api-best-practices","h":"#do-not-store-personal-identifiable-information-in-tuples","p":328},{"i":333,"t":"It is strongly recommended that authorization model ID be specified in your Relationship Queries (such as Check and ListObjects) and Relationship Commands (such as Write). Specifying authorization model ID in API calls have the following advantages: Better performance as OpenFGA will not need to perform a database query to get the latest authorization model ID. Allows consistent behavior in your production system until you are ready to switch to the new model.","s":"Always Specify Authorization Model ID Whenever Possible","u":"/pr-preview/pr-728/docs/getting-started/tuples-api-best-practices","h":"#always-specify-authorization-model-id-whenever-possible","p":328},{"i":335,"t":"Check the following sections for more on recommendation for managing relations and model in production environment. Migrating Relations Learn how to migrate relations in a production environment More","s":"Related Sections","u":"/pr-preview/pr-728/docs/getting-started/tuples-api-best-practices","h":"#related-sections","p":328},{"i":337,"t":"The Playground facilitates rapid development by allowing you to visualize and model your application's authorization models and manage relationship tuples with a locally running OpenFGA instance. It is enabled on port 3000 by default and accessible at http://localhost:3000/playground. The Playground is designed for early prototyping and learning. It has several limitations: It works by embedding the public Playground website in an