[{"data":1,"prerenderedAt":2103},["ShallowReactive",2],{"navigation_docs_en":3,"-en-reference-extensions-data-connectors-permissions":445,"-en-reference-extensions-data-connectors-permissions-surround":2098},[4,30,72,132,260,436],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting Started",false,"\u002Fen\u002Fgetting-started","en\u002F1.getting-started",[10,15,20,25],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fen\u002Fgetting-started\u002Fintroduction","en\u002F1.getting-started\u002F2.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Quickstart","\u002Fen\u002Fgetting-started\u002Finstallation","en\u002F1.getting-started\u002F3.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Use Cases","\u002Fen\u002Fgetting-started\u002Fuse-cases","en\u002F1.getting-started\u002F4.use-cases","i-lucide-layers",{"title":26,"path":27,"stem":28,"icon":29},"Concepts","\u002Fen\u002Fgetting-started\u002Fconcepts","en\u002F1.getting-started\u002F5.concepts","i-lucide-book",{"title":26,"path":31,"stem":32,"children":33,"page":6},"\u002Fen\u002Fconcepts","en\u002F2.concepts",[34,38,43,48,53,58,63,68],{"title":35,"path":36,"stem":37,"icon":14},"Organization","\u002Fen\u002Fconcepts\u002Forganization","en\u002F2.concepts\u002F1.organization",{"title":39,"path":40,"stem":41,"icon":42},"Data Model","\u002Fen\u002Fconcepts\u002Fdata-model","en\u002F2.concepts\u002F2.data-model","i-lucide-database",{"title":44,"path":45,"stem":46,"icon":47},"Access Control","\u002Fen\u002Fconcepts\u002Faccess-permissions","en\u002F2.concepts\u002F3.access-permissions","i-lucide-user-key",{"title":49,"path":50,"stem":51,"icon":52},"Audit Logs","\u002Fen\u002Fconcepts\u002Faudit-logs","en\u002F2.concepts\u002F4.audit-logs","i-lucide-scroll-text",{"title":54,"path":55,"stem":56,"icon":57},"Introspection","\u002Fen\u002Fconcepts\u002Fintrospection","en\u002F2.concepts\u002F6.introspection","i-lucide-database-search",{"title":59,"path":60,"stem":61,"icon":62},"Query Engine","\u002Fen\u002Fconcepts\u002Fquery-engine","en\u002F2.concepts\u002F7.query-engine","i-lucide-workflow",{"title":64,"path":65,"stem":66,"icon":67},"AI","\u002Fen\u002Fconcepts\u002Fai","en\u002F2.concepts\u002F8.ai","i-lucide-sparkles",{"title":69,"path":70,"stem":71,"icon":42},"Caching","\u002Fen\u002Fconcepts\u002Fcaching","en\u002F2.concepts\u002F9.caching",{"title":73,"path":74,"stem":75,"children":76,"page":6},"Guides","\u002Fen\u002Fguides","en\u002F4.guides",[77,82,87,92,97,102,107,112],{"title":78,"path":79,"stem":80,"icon":81},"REST API Quickstart","\u002Fen\u002Fguides\u002Frest-api","en\u002F4.guides\u002F1.rest-api","i-lucide-plug",{"title":83,"path":84,"stem":85,"icon":86},"SDK Quickstart","\u002Fen\u002Fguides\u002Fsdk","en\u002F4.guides\u002F2.sdk","i-lucide-terminal",{"title":88,"path":89,"stem":90,"icon":91},"Configure SSO","\u002Fen\u002Fguides\u002Fconfigure-sso","en\u002F4.guides\u002F3.configure-sso","i-lucide-key-round",{"title":93,"path":94,"stem":95,"icon":96},"Configure MCP","\u002Fen\u002Fguides\u002Fmcp","en\u002F4.guides\u002F4.mcp","i-lucide-brain-cog",{"title":98,"path":99,"stem":100,"icon":101},"Customize Content Space","\u002Fen\u002Fguides\u002Fcustomize-content-space","en\u002F4.guides\u002F5.customize-content-space","i-lucide-columns-3-cog",{"title":103,"path":104,"stem":105,"icon":106},"Build an Application with AI Assistance","\u002Fen\u002Fguides\u002Fbuild-an-application","en\u002F4.guides\u002F6.build-an-application","i-lucide-route",{"title":108,"path":109,"stem":110,"icon":111},"Horizontal Scaling","\u002Fen\u002Fguides\u002Fhorizontal-scaling","en\u002F4.guides\u002F7.horizontal-scaling","i-lucide-network",{"title":113,"icon":114,"path":115,"stem":116,"children":117,"page":6},"Data Connectors","i-lucide-cable","\u002Fen\u002Fguides\u002Fdata-connectors","en\u002F4.guides\u002F8.data-connectors",[118,122,127],{"title":16,"path":119,"stem":120,"icon":121},"\u002Fen\u002Fguides\u002Fdata-connectors\u002Fquickstart","en\u002F4.guides\u002F8.data-connectors\u002F1.quickstart","i-lucide-rocket",{"title":123,"path":124,"stem":125,"icon":126},"Build a Stripe Connector","\u002Fen\u002Fguides\u002Fdata-connectors\u002Fstripe","en\u002F4.guides\u002F8.data-connectors\u002F2.stripe","i-lucide-hammer",{"title":128,"path":129,"stem":130,"icon":131},"Build with AI Agents","\u002Fen\u002Fguides\u002Fdata-connectors\u002Fai-agents","en\u002F4.guides\u002F8.data-connectors\u002F3.ai-agents","i-lucide-bot",{"title":133,"path":134,"stem":135,"children":136,"page":6},"Developer","\u002Fen\u002Fdeveloper","en\u002F5.developer",[137,191,215,220],{"title":138,"path":139,"stem":140,"children":141,"page":6},"Data Access","\u002Fen\u002Fdeveloper\u002Fapi","en\u002F5.developer\u002F1.api",[142,147,152,157,162,167,172,177,182,186],{"title":143,"path":144,"stem":145,"icon":146},"Overview","\u002Fen\u002Fdeveloper\u002Fapi\u002Foverview","en\u002F5.developer\u002F1.api\u002F1.overview","i-lucide-globe",{"title":148,"path":149,"stem":150,"icon":151},"Errors","\u002Fen\u002Fdeveloper\u002Fapi\u002Ferrors","en\u002F5.developer\u002F1.api\u002F10.errors","i-lucide-alert-triangle",{"title":153,"path":154,"stem":155,"icon":156},"Authentication","\u002Fen\u002Fdeveloper\u002Fapi\u002Fauthentication","en\u002F5.developer\u002F1.api\u002F2.authentication","i-lucide-lock",{"title":158,"path":159,"stem":160,"icon":161},"Reading Data","\u002Fen\u002Fdeveloper\u002Fapi\u002Freading-data","en\u002F5.developer\u002F1.api\u002F3.reading-data","i-lucide-book-open",{"title":163,"path":164,"stem":165,"icon":166},"Writing Data","\u002Fen\u002Fdeveloper\u002Fapi\u002Fwriting-data","en\u002F5.developer\u002F1.api\u002F4.writing-data","i-lucide-pencil",{"title":168,"path":169,"stem":170,"icon":171},"Filtering","\u002Fen\u002Fdeveloper\u002Fapi\u002Ffiltering","en\u002F5.developer\u002F1.api\u002F5.filtering","i-lucide-filter",{"title":173,"path":174,"stem":175,"icon":176},"Field Selection","\u002Fen\u002Fdeveloper\u002Fapi\u002Ffield-selection","en\u002F5.developer\u002F1.api\u002F6.field-selection","i-lucide-list-checks",{"title":178,"path":179,"stem":180,"icon":181},"Sorting & Pagination","\u002Fen\u002Fdeveloper\u002Fapi\u002Fsorting-pagination","en\u002F5.developer\u002F1.api\u002F7.sorting-pagination","i-lucide-arrow-up-down",{"title":183,"path":184,"stem":185,"icon":111},"Relational Data","\u002Fen\u002Fdeveloper\u002Fapi\u002Frelational-data","en\u002F5.developer\u002F1.api\u002F8.relational-data",{"title":187,"path":188,"stem":189,"icon":190},"Files & Assets","\u002Fen\u002Fdeveloper\u002Fapi\u002Ffiles","en\u002F5.developer\u002F1.api\u002F9.files","i-lucide-file-up",{"title":192,"path":193,"stem":194,"children":195,"page":6},"Client SDK","\u002Fen\u002Fdeveloper\u002Fsdk","en\u002F5.developer\u002F2.sdk",[196,200,205,210],{"title":197,"path":198,"stem":199,"icon":19},"Installation","\u002Fen\u002Fdeveloper\u002Fsdk\u002Finstallation","en\u002F5.developer\u002F2.sdk\u002F1.installation",{"title":201,"path":202,"stem":203,"icon":204},"Client Setup","\u002Fen\u002Fdeveloper\u002Fsdk\u002Fclient-setup","en\u002F5.developer\u002F2.sdk\u002F2.client-setup","i-lucide-settings",{"title":206,"path":207,"stem":208,"icon":209},"Type System","\u002Fen\u002Fdeveloper\u002Fsdk\u002Ftype-system","en\u002F5.developer\u002F2.sdk\u002F3.type-system","i-lucide-braces",{"title":211,"path":212,"stem":213,"icon":214},"Advanced","\u002Fen\u002Fdeveloper\u002Fsdk\u002Fadvanced","en\u002F5.developer\u002F2.sdk\u002F5.advanced","i-lucide-puzzle",{"title":216,"path":217,"stem":218,"icon":219},"Application Users","\u002Fen\u002Fdeveloper\u002Fapplication-users","en\u002F5.developer\u002F3.application-users","i-lucide-users",{"title":221,"path":222,"stem":223,"children":224,"icon":214},"Extensions","\u002Fen\u002Fdeveloper\u002Fextensions","en\u002F5.developer\u002F3.extensions\u002Findex",[225,226,231],{"title":143,"path":222,"stem":223,"icon":214},{"title":227,"path":228,"stem":229,"icon":230},"Install and Manage Extensions","\u002Fen\u002Fdeveloper\u002Fextensions\u002Finstall","en\u002F5.developer\u002F3.extensions\u002F1.install","i-lucide-package-plus",{"title":113,"path":232,"stem":233,"children":234,"icon":114},"\u002Fen\u002Fdeveloper\u002Fextensions\u002Fdata-connectors","en\u002F5.developer\u002F3.extensions\u002F2.data-connectors\u002Findex",[235,236,241,245,250,255],{"title":143,"path":232,"stem":233,"icon":114},{"title":237,"path":238,"stem":239,"icon":240},"How Data Connectors Run","\u002Fen\u002Fdeveloper\u002Fextensions\u002Fdata-connectors\u002Fruntime","en\u002F5.developer\u002F3.extensions\u002F2.data-connectors\u002F2.runtime","i-lucide-cpu",{"title":242,"path":243,"stem":244,"icon":42},"Data Sources","\u002Fen\u002Fdeveloper\u002Fextensions\u002Fdata-connectors\u002Fdata-sources","en\u002F5.developer\u002F3.extensions\u002F2.data-connectors\u002F3.data-sources",{"title":246,"path":247,"stem":248,"icon":249},"Map an External Data Source","\u002Fen\u002Fdeveloper\u002Fextensions\u002Fdata-connectors\u002Fdata-source-mapping","en\u002F5.developer\u002F3.extensions\u002F2.data-connectors\u002F4.data-source-mapping","i-lucide-map",{"title":251,"path":252,"stem":253,"icon":254},"Handle Errors","\u002Fen\u002Fdeveloper\u002Fextensions\u002Fdata-connectors\u002Ferrors","en\u002F5.developer\u002F3.extensions\u002F2.data-connectors\u002F5.errors","i-lucide-shield-alert",{"title":256,"path":257,"stem":258,"icon":259},"Test a Data Connector","\u002Fen\u002Fdeveloper\u002Fextensions\u002Fdata-connectors\u002Ftesting","en\u002F5.developer\u002F3.extensions\u002F2.data-connectors\u002F6.testing","i-lucide-flask-conical",{"title":261,"path":262,"stem":263,"children":264,"page":6},"Reference","\u002Fen\u002Freference","en\u002F6.reference",[265,269,274,279,295,299,304,340,369,374],{"title":266,"path":267,"stem":268,"icon":204},"Configuration","\u002Fen\u002Freference\u002Fenvironment-variables","en\u002F6.reference\u002F1.environment-variables",{"title":270,"path":271,"stem":272,"icon":273},"System Requirements","\u002Fen\u002Freference\u002Fsystem-requirements","en\u002F6.reference\u002F2.system-requirements","i-lucide-server",{"title":275,"path":276,"stem":277,"icon":278},"Licensing","\u002Fen\u002Freference\u002Flicensing","en\u002F6.reference\u002F3.licensing","i-lucide-gem",{"title":280,"path":281,"stem":282,"children":283,"icon":81},"Connectors","\u002Fen\u002Freference\u002Fconnectors","en\u002F6.reference\u002F4.connectors\u002Findex",[284,285,290],{"title":280,"path":281,"stem":282,"icon":81},{"title":286,"path":287,"stem":288,"icon":289},"PostgreSQL and Supabase","\u002Fen\u002Freference\u002Fconnectors\u002Fpostgresql-supabase","en\u002F6.reference\u002F4.connectors\u002F1.postgresql-supabase","i-simple-icons-postgresql",{"title":291,"path":292,"stem":293,"icon":294},"MySQL and MariaDB","\u002Fen\u002Freference\u002Fconnectors\u002Fmysql-mariadb","en\u002F6.reference\u002F4.connectors\u002F2.mysql-mariadb","i-simple-icons-mysql",{"title":296,"path":297,"stem":298,"icon":209},"Data Types Representation","\u002Fen\u002Freference\u002Fdata-types","en\u002F6.reference\u002F5.data-types",{"title":300,"path":301,"stem":302,"icon":303},"Permissions Reference","\u002Fen\u002Freference\u002Fpermissions","en\u002F6.reference\u002F6.permissions","i-lucide-shield",{"title":305,"path":306,"stem":307,"children":308,"page":6},"API Reference","\u002Fen\u002Freference\u002Fapi-reference","en\u002F6.reference\u002F7.api-reference",[309,313,318],{"title":310,"path":311,"stem":312,"icon":273},"System Endpoints","\u002Fen\u002Freference\u002Fapi-reference\u002Fsystem-endpoints","en\u002F6.reference\u002F7.api-reference\u002F1.system-endpoints",{"title":314,"path":315,"stem":316,"icon":317},"OpenAPI Spec","\u002Fen\u002Freference\u002Fapi-reference\u002Fopenapi-spec","en\u002F6.reference\u002F7.api-reference\u002F2.openapi-spec","i-lucide-file-code",{"title":319,"path":320,"stem":321,"children":322,"icon":324},"Schema Migration","\u002Fen\u002Freference\u002Fapi-reference\u002Fschema-migration","en\u002F6.reference\u002F7.api-reference\u002F3.schema-migration\u002Findex",[323,325,330,335],{"title":319,"path":320,"stem":321,"icon":324},"i-lucide-database-zap",{"title":326,"path":327,"stem":328,"icon":329},"Apply Migrations","\u002Fen\u002Freference\u002Fapi-reference\u002Fschema-migration\u002Fapply-migrations","en\u002F6.reference\u002F7.api-reference\u002F3.schema-migration\u002F1.apply-migrations","i-lucide-upload",{"title":331,"path":332,"stem":333,"icon":334},"Import Changes","\u002Fen\u002Freference\u002Fapi-reference\u002Fschema-migration\u002Fimport-changes","en\u002F6.reference\u002F7.api-reference\u002F3.schema-migration\u002F2.import-changes","i-lucide-refresh-cw",{"title":336,"path":337,"stem":338,"icon":339},"Operation Reference","\u002Fen\u002Freference\u002Fapi-reference\u002Fschema-migration\u002Foperation-reference","en\u002F6.reference\u002F7.api-reference\u002F3.schema-migration\u002F3.operation-reference","i-lucide-list-tree",{"title":341,"path":342,"stem":343,"children":344,"page":6},"Design Considerations","\u002Fen\u002Freference\u002Fdesign-considerations","en\u002F6.reference\u002F8.design-considerations",[345,349,354,359,364],{"title":143,"path":346,"stem":347,"icon":348},"\u002Fen\u002Freference\u002Fdesign-considerations\u002Foverview","en\u002F6.reference\u002F8.design-considerations\u002F1.overview","i-lucide-compass",{"title":350,"path":351,"stem":352,"icon":353},"Instance Configuration","\u002Fen\u002Freference\u002Fdesign-considerations\u002Finstance-configuration-related-problems","en\u002F6.reference\u002F8.design-considerations\u002F3.instance-configuration-related-problems","i-lucide-wrench",{"title":355,"path":356,"stem":357,"icon":358},"Overly Permissive Public Access","\u002Fen\u002Freference\u002Fdesign-considerations\u002Foverly-permissive","en\u002F6.reference\u002F8.design-considerations\u002F4.overly-permissive","i-lucide-shield-off",{"title":360,"path":361,"stem":362,"icon":363},"No Aggregates","\u002Fen\u002Freference\u002Fdesign-considerations\u002Fno-aggregates","en\u002F6.reference\u002F8.design-considerations\u002F5.no-aggregates","i-lucide-sigma",{"title":365,"path":366,"stem":367,"icon":368},"Cross-Data-Source Referential Integrity","\u002Fen\u002Freference\u002Fdesign-considerations\u002Fcross-data-source-referential-integrity","en\u002F6.reference\u002F8.design-considerations\u002F6.cross-data-source-referential-integrity","i-lucide-unlink",{"title":370,"path":371,"stem":372,"icon":373},"CLI","\u002Fen\u002Freference\u002Fcli","en\u002F6.reference\u002F9.cli","i-lucide-square-terminal",{"title":221,"path":375,"stem":376,"children":377,"page":6},"\u002Fen\u002Freference\u002Fextensions","en\u002F6.reference\u002F9.extensions",[378,383,386,405],{"title":379,"path":380,"stem":381,"icon":382},"Extension Config and Manifest","\u002Fen\u002Freference\u002Fextensions\u002Fmanifest","en\u002F6.reference\u002F9.extensions\u002F1.manifest","i-lucide-file-json",{"title":370,"path":384,"stem":385,"icon":86},"\u002Fen\u002Freference\u002Fextensions\u002Fcli","en\u002F6.reference\u002F9.extensions\u002F2.cli",{"title":387,"path":388,"stem":389,"children":390,"page":6},"Extension Kit","\u002Fen\u002Freference\u002Fextensions\u002Fextension-kit","en\u002F6.reference\u002F9.extensions\u002F3.extension-kit",[391,395,400],{"title":392,"path":393,"stem":394,"icon":81},"Data Connector","\u002Fen\u002Freference\u002Fextensions\u002Fextension-kit\u002Fdata-connector","en\u002F6.reference\u002F9.extensions\u002F3.extension-kit\u002F1.data-connector",{"title":396,"path":397,"stem":398,"icon":399},"Protocol","\u002Fen\u002Freference\u002Fextensions\u002Fextension-kit\u002Fprotocol","en\u002F6.reference\u002F9.extensions\u002F3.extension-kit\u002F2.protocol","i-lucide-arrow-left-right",{"title":401,"path":402,"stem":403,"icon":404},"Schema Helpers","\u002Fen\u002Freference\u002Fextensions\u002Fextension-kit\u002Fexperimental","en\u002F6.reference\u002F9.extensions\u002F3.extension-kit\u002F3.experimental","i-lucide-blocks",{"title":113,"path":406,"stem":407,"children":408,"page":6},"\u002Fen\u002Freference\u002Fextensions\u002Fdata-connectors","en\u002F6.reference\u002F9.extensions\u002F4.data-connectors",[409,413,417,421,426,431],{"title":410,"path":411,"stem":412,"icon":81},"Data Connector API","\u002Fen\u002Freference\u002Fextensions\u002Fdata-connectors\u002Fapi","en\u002F6.reference\u002F9.extensions\u002F4.data-connectors\u002F1.api",{"title":414,"path":415,"stem":416,"icon":176},"Operations and Operators","\u002Fen\u002Freference\u002Fextensions\u002Fdata-connectors\u002Foperations","en\u002F6.reference\u002F9.extensions\u002F4.data-connectors\u002F2.operations",{"title":148,"path":418,"stem":419,"icon":420},"\u002Fen\u002Freference\u002Fextensions\u002Fdata-connectors\u002Ferrors","en\u002F6.reference\u002F9.extensions\u002F4.data-connectors\u002F3.errors","i-lucide-triangle-alert",{"title":422,"path":423,"stem":424,"icon":425},"Runtime Limits","\u002Fen\u002Freference\u002Fextensions\u002Fdata-connectors\u002Flimits","en\u002F6.reference\u002F9.extensions\u002F4.data-connectors\u002F4.limits","i-lucide-gauge",{"title":427,"path":428,"stem":429,"icon":430},"Limitations","\u002Fen\u002Freference\u002Fextensions\u002Fdata-connectors\u002Flimitations","en\u002F6.reference\u002F9.extensions\u002F4.data-connectors\u002F5.limitations","i-lucide-ban",{"title":432,"path":433,"stem":434,"icon":435},"Network Permissions","\u002Fen\u002Freference\u002Fextensions\u002Fdata-connectors\u002Fpermissions","en\u002F6.reference\u002F9.extensions\u002F4.data-connectors\u002F6.permissions","i-lucide-shield-check",{"title":437,"icon":121,"path":438,"stem":439,"children":440,"page":6},"Release Notes","\u002Fen\u002Frelease-notes","en\u002F7.release-notes",[441],{"title":442,"path":443,"stem":444,"icon":121},"Changelog","\u002Fen\u002Frelease-notes\u002Fchangelog","en\u002F7.release-notes\u002F1.changelog",{"id":446,"title":432,"body":447,"description":2091,"extension":2092,"links":2093,"meta":2094,"navigation":2095,"path":433,"seo":2096,"stem":434,"__hash__":2097},"docs_en\u002Fen\u002F6.reference\u002F9.extensions\u002F4.data-connectors\u002F6.permissions.md",{"type":448,"value":449,"toc":2074},"minimark",[450,453,457,470,482,485,543,550,557,561,575,628,670,675,689,876,879,883,886,909,915,928,934,943,995,1017,1020,1032,1045,1049,1070,1080,1106,1167,1171,1174,1386,1410,1425,1429,1432,1521,1532,1536,1545,1746,1753,1780,1783,1789,1803,1807,1828,1891,1911,1980,1994,1997,2000,2003,2025,2032,2036,2070],[451,452],"preview",{},[454,455,143],"h2",{"id":456},"overview",[458,459,460,461,465,466,469],"p",{},"A data connector extension reaches only the hosts it was granted. Every other network request from its code fails. The connector declares the hosts it needs as ",[462,463,464],"code",{},"net:"," permissions in its entry's ",[462,467,468],{},"engine.permissions",".",[458,471,472,473,477,478,481],{},"The grant belongs to each ",[474,475,476],"strong",{},"data source",": the connector configured in a ",[474,479,480],{},"workspace"," (a container with its own members, roles and data sources). Whoever creates the data source approves the grant, and the data source stores it.",[458,483,484],{},"For a data connector, the required set comes from two places:",[486,487,488,504],"table",{},[489,490,491],"thead",{},[492,493,494,498,501],"tr",{},[495,496,497],"th",{},"Source",[495,499,500],{},"Declares",[495,502,503],{},"Use for",[505,506,507,529],"tbody",{},[492,508,509,520,523],{},[510,511,512,514,515],"td",{},[462,513,468],{}," in the ",[516,517,519],"a",{"href":518},"\u002Freference\u002Fextensions\u002Fdata-connectors\u002Fapi#engine","extension config",[510,521,522],{},"Hosts every data source needs",[510,524,525,526],{},"A fixed external data source, such as ",[462,527,528],{},"net:api.artic.edu",[492,530,531,537,540],{},[510,532,533,534],{},"The connector's ",[462,535,536],{},"preflight",[510,538,539],{},"Hosts that depend on the data source's configuration",[510,541,542],{},"A configurable base URL or tenant host",[458,544,545,546,549],{},"The ",[474,547,548],{},"instance"," (your running Monospace deployment) requires the grant to match the union of both sets exactly. A grant missing a host is refused, and so is a grant with an extra host.",[458,551,552,553,556],{},"Each redirect is checked against the grant too. When a granted host redirects to a host or port outside the grant, ",[462,554,555],{},"fetch"," fails at that hop, so grant every host in a redirect chain your connector follows.",[454,558,560],{"id":559},"write-a-permission","Write a Permission",[458,562,563,564,566,567,570,571,574],{},"Each permission is an object in the entry's ",[462,565,468],{}," array, with a ",[462,568,569],{},"permission"," string, a ",[462,572,573],{},"reason",", and no other fields:",[576,577,583],"pre",{"className":578,"code":579,"filename":580,"language":581,"meta":582,"style":582},"language-json shiki shiki-themes monospace-light monospace-light monospace-dark","{\n  \"permission\": \"net:api.artic.edu\",\n  \"reason\": \"Read artworks and artists from the Art Institute of Chicago API\"\n}\n","engine.permissions item","json","",[462,584,585,594,611,622],{"__ignoreMap":582},[586,587,590],"span",{"class":588,"line":589},"line",1,[586,591,593],{"class":592},"sTMul","{\n",[586,595,597,601,604,608],{"class":588,"line":596},2,[586,598,600],{"class":599},"snHjA","  \"permission\"",[586,602,603],{"class":592},": ",[586,605,607],{"class":606},"suKVh","\"net:api.artic.edu\"",[586,609,610],{"class":592},",\n",[586,612,614,617,619],{"class":588,"line":613},3,[586,615,616],{"class":599},"  \"reason\"",[586,618,603],{"class":592},[586,620,621],{"class":606},"\"Read artworks and artists from the Art Institute of Chicago API\"\n",[586,623,625],{"class":588,"line":624},4,[586,626,627],{"class":592},"}\n",[486,629,630,640],{},[489,631,632],{},[492,633,634,637],{},[495,635,636],{},"Field",[495,638,639],{},"Rules",[505,641,642,661],{},[492,643,644,648],{},[510,645,646],{},[462,647,569],{},[510,649,650,652,653,656,657,660],{},[462,651,464],{}," followed by a target. ",[462,654,655],{},"net"," is the only capability. ",[462,658,659],{},"NET:"," and other prefixes are rejected",[492,662,663,667],{},[510,664,665],{},[462,666,573],{},[510,668,669],{},"Required. Must contain a non-whitespace character. Shown to whoever approves the grant",[671,672,674],"h3",{"id":673},"target-syntax","Target Syntax",[458,676,677,678,681,682,684,685,688],{},"A target names a host, an IPv4 address or subnet, or a bracketed IPv6 address, with an optional port from 1 to 65535, never a URL. A grant can't limit a connector to certain URL paths or HTTP methods: a granted host is reachable with any request. Monospace supports the forms marked accepted below, and no others. The rejected rows are common mistakes, which ",[462,679,680],{},"monospace extension build"," and Engine's manifest check refuse. Permissions that ",[462,683,536],{}," answers skip that check and go through the runtime's parser only, which accepts some of them, such as a ",[462,686,687],{},"unix:"," socket path:",[486,690,691,704],{},[489,692,693],{},[492,694,695,698,701],{},[495,696,697],{},"Target",[495,699,700],{},"Accepted",[495,702,703],{},"Notes",[505,705,706,719,731,746,762,774,789,802,814,829,841,853,865],{},[492,707,708,713,716],{},[510,709,710],{},[462,711,712],{},"net:api.example.com",[510,714,715],{},"Yes",[510,717,718],{},"Any port",[492,720,721,726,728],{},[510,722,723],{},[462,724,725],{},"net:api.example.com:443",[510,727,715],{},[510,729,730],{},"Port 443 only",[492,732,733,738,740],{},[510,734,735],{},[462,736,737],{},"net:*.example.com",[510,739,715],{},[510,741,742,745],{},[462,743,744],{},"example.com"," itself and every subdomain",[492,747,748,757,759],{},[510,749,750,753,754],{},[462,751,752],{},"net:127.0.0.1",", ",[462,755,756],{},"net:127.0.0.1:8080",[510,758,715],{},[510,760,761],{},"IPv4, with or without a port",[492,763,764,769,771],{},[510,765,766],{},[462,767,768],{},"net:10.0.0.0\u002F8",[510,770,715],{},[510,772,773],{},"An IPv4 subnet",[492,775,776,784,786],{},[510,777,778,753,781],{},[462,779,780],{},"net:[::1]",[462,782,783],{},"net:[::1]:443",[510,785,715],{},[510,787,788],{},"IPv6 in brackets",[492,790,791,796,799],{},[510,792,793],{},[462,794,795],{},"net:https:\u002F\u002Fexample.com",[510,797,798],{},"No",[510,800,801],{},"URLs are rejected",[492,803,804,809,811],{},[510,805,806],{},[462,807,808],{},"net:unix:\u002Ftmp\u002Fapp.sock",[510,810,798],{},[510,812,813],{},"Unix sockets and paths are rejected",[492,815,816,821,823],{},[510,817,818],{},[462,819,820],{},"net:example.com:0",[510,822,798],{},[510,824,825,826],{},"Port ",[462,827,828],{},"0",[492,830,831,836,838],{},[510,832,833],{},[462,834,835],{},"net:example.com:",[510,837,798],{},[510,839,840],{},"Empty port",[492,842,843,848,850],{},[510,844,845],{},[462,846,847],{},"net:example.com:notaport",[510,849,798],{},[510,851,852],{},"Non-numeric port",[492,854,855,860,862],{},[510,856,857],{},[462,858,859],{},"net:::1",[510,861,798],{},[510,863,864],{},"IPv6 without brackets",[492,866,867,871,873],{},[510,868,869],{},[462,870,464],{},[510,872,798],{},[510,874,875],{},"Empty target",[458,877,878],{},"The instance rejects an entire extension whose manifest contains a target it can't parse.",[671,880,882],{"id":881},"normalization-and-deduplication","Normalization and Deduplication",[458,884,885],{},"The instance normalizes each target before comparing it:",[887,888,889,900],"ul",{},[890,891,892,893,896,897,899],"li",{},"Hostnames are lowercased: ",[462,894,895],{},"net:API.Example.com"," and ",[462,898,712],{}," are one permission.",[890,901,902,903,906,907,469],{},"IPv6 addresses are shortened: ",[462,904,905],{},"net:[0:0:0:0:0:0:0:1]:443"," becomes ",[462,908,783],{},[458,910,911,912,914],{},"A target listed twice keeps its first reason. When the manifest and ",[462,913,536],{}," name the same target, the manifest's reason wins. Reasons are never compared: a grant matches when it names the same targets, whatever reasons it carries.",[458,916,917,918,920,921,923,924,920,926,469],{},"Targets match as written after normalization, not by the access they cover. ",[462,919,712],{}," doesn't stand in for ",[462,922,725],{},", and ",[462,925,737],{},[462,927,712],{},[454,929,931,932],{"id":930},"derive-permissions-in-preflight","Derive Permissions in ",[462,933,536],{},[458,935,936,938,939,942],{},[462,937,536],{}," receives the data source's configuration and returns the extra permissions that configuration needs. The instance calls it before ",[462,940,941],{},"setup",", on every start of the data source.",[486,944,945,955],{},[489,946,947],{},[492,948,949,952],{},[495,950,951],{},"Rule",[495,953,954],{},"Result when broken",[505,956,957,968,980],{},[492,958,959,962],{},[510,960,961],{},"Return synchronously",[510,963,964,965],{},"A returned promise fails with ",[462,966,967],{},"preflight must answer synchronously",[492,969,970,977],{},[510,971,972,973,976],{},"Return ",[462,974,975],{},"{ permissions: [...] }"," in the same shape as the manifest",[510,978,979],{},"An unparseable target or blank reason deactivates the data source until the extension is reloaded",[492,981,982,985],{},[510,983,984],{},"Touch nothing the runtime denies",[510,986,987,988,990,991,994],{},"A permission denial in ",[462,989,536],{}," (Deno's ",[462,992,993],{},"NotCapable",", e.g., from reading an environment variable) deactivates the data source until the extension is reloaded",[458,996,997,998,1001,1002,1006,1007,1010,1011,1016],{},"A deactivated data source refuses every request that reaches its connector without starting the connector again. After malformed permissions it answers ",[462,999,1000],{},"503"," \"Data source is deactivated\". After a permission denial, or a grant that doesn't match (see ",[516,1003,1005],{"href":1004},"#change-permissions","Change Permissions","), it answers ",[462,1008,1009],{},"422"," \"Invalid extension permissions\". A result the cache already holds is still served. Reloading the extension, on restart or through ",[1012,1013],"env-var",{"name":1014,"section":1015},"extensions__auto_reload","extensions",", lets the next request try again.",[458,1018,1019],{},"Deactivation belongs to the data source. A connection test or schema preview starts a fresh connector from the configuration it's sent, so a failed attempt doesn't need a reload before the next one.",[458,1021,1022,1023,1025,1026,1029,1030,469],{},"Derive hosts from the configuration only. ",[462,1024,536],{}," is stateless: don't make requests, open connections or build clients in it. When the configuration it reads is invalid, throw ",[462,1027,1028],{},"InvalidConfiguration","; that stops the data source until the extension is reloaded, as it does from ",[462,1031,941],{},[458,1033,1034,1035,1037,1038,1041,1042,1044],{},"A connector without ",[462,1036,536],{}," requires only its manifest permissions. See ",[516,1039,410],{"href":1040},"\u002Freference\u002Fextensions\u002Fdata-connectors\u002Fapi"," for the ",[462,1043,536],{}," signature.",[454,1046,1048],{"id":1047},"approve-permissions","Approve Permissions",[458,1050,1051,1052,1055,1056,1058,1059,1062,1063,1066,1067,1069],{},"When you create a data source, you approve its network permissions. Creating, testing or introspecting a data source sends a ",[462,1053,1054],{},"permissions"," array with the request. When it doesn't match the required set, the instance answers ",[462,1057,1009],{}," with code ",[462,1060,1061],{},"7001"," and the complete required set in ",[462,1064,1065],{},"meta.permissions",". Resend the same request with ",[462,1068,1054],{}," replaced by that set.",[458,1071,1072,1073,1075,1076,469],{},"The connector file loads under the permissions you send, before Engine compares them. A request at module scope to a host your grant lacks fails the start before Engine can answer ",[462,1074,1061],{},", so keep network calls out of module scope. See ",[516,1077,1079],{"href":1078},"\u002Fdeveloper\u002Fextensions\u002Fdata-connectors\u002Fruntime#data-source-lifecycle","Data Source Lifecycle",[458,1081,1082,1083,1090,1091,1094,1095,1098,1099,1102,1103,469],{},"The three endpoints share this handshake, and each requires the ",[516,1084,1086,1089],{"href":1085},"\u002Freference\u002Fpermissions#workspace-entitlements",[462,1087,1088],{},"dataSource:create"," entitlement"," in the workspace; a matching grant doesn't replace it. Their bodies and answers differ: testing and introspecting take the configuration without ",[462,1092,1093],{},"apiName",", a passing test answers ",[462,1096,1097],{},"204"," with no body, and introspection answers with the schema in ",[462,1100,1101],{},"data.schema",", next to a ",[462,1104,1105],{},"data.hash",[486,1107,1108,1121],{},[489,1109,1110],{},[492,1111,1112,1115,1118],{},[495,1113,1114],{},"Operation",[495,1116,1117],{},"Method",[495,1119,1120],{},"Path",[505,1122,1123,1139,1153],{},[492,1124,1125,1128,1134],{},[510,1126,1127],{},"Create a data source",[510,1129,1130],{},[1131,1132],"http-method",{"method":1133},"POST",[510,1135,1136],{},[462,1137,1138],{},"\u002Fapi\u002F{workspace}\u002Fsources\u002Fdata",[492,1140,1141,1144,1148],{},[510,1142,1143],{},"Test a connection",[510,1145,1146],{},[1131,1147],{"method":1133},[510,1149,1150],{},[462,1151,1152],{},"\u002Fapi\u002F{workspace}\u002Fsources\u002Fdata\u002Ftest",[492,1154,1155,1158,1162],{},[510,1156,1157],{},"Introspect without creating",[510,1159,1160],{},[1131,1161],{"method":1133},[510,1163,1164],{},[462,1165,1166],{},"\u002Fapi\u002F{workspace}\u002Fsources\u002Fdata\u002Fintrospect",[671,1168,1170],{"id":1169},"send-the-first-request","Send the First Request",[458,1172,1173],{},"This request tries to create a data source with no grant. The SDK has no method for data sources, so call the endpoint directly:",[1175,1176,1177,1253],"code-group",{},[576,1178,1183],{"className":1179,"code":1180,"filename":1181,"language":1182,"meta":582,"style":582},"language-bash shiki shiki-themes monospace-light monospace-light monospace-dark","curl -X POST https:\u002F\u002Fexample.monospace.io\u002Fapi\u002Fblog\u002Fsources\u002Fdata \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"apiName\": \"artic\",\n    \"provider\": \"example\u002Fartic-connector\",\n    \"config\": {}\n  }'\n","curl","bash",[462,1184,1185,1202,1212,1221,1229,1235,1241,1247],{"__ignoreMap":582},[586,1186,1187,1190,1193,1196,1199],{"class":588,"line":589},[586,1188,1181],{"class":1189},"ssBNi",[586,1191,1192],{"class":1189}," -X",[586,1194,1195],{"class":606}," POST",[586,1197,1198],{"class":606}," https:\u002F\u002Fexample.monospace.io\u002Fapi\u002Fblog\u002Fsources\u002Fdata",[586,1200,1201],{"class":1189}," \\\n",[586,1203,1204,1207,1210],{"class":588,"line":596},[586,1205,1206],{"class":1189},"  -H",[586,1208,1209],{"class":606}," \"Authorization: Bearer YOUR_API_KEY\"",[586,1211,1201],{"class":1189},[586,1213,1214,1216,1219],{"class":588,"line":613},[586,1215,1206],{"class":1189},[586,1217,1218],{"class":606}," \"Content-Type: application\u002Fjson\"",[586,1220,1201],{"class":1189},[586,1222,1223,1226],{"class":588,"line":624},[586,1224,1225],{"class":1189},"  -d",[586,1227,1228],{"class":606}," '{\n",[586,1230,1232],{"class":588,"line":1231},5,[586,1233,1234],{"class":606},"    \"apiName\": \"artic\",\n",[586,1236,1238],{"class":588,"line":1237},6,[586,1239,1240],{"class":606},"    \"provider\": \"example\u002Fartic-connector\",\n",[586,1242,1244],{"class":588,"line":1243},7,[586,1245,1246],{"class":606},"    \"config\": {}\n",[586,1248,1250],{"class":588,"line":1249},8,[586,1251,1252],{"class":606},"  }'\n",[576,1254,1258],{"className":1255,"code":1256,"filename":555,"language":1257,"meta":582,"style":582},"language-ts shiki shiki-themes monospace-light monospace-light monospace-dark","const response = await fetch('https:\u002F\u002Fexample.monospace.io\u002Fapi\u002Fblog\u002Fsources\u002Fdata', {\n  method: 'POST',\n  headers: {\n    'Authorization': 'Bearer YOUR_API_KEY',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    apiName: 'artic',\n    provider: 'example\u002Fartic-connector',\n    config: {},\n  }),\n});\n","ts",[462,1259,1260,1287,1297,1302,1314,1326,1331,1347,1357,1368,1374,1380],{"__ignoreMap":582},[586,1261,1262,1266,1269,1272,1275,1278,1281,1284],{"class":588,"line":589},[586,1263,1265],{"class":1264},"sLVBU","const",[586,1267,1268],{"class":1189}," response",[586,1270,1271],{"class":1264}," =",[586,1273,1274],{"class":1264}," await",[586,1276,1277],{"class":1189}," fetch",[586,1279,1280],{"class":592},"(",[586,1282,1283],{"class":606},"'https:\u002F\u002Fexample.monospace.io\u002Fapi\u002Fblog\u002Fsources\u002Fdata'",[586,1285,1286],{"class":592},", {\n",[586,1288,1289,1292,1295],{"class":588,"line":596},[586,1290,1291],{"class":592},"  method: ",[586,1293,1294],{"class":606},"'POST'",[586,1296,610],{"class":592},[586,1298,1299],{"class":588,"line":613},[586,1300,1301],{"class":592},"  headers: {\n",[586,1303,1304,1307,1309,1312],{"class":588,"line":624},[586,1305,1306],{"class":606},"    'Authorization'",[586,1308,603],{"class":592},[586,1310,1311],{"class":606},"'Bearer YOUR_API_KEY'",[586,1313,610],{"class":592},[586,1315,1316,1319,1321,1324],{"class":588,"line":1231},[586,1317,1318],{"class":606},"    'Content-Type'",[586,1320,603],{"class":592},[586,1322,1323],{"class":606},"'application\u002Fjson'",[586,1325,610],{"class":592},[586,1327,1328],{"class":588,"line":1237},[586,1329,1330],{"class":592},"  },\n",[586,1332,1333,1336,1339,1341,1344],{"class":588,"line":1243},[586,1334,1335],{"class":592},"  body: ",[586,1337,1338],{"class":1189},"JSON",[586,1340,469],{"class":592},[586,1342,1343],{"class":1189},"stringify",[586,1345,1346],{"class":592},"({\n",[586,1348,1349,1352,1355],{"class":588,"line":1249},[586,1350,1351],{"class":592},"    apiName: ",[586,1353,1354],{"class":606},"'artic'",[586,1356,610],{"class":592},[586,1358,1360,1363,1366],{"class":588,"line":1359},9,[586,1361,1362],{"class":592},"    provider: ",[586,1364,1365],{"class":606},"'example\u002Fartic-connector'",[586,1367,610],{"class":592},[586,1369,1371],{"class":588,"line":1370},10,[586,1372,1373],{"class":592},"    config: {},\n",[586,1375,1377],{"class":588,"line":1376},11,[586,1378,1379],{"class":592},"  }),\n",[586,1381,1383],{"class":588,"line":1382},12,[586,1384,1385],{"class":592},"});\n",[458,1387,1388,1391,1392,1395,1396,1399,1400,896,1402,1404,1405,896,1407,1409],{},[462,1389,1390],{},"provider"," is the entry id of an installed data connector. See ",[516,1393,227],{"href":1394},"\u002Fdeveloper\u002Fextensions\u002Finstall"," to install one first. ",[462,1397,1398],{},"config"," is the data source's configuration, passed to ",[462,1401,536],{},[462,1403,941],{}," unchanged. Both ",[462,1406,1398],{},[462,1408,1054],{}," default to empty when omitted.",[458,1411,1412,1413,1415,1416,1418,1419,1421,1422,1424],{},"Each ",[462,1414,1054],{}," item takes the manifest shape: a ",[462,1417,569],{}," and a non-blank ",[462,1420,573],{},". A malformed item fails the request without the ",[462,1423,1061],{}," handshake.",[671,1426,1428],{"id":1427},"read-the-refusal","Read the Refusal",[458,1430,1431],{},"The instance refuses the request and lists the set to approve:",[576,1433,1436],{"className":578,"code":1434,"filename":1435,"language":581,"meta":582,"style":582},"{\n  \"message\": \"The connector requires permissions this data source was not granted. Approve them and retry.\",\n  \"code\": \"7001\",\n  \"meta\": {\n    \"permissions\": [\n      { \"permission\": \"net:api.artic.edu\", \"reason\": \"Read artworks and artists from the Art Institute of Chicago API\" }\n    ]\n  }\n}\n","response.json",[462,1437,1438,1442,1454,1466,1474,1482,1507,1512,1517],{"__ignoreMap":582},[586,1439,1440],{"class":588,"line":589},[586,1441,593],{"class":592},[586,1443,1444,1447,1449,1452],{"class":588,"line":596},[586,1445,1446],{"class":599},"  \"message\"",[586,1448,603],{"class":592},[586,1450,1451],{"class":606},"\"The connector requires permissions this data source was not granted. Approve them and retry.\"",[586,1453,610],{"class":592},[586,1455,1456,1459,1461,1464],{"class":588,"line":613},[586,1457,1458],{"class":599},"  \"code\"",[586,1460,603],{"class":592},[586,1462,1463],{"class":606},"\"7001\"",[586,1465,610],{"class":592},[586,1467,1468,1471],{"class":588,"line":624},[586,1469,1470],{"class":599},"  \"meta\"",[586,1472,1473],{"class":592},": {\n",[586,1475,1476,1479],{"class":588,"line":1231},[586,1477,1478],{"class":599},"    \"permissions\"",[586,1480,1481],{"class":592},": [\n",[586,1483,1484,1487,1490,1492,1494,1496,1499,1501,1504],{"class":588,"line":1237},[586,1485,1486],{"class":592},"      { ",[586,1488,1489],{"class":599},"\"permission\"",[586,1491,603],{"class":592},[586,1493,607],{"class":606},[586,1495,753],{"class":592},[586,1497,1498],{"class":599},"\"reason\"",[586,1500,603],{"class":592},[586,1502,1503],{"class":606},"\"Read artworks and artists from the Art Institute of Chicago API\"",[586,1505,1506],{"class":592}," }\n",[586,1508,1509],{"class":588,"line":1243},[586,1510,1511],{"class":592},"    ]\n",[586,1513,1514],{"class":588,"line":1249},[586,1515,1516],{"class":592},"  }\n",[586,1518,1519],{"class":588,"line":1359},[586,1520,627],{"class":592},[458,1522,1523,1525,1526,1528,1529,1531],{},[462,1524,1065],{}," is the whole required set, not the difference from what you sent. Nothing is created and the connector's ",[462,1527,941],{}," doesn't run. The connector's module and ",[462,1530,536],{}," have already run, with the grant you sent, to compute the set.",[671,1533,1535],{"id":1534},"resend-with-the-grant","Resend with the Grant",[458,1537,1538,1539,1541,1542,1544],{},"Review the hosts and reasons in ",[462,1540,1065],{},". To approve them, copy the set into the request as ",[462,1543,1054],{},":",[1175,1546,1547,1617],{},[576,1548,1550],{"className":1179,"code":1549,"filename":1181,"language":1182,"meta":582,"style":582},"curl -X POST https:\u002F\u002Fexample.monospace.io\u002Fapi\u002Fblog\u002Fsources\u002Fdata \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"apiName\": \"artic\",\n    \"provider\": \"example\u002Fartic-connector\",\n    \"config\": {},\n    \"permissions\": [\n      { \"permission\": \"net:api.artic.edu\", \"reason\": \"Read artworks and artists from the Art Institute of Chicago API\" }\n    ]\n  }'\n",[462,1551,1552,1564,1572,1580,1586,1590,1594,1599,1604,1609,1613],{"__ignoreMap":582},[586,1553,1554,1556,1558,1560,1562],{"class":588,"line":589},[586,1555,1181],{"class":1189},[586,1557,1192],{"class":1189},[586,1559,1195],{"class":606},[586,1561,1198],{"class":606},[586,1563,1201],{"class":1189},[586,1565,1566,1568,1570],{"class":588,"line":596},[586,1567,1206],{"class":1189},[586,1569,1209],{"class":606},[586,1571,1201],{"class":1189},[586,1573,1574,1576,1578],{"class":588,"line":613},[586,1575,1206],{"class":1189},[586,1577,1218],{"class":606},[586,1579,1201],{"class":1189},[586,1581,1582,1584],{"class":588,"line":624},[586,1583,1225],{"class":1189},[586,1585,1228],{"class":606},[586,1587,1588],{"class":588,"line":1231},[586,1589,1234],{"class":606},[586,1591,1592],{"class":588,"line":1237},[586,1593,1240],{"class":606},[586,1595,1596],{"class":588,"line":1243},[586,1597,1598],{"class":606},"    \"config\": {},\n",[586,1600,1601],{"class":588,"line":1249},[586,1602,1603],{"class":606},"    \"permissions\": [\n",[586,1605,1606],{"class":588,"line":1359},[586,1607,1608],{"class":606},"      { \"permission\": \"net:api.artic.edu\", \"reason\": \"Read artworks and artists from the Art Institute of Chicago API\" }\n",[586,1610,1611],{"class":588,"line":1370},[586,1612,1511],{"class":606},[586,1614,1615],{"class":588,"line":1376},[586,1616,1252],{"class":606},[576,1618,1620],{"className":1255,"code":1619,"filename":555,"language":1257,"meta":582,"style":582},"const response = await fetch('https:\u002F\u002Fexample.monospace.io\u002Fapi\u002Fblog\u002Fsources\u002Fdata', {\n  method: 'POST',\n  headers: {\n    'Authorization': 'Bearer YOUR_API_KEY',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    apiName: 'artic',\n    provider: 'example\u002Fartic-connector',\n    config: {},\n    permissions: [\n      { permission: 'net:api.artic.edu', reason: 'Read artworks and artists from the Art Institute of Chicago API' },\n    ],\n  }),\n});\n",[462,1621,1622,1640,1648,1652,1662,1672,1676,1688,1696,1704,1708,1713,1730,1736,1741],{"__ignoreMap":582},[586,1623,1624,1626,1628,1630,1632,1634,1636,1638],{"class":588,"line":589},[586,1625,1265],{"class":1264},[586,1627,1268],{"class":1189},[586,1629,1271],{"class":1264},[586,1631,1274],{"class":1264},[586,1633,1277],{"class":1189},[586,1635,1280],{"class":592},[586,1637,1283],{"class":606},[586,1639,1286],{"class":592},[586,1641,1642,1644,1646],{"class":588,"line":596},[586,1643,1291],{"class":592},[586,1645,1294],{"class":606},[586,1647,610],{"class":592},[586,1649,1650],{"class":588,"line":613},[586,1651,1301],{"class":592},[586,1653,1654,1656,1658,1660],{"class":588,"line":624},[586,1655,1306],{"class":606},[586,1657,603],{"class":592},[586,1659,1311],{"class":606},[586,1661,610],{"class":592},[586,1663,1664,1666,1668,1670],{"class":588,"line":1231},[586,1665,1318],{"class":606},[586,1667,603],{"class":592},[586,1669,1323],{"class":606},[586,1671,610],{"class":592},[586,1673,1674],{"class":588,"line":1237},[586,1675,1330],{"class":592},[586,1677,1678,1680,1682,1684,1686],{"class":588,"line":1243},[586,1679,1335],{"class":592},[586,1681,1338],{"class":1189},[586,1683,469],{"class":592},[586,1685,1343],{"class":1189},[586,1687,1346],{"class":592},[586,1689,1690,1692,1694],{"class":588,"line":1249},[586,1691,1351],{"class":592},[586,1693,1354],{"class":606},[586,1695,610],{"class":592},[586,1697,1698,1700,1702],{"class":588,"line":1359},[586,1699,1362],{"class":592},[586,1701,1365],{"class":606},[586,1703,610],{"class":592},[586,1705,1706],{"class":588,"line":1370},[586,1707,1373],{"class":592},[586,1709,1710],{"class":588,"line":1376},[586,1711,1712],{"class":592},"    permissions: [\n",[586,1714,1715,1718,1721,1724,1727],{"class":588,"line":1382},[586,1716,1717],{"class":592},"      { permission: ",[586,1719,1720],{"class":606},"'net:api.artic.edu'",[586,1722,1723],{"class":592},", reason: ",[586,1725,1726],{"class":606},"'Read artworks and artists from the Art Institute of Chicago API'",[586,1728,1729],{"class":592}," },\n",[586,1731,1733],{"class":588,"line":1732},13,[586,1734,1735],{"class":592},"    ],\n",[586,1737,1739],{"class":588,"line":1738},14,[586,1740,1379],{"class":592},[586,1742,1744],{"class":588,"line":1743},15,[586,1745,1385],{"class":592},[458,1747,1748,1749,1752],{},"With the grant matching, the instance runs the connector's ",[462,1750,1751],{},"testConnection",", creates the data source, and returns its id:",[576,1754,1756],{"className":578,"code":1755,"filename":1435,"language":581,"meta":582,"style":582},"{ \"data\": { \"id\": \"d7c8f0e2-9b3a-4c1e-8f2a-1a2b3c4d5e6f\" } }\n",[462,1757,1758],{"__ignoreMap":582},[586,1759,1760,1763,1766,1769,1772,1774,1777],{"class":588,"line":589},[586,1761,1762],{"class":592},"{ ",[586,1764,1765],{"class":599},"\"data\"",[586,1767,1768],{"class":592},": { ",[586,1770,1771],{"class":599},"\"id\"",[586,1773,603],{"class":592},[586,1775,1776],{"class":606},"\"d7c8f0e2-9b3a-4c1e-8f2a-1a2b3c4d5e6f\"",[586,1778,1779],{"class":592}," } }\n",[458,1781,1782],{},"Studio runs the same handshake. It sends the manifest permissions first, and when they match the required set, no dialog appears.",[458,1784,1785,1786,1788],{},"When the instance refuses them because the required set has hosts they lack, for example because ",[462,1787,536],{}," adds a host, Studio shows the required set with each reason. It resends once you approve. A refusal caused only by extra hosts opens no dialog; Studio reports the error. ",[1790,1791,1792,1795,1796,1798,1799,1802],"tip",{},[462,1793,1794],{},"GET \u002Fapi\u002F{workspace}\u002Fconnectors\u002Fdata"," lists every installed data connector with its manifest ",[462,1797,1054],{},", so you can review them before creating a data source. It requires the ",[462,1800,1801],{},"extension:read"," entitlement in the workspace.",[454,1804,1806],{"id":1805},"handle-a-denied-request","Handle a Denied Request",[458,1808,1809,1810,1812,1813,1815,1816,1819,1820,1822,1823,1827],{},"A request to a host outside the grant never leaves the instance. ",[462,1811,555],{}," rejects with Deno's ",[462,1814,993],{}," error inside your connector. Engine looks for that error along the ",[462,1817,1818],{},"cause"," chain of whatever your connector throws. When you wrap the rejection in a kit error class, pass it as the ",[462,1821,1818],{},", as ",[516,1824,1826],{"href":1825},"\u002Fdeveloper\u002Fextensions\u002Fdata-connectors\u002Fruntime#http-through-fetch","HTTP Through fetch"," shows.",[486,1829,1830,1840],{},[489,1831,1832],{},[492,1833,1834,1837],{},[495,1835,1836],{},"Where it's thrown",[495,1838,1839],{},"What the caller sees",[505,1841,1842,1860,1873],{},[492,1843,1844,1855],{},[510,1845,1846,1848,1849,1852,1853],{},[462,1847,1751],{}," or ",[462,1850,1851],{},"query",", uncaught or kept as the ",[462,1854,1818],{},[510,1856,1857,1859],{},[462,1858,1009],{}," \"Invalid extension permissions\"",[492,1861,1862,1868],{},[510,1863,1864,1852,1866],{},[462,1865,941],{},[462,1867,1818],{},[510,1869,1870,1871,1859],{},"The data source is deactivated until the extension is reloaded, and answers ",[462,1872,1009],{},[492,1874,1875,1880],{},[510,1876,1877,1878],{},"Wrapped in another error class without ",[462,1879,1818],{},[510,1881,1882,1883,1886,1887,1890],{},"That class's error. The permission denial is lost. A ",[462,1884,1885],{},"ConnectionFailed"," wrapper reads as ",[462,1888,1889],{},"500"," \"Failed to connect to the database\" ",[458,1892,1893,1894,1897,1898,1901,1902,1904,1905,1907,1908,1910],{},"A connection test of the Quickstart connector, changed to call ",[462,1895,1896],{},"www.artic.edu"," instead of the granted ",[462,1899,1900],{},"api.artic.edu",", answers ",[462,1903,1009],{},". The connector wraps the rejection in ",[462,1906,1885],{}," with the rejection as its ",[462,1909,1818],{},", so the innermost message is the connector's own:",[576,1912,1914],{"className":578,"code":1913,"filename":1435,"language":581,"meta":582,"style":582},"{\n  \"message\": \"Failed to connect to data source with the provided configuration\",\n  \"source\": {\n    \"message\": \"Invalid extension permissions\",\n    \"source\": {\n      \"message\": \"the extension returned an error: The Art Institute API did not answer.\"\n    }\n  }\n}\n",[462,1915,1916,1920,1931,1938,1950,1957,1967,1972,1976],{"__ignoreMap":582},[586,1917,1918],{"class":588,"line":589},[586,1919,593],{"class":592},[586,1921,1922,1924,1926,1929],{"class":588,"line":596},[586,1923,1446],{"class":599},[586,1925,603],{"class":592},[586,1927,1928],{"class":606},"\"Failed to connect to data source with the provided configuration\"",[586,1930,610],{"class":592},[586,1932,1933,1936],{"class":588,"line":613},[586,1934,1935],{"class":599},"  \"source\"",[586,1937,1473],{"class":592},[586,1939,1940,1943,1945,1948],{"class":588,"line":624},[586,1941,1942],{"class":599},"    \"message\"",[586,1944,603],{"class":592},[586,1946,1947],{"class":606},"\"Invalid extension permissions\"",[586,1949,610],{"class":592},[586,1951,1952,1955],{"class":588,"line":1231},[586,1953,1954],{"class":599},"    \"source\"",[586,1956,1473],{"class":592},[586,1958,1959,1962,1964],{"class":588,"line":1237},[586,1960,1961],{"class":599},"      \"message\"",[586,1963,603],{"class":592},[586,1965,1966],{"class":606},"\"the extension returned an error: The Art Institute API did not answer.\"\n",[586,1968,1969],{"class":588,"line":1243},[586,1970,1971],{"class":592},"    }\n",[586,1973,1974],{"class":588,"line":1249},[586,1975,1516],{"class":592},[586,1977,1978],{"class":588,"line":1359},[586,1979,627],{"class":592},[458,1981,1982,1983,1986,1987,1990,1991,1993],{},"A connector that lets the rejection through uncaught shows Deno's message there instead, which names the host: ",[462,1984,1985],{},"Requires net access to \"www.artic.edu:443\", run again with the --allow-net flag",". The ",[462,1988,1989],{},"--allow-net"," hint comes from Deno; it isn't an option you can set. When the host is wrong, fix the URL your connector calls. When the connector needs the host, add it to the manifest or ",[462,1992,536],{},", then recreate the data source.",[454,1995,1005],{"id":1996},"change-permissions",[458,1998,1999],{},"A data source's grant is fixed when you create it. There is no endpoint to update a data source's grant or configuration. Reintrospecting runs the data source's existing connector, with its original configuration and grant.",[458,2001,2002],{},"When an extension update changes the required set, existing data sources stop serving:",[2004,2005,2006,2011,2014],"ol",{},[890,2007,2008,2009,469],{},"The instance reloads the extension, on restart or through ",[1012,2010],{"name":1014,"section":1015},[890,2012,2013],{},"Each data source compares its stored grant with the new required set on its next start.",[890,2015,2016,2017,2019,2020,2022,2023,469],{},"A mismatch deactivates the data source. Queries that reach the connector fail with ",[462,2018,1009],{}," \"Invalid extension permissions\", code ",[462,2021,1061],{},", and the full required set in ",[462,2024,1065],{},[458,2026,2027,2028,469],{},"This applies to removed hosts as well as added ones. To recover, delete the data source and create it again with the new set. Reverting the extension to the previous set reactivates the data source. A connection test with the new set doesn't change the data source's stored grant. See ",[516,2029,2031],{"href":2030},"\u002Fdeveloper\u002Fextensions\u002Fdata-connectors\u002Fdata-sources#recreate-a-data-source","Recreate a Data Source",[454,2033,2035],{"id":2034},"see-also","See Also",[887,2037,2038,2051,2057,2064],{},[890,2039,2040,2042,2043,2045,2046,896,2048,2050],{},[516,2041,410],{"href":1040},": where ",[462,2044,468],{}," lives, and the ",[462,2047,536],{},[462,2049,941],{}," signatures",[890,2052,2053,2056],{},[516,2054,237],{"href":2055},"\u002Fdeveloper\u002Fextensions\u002Fdata-connectors\u002Fruntime",": where the permission check sits in the data source lifecycle",[890,2058,2059,2063],{},[516,2060,2062],{"href":2061},"\u002Fdeveloper\u002Fextensions\u002Fdata-connectors\u002Fdata-sources","Manage Data Sources",": update and recreate data sources after an extension update",[890,2065,2066,2069],{},[516,2067,422],{"href":2068},"\u002Freference\u002Fextensions\u002Fdata-connectors\u002Flimits",": what else the runtime allows and refuses",[2071,2072,2073],"style",{},"html pre.shiki code .sTMul, html code.shiki .sTMul{--shiki-light:#1F2937;--shiki-default:#1F2937;--shiki-dark:#94A3B8}html pre.shiki code .snHjA, html code.shiki .snHjA{--shiki-light:#124BC4;--shiki-default:#124BC4;--shiki-dark:#5B8EF4}html pre.shiki code .suKVh, html code.shiki .suKVh{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#F8FAFC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .ssBNi, html code.shiki .ssBNi{--shiki-light:#1659E9;--shiki-default:#1659E9;--shiki-dark:#94B3F5}html pre.shiki code .sLVBU, html code.shiki .sLVBU{--shiki-light:#0891B2;--shiki-default:#0891B2;--shiki-dark:#22D3EE}",{"title":582,"searchDepth":596,"depth":596,"links":2075},[2076,2077,2081,2083,2088,2089,2090],{"id":456,"depth":596,"text":143},{"id":559,"depth":596,"text":560,"children":2078},[2079,2080],{"id":673,"depth":613,"text":674},{"id":881,"depth":613,"text":882},{"id":930,"depth":596,"text":2082},"Derive Permissions in preflight",{"id":1047,"depth":596,"text":1048,"children":2084},[2085,2086,2087],{"id":1169,"depth":613,"text":1170},{"id":1427,"depth":613,"text":1428},{"id":1534,"depth":613,"text":1535},{"id":1805,"depth":596,"text":1806},{"id":1996,"depth":596,"text":1005},{"id":2034,"depth":596,"text":2035},"Learn how data connector entries declare net permissions, how Monospace derives the set a data source needs, and how to approve it when you create one.","md",null,{},{"icon":435},{"title":432,"description":2091},"XexQZpcNmeqpRMMbQ7IdcXHmuCh4UVgA-bONbzsLTqY",[2099,2101],{"title":427,"path":428,"stem":429,"description":2100,"icon":430,"children":-1},"Review what a data connector extension can't do today, what happens when an external data source needs it, and how to work around it.",{"title":442,"path":443,"stem":444,"description":2102,"icon":121,"children":-1},"Review the new features, improvements, and fixes shipped in each Monospace release.",1790840064605]