[{"data":1,"prerenderedAt":941},["ShallowReactive",2],{"fougere:post.list:{}":3,"docs:\u002Fdocs\u002Frun\u002Fsecure":6,"docs-uses":629,"docs-nav":803},{"items":4,"hasMore":5},[],false,{"id":7,"title":8,"body":9,"description":615,"extension":616,"forms":617,"kind":618,"meta":619,"navigation":620,"path":621,"seo":622,"stem":623,"step":624,"uses":625,"__hash__":628},"docs\u002Fdocs\u002F6.run\u002F2.secure.md","Secure calls between processes",{"type":10,"value":11,"toc":605},"minimark",[12,16,21,29,37,149,157,160,171,175,178,288,291,330,334,340,347,350,354,386,404,414,418,421,487,494,498,511,531,558,562,572,582,588,592,601],[13,14,15],"p",{},"Once a frond runs in another process, the receiver has to know who is calling it. On one machine that is free; across a network it is a signature.",[17,18,20],"h2",{"id":19},"loopback-or-signed","Loopback or signed",[13,22,23,24,28],{},"In one process a call is a function call: nothing crosses, nothing needs proving. Split a frond out\nand the call becomes a payload, which can say anything. So a receiver ",[25,26,27],"strong",{},"establishes"," who calls it\nrather than accepting what the payload claims.",[13,30,31,32,36],{},"It binds ",[33,34,35],"code",{},"127.0.0.1"," by default. Widening the address is one line, and it comes with a condition,\nchecked at boot:",[38,39,44],"pre",{"className":40,"code":41,"language":42,"meta":43,"style":43},"language-ts shiki shiki-themes material-theme-lighter fougere-pastel material-theme-palenight","await serve(runner, { hosts: ['0.0.0.0'] })            \u002F\u002F refuses to start on its own\nawait serve(runner, { hosts: ['0.0.0.0'], verify })    \u002F\u002F verifies every call\n","ts","",[33,45,46,107],{"__ignoreMap":43},[47,48,51,55,59,63,67,71,74,78,81,84,88,92,94,97,100,103],"span",{"class":49,"line":50},"line",1,[47,52,54],{"class":53},"sK6XW","await",[47,56,58],{"class":57},"s4mR9"," serve",[47,60,62],{"class":61},"srlTG","(",[47,64,66],{"class":65},"sPEhv","runner",[47,68,70],{"class":69},"s15xx",",",[47,72,73],{"class":69}," {",[47,75,77],{"class":76},"sHtqg"," hosts",[47,79,80],{"class":69},":",[47,82,83],{"class":61}," [",[47,85,87],{"class":86},"sDDC1","'",[47,89,91],{"class":90},"sN-8n","0.0.0.0",[47,93,87],{"class":86},[47,95,96],{"class":61},"]",[47,98,99],{"class":69}," }",[47,101,102],{"class":61},")",[47,104,106],{"class":105},"skXKP","            \u002F\u002F refuses to start on its own\n",[47,108,110,112,114,116,118,120,122,124,126,128,130,132,134,136,138,141,144,146],{"class":49,"line":109},2,[47,111,54],{"class":53},[47,113,58],{"class":57},[47,115,62],{"class":61},[47,117,66],{"class":65},[47,119,70],{"class":69},[47,121,73],{"class":69},[47,123,77],{"class":76},[47,125,80],{"class":69},[47,127,83],{"class":61},[47,129,87],{"class":86},[47,131,91],{"class":90},[47,133,87],{"class":86},[47,135,96],{"class":61},[47,137,70],{"class":69},[47,139,140],{"class":65}," verify ",[47,142,143],{"class":69},"}",[47,145,102],{"class":61},[47,147,148],{"class":105},"    \u002F\u002F verifies every call\n",[38,150,155],{"className":151,"code":153,"language":154},[152],"language-text","127.0.0.1                        starts, nothing to configure\n0.0.0.0 + FOUGERE_ROOT_KEY       starts, verifies every call\n0.0.0.0 with no root             does not start, and says what to do\n0.0.0.0 + allowUnsigned: true    starts — something in front already authenticated\n","text",[33,156,153],{"__ignoreMap":43},[13,158,159],{},"A receiver reachable from outside, that establishes nothing, would believe whatever state it is\nhanded — so it does not start. Refusing at boot rather than per call means you find out at\ndeployment, not in production.",[13,161,162,163,166,167,170],{},"A caller may send up to ",[33,164,165],{},"maxBodyBytes"," (2 MiB unless ",[33,168,169],{},"fougere.config.ts"," says otherwise); a hop\nkeeps 64 KiB above it for what it adds around the call — the trace, the identity, the state — so a\nbody that passes in one process passes split.",[17,172,174],{"id":173},"what-travels","What travels",[13,176,177],{},"Every call across a link carries an envelope, signed by the caller:",[38,179,183],{"className":180,"code":181,"language":182,"meta":43,"style":43},"language-json shiki shiki-themes material-theme-lighter fougere-pastel material-theme-palenight","{ \"method\": \"post.list\",\n  \"params\": { \"params\": {}, \"query\": {}, \"input\": null,\n              \"identity\": \"eyJhbGciOiJFZERTQSIs…\" } }\n","json",[33,184,185,212,263],{"__ignoreMap":43},[47,186,187,190,193,197,200,202,204,207,209],{"class":49,"line":50},[47,188,189],{"class":69},"{",[47,191,192],{"class":69}," \"",[47,194,196],{"class":195},"s8ClO","method",[47,198,199],{"class":69},"\"",[47,201,80],{"class":69},[47,203,192],{"class":86},[47,205,206],{"class":90},"post.list",[47,208,199],{"class":86},[47,210,211],{"class":69},",\n",[47,213,214,217,220,222,224,226,228,231,233,235,238,240,243,245,247,249,251,254,256,258,261],{"class":49,"line":109},[47,215,216],{"class":69},"  \"",[47,218,219],{"class":195},"params",[47,221,199],{"class":69},[47,223,80],{"class":69},[47,225,73],{"class":69},[47,227,192],{"class":69},[47,229,219],{"class":230},"sWI7z",[47,232,199],{"class":69},[47,234,80],{"class":69},[47,236,237],{"class":69}," {},",[47,239,192],{"class":69},[47,241,242],{"class":230},"query",[47,244,199],{"class":69},[47,246,80],{"class":69},[47,248,237],{"class":69},[47,250,192],{"class":69},[47,252,253],{"class":230},"input",[47,255,199],{"class":69},[47,257,80],{"class":69},[47,259,260],{"class":86}," null",[47,262,211],{"class":69},[47,264,266,269,272,274,276,278,281,283,285],{"class":49,"line":265},3,[47,267,268],{"class":69},"              \"",[47,270,271],{"class":230},"identity",[47,273,199],{"class":69},[47,275,80],{"class":69},[47,277,192],{"class":86},[47,279,280],{"class":90},"eyJhbGciOiJFZERTQSIs…",[47,282,199],{"class":86},[47,284,99],{"class":69},[47,286,287],{"class":69}," }\n",[13,289,290],{},"The envelope carries the state — who is signed in, if anyone — and the receiver takes it\nfrom there rather than from the payload. Sending both would leave every reader downstream\nchoosing between a proof and a claim about the same thing.",[13,292,293,294,297,298,301,302,301,305,301,307,309,310,313,314,318,319,322,323,325,326,329],{},"It binds the ",[25,295,296],{},"whole call",": ",[33,299,300],{},"address",", ",[33,303,304],{},"op",[33,306,219],{},[33,308,242],{}," and ",[33,311,312],{},"state"," by value, the body by\ndigest. Signing the state alone would prove ",[315,316,317],"em",{},"who"," without proving ",[315,320,321],{},"what",", and a captured\nenvelope could be replayed against another operation for as long as it stayed valid —\n",[33,324,206],{}," re-sent as ",[33,327,328],{},"post.delete",", same signature, still good.",[17,331,333],{"id":332},"two-signatures-one-public-key","Two signatures, one public key",[38,335,338],{"className":336,"code":337,"language":154},[152],"GRANT      the root says \"this key is blog\"   — issued once, at deployment\nENVELOPE   blog says \"here is my whole call\"  — signed per call\n",[33,339,337],{"__ignoreMap":43},[13,341,342,343,346],{},"A receiver holds the root's public key and ",[25,344,345],{},"nothing else",". It admits a frond it has\nnever seen, and a frond granted tomorrow is admitted by a receiver deployed today without\nits configuration being touched. That is the difference between an authority and a list of\nknown callers: the list has to be updated everywhere, and it goes stale.",[13,348,349],{},"Verification is offline — no service is joined, on any call or at any boot.",[17,351,353],{"id":352},"issuing","Issuing",[38,355,359],{"className":356,"code":357,"language":358,"meta":43,"style":43},"language-bash shiki shiki-themes material-theme-lighter fougere-pastel material-theme-palenight","fougere keys              # once per system — writes fougere.key, prints FOUGERE_ROOT_KEY\nfougere grant blog        # once per frond that CALLS — prints FOUGERE_KEY and FOUGERE_GRANT\n","bash",[33,360,361,373],{"__ignoreMap":43},[47,362,363,367,370],{"class":49,"line":50},[47,364,366],{"class":365},"sV8pK","fougere",[47,368,369],{"class":90}," keys",[47,371,372],{"class":105},"              # once per system — writes fougere.key, prints FOUGERE_ROOT_KEY\n",[47,374,375,377,380,383],{"class":49,"line":109},[47,376,366],{"class":365},[47,378,379],{"class":90}," grant",[47,381,382],{"class":90}," blog",[47,384,385],{"class":105},"        # once per frond that CALLS — prints FOUGERE_KEY and FOUGERE_GRANT\n",[13,387,388,391,392,395,396,399,400,403],{},[33,389,390],{},"fougere keys"," is a command, not a service: it runs at deployment time and exits. Nothing\nstays alive, nothing is joined at boot. The root's private key is written to\n",[33,393,394],{},"fougere.key"," (mode ",[33,397,398],{},"600",", added to ",[33,401,402],{},".gitignore",") and never printed — it signs grants,\nand a grant is the only thing that has to travel.",[13,405,406,409,410,413],{},[33,407,408],{},"fougere grant"," prints and stores nothing. Re-running it issues a ",[25,411,412],{},"new"," key rather than\nshowing the old one, which is what rotation is: run it again, redeploy that frond, and\nnobody else's configuration moves.",[17,415,417],{"id":416},"what-a-deployment-injects","What a deployment injects",[13,419,420],{},"Three variables, no configuration key — a private key does not belong in a committed file.\nPEM or base64, both are read.",[422,423,424,439],"table",{},[425,426,427],"thead",{},[428,429,430,433,436],"tr",{},[431,432],"th",{},[431,434,435],{},"Where",[431,437,438],{},"What it is",[440,441,442,459,474],"tbody",{},[428,443,444,450,456],{},[445,446,447],"td",{},[33,448,449],{},"FOUGERE_ROOT_KEY",[445,451,452,453],{},"every frond that ",[25,454,455],{},"answers",[445,457,458],{},"public — safe in an image or a manifest",[428,460,461,466,471],{},[445,462,463],{},[33,464,465],{},"FOUGERE_KEY",[445,467,452,468],{},[25,469,470],{},"calls",[445,472,473],{},"secret, shown once",[428,475,476,481,484],{},[445,477,478],{},[33,479,480],{},"FOUGERE_GRANT",[445,482,483],{},"beside it",[445,485,486],{},"the root's word that this key is that frond",[13,488,489,490,493],{},"A Frond may hold either half or both: one that only answers has no key, one that only calls\ntrusts no root, one in the middle does both. Trusting a root ",[25,491,492],{},"is"," asking to refuse — there\nis no second flag, because a deployment that names an authority and then accepts unsigned\ncalls has said two things at once.",[17,495,497],{"id":496},"what-a-handler-sees","What a handler sees",[13,499,500,501,506,507,510],{},"Nothing new to write. The state arrives where it always did, so a\n",[502,503,505],"a",{"href":504},"\u002Fdocs\u002Faccess\u002Fauthentication#know-who-calls","collector"," reading ",[33,508,509],{},"ctx.state.user"," is unchanged — in process,\nand split. What is added is one field:",[38,512,514],{"className":40,"code":513,"language":42,"meta":43,"style":43},"invocation.caller   \u002F\u002F 'blog' — the frond that signed, as the root named it\n",[33,515,516],{"__ignoreMap":43},[47,517,518,521,524,528],{"class":49,"line":50},[47,519,520],{"class":65},"invocation",[47,522,523],{"class":69},".",[47,525,527],{"class":526},"sy9f4","caller",[47,529,530],{"class":105},"   \u002F\u002F 'blog' — the frond that signed, as the root named it\n",[13,532,533,534,536,537,539,540,542,543,546,547,550,551,554,555,523],{},"It is top-level and not a key of ",[33,535,312],{},", and the reason decides how to read it: ",[33,538,312],{},"\ntravels unverified when no verifier is wired, so a ",[33,541,527],{}," living inside it would be\nforgeable exactly where nothing checks. ",[25,544,545],{},"Absent means not established",", and there is no\nspelling for a claim. A sender clears it on every hop, so it names the last one:\n",[33,548,549],{},"shop → catalog → billing"," has ",[33,552,553],{},"billing"," read ",[33,556,557],{},"catalog",[17,559,561],{"id":560},"what-this-does-not-do","What this does not do",[13,563,564,567,568,571],{},[25,565,566],{},"Authorization."," A signature says who is calling, never what they may call.\n",[33,569,570],{},"if (user.role !== 'admin') throw"," is still yours to write.",[13,573,574,577,578,581],{},[25,575,576],{},"A mesh's job."," Under a service mesh the sidecar terminated mTLS before your process saw\nthe request, and asking for a second signature would redo what was just done a centimetre\naway. That is what ",[33,579,580],{},"allowUnsigned: true"," is for — spelled separately from everything else,\nso it can only ever mean \"I thought about this\".",[13,583,584,587],{},[25,585,586],{},"Cross-language bodies."," The body is bound by digest over its JSON text, which is the one\nplace key order matters. A sender written in another language must emit the body the way it\nhashed it. Everything else is bound by value, which is what keeps a canonical-JSON\ndependency out of the wire.",[17,589,591],{"id":590},"the-browser-is-not-in-this","The browser is not in this",[13,593,594,595,597,598,523],{},"A browser sits outside the topology and holds no key. It never signs, and nothing it sends\nis taken as identity: the host resolves the session server-side from the request's own\ncookie, and the payload's ",[33,596,312],{}," is dropped. This page is about the link between two ",[315,599,600],{},"processes",[602,603,604],"style",{},"html pre.shiki code .sK6XW, html code.shiki .sK6XW{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#8FCF86;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s4mR9, html code.shiki .s4mR9{--shiki-light:#6182B8;--shiki-default:#C9B6EA;--shiki-dark:#82AAFF}html pre.shiki code .srlTG, html code.shiki .srlTG{--shiki-light:#90A4AE;--shiki-default:#A3B0A5;--shiki-dark:#BABED8}html pre.shiki code .sPEhv, html code.shiki .sPEhv{--shiki-light:#90A4AE;--shiki-default:#DDE5DA;--shiki-dark:#BABED8}html pre.shiki code .s15xx, html code.shiki .s15xx{--shiki-light:#39ADB5;--shiki-default:#A3B0A5;--shiki-dark:#89DDFF}html pre.shiki code .sHtqg, html code.shiki .sHtqg{--shiki-light:#E53935;--shiki-default:#93CFC0;--shiki-dark:#F07178}html pre.shiki code .sDDC1, html code.shiki .sDDC1{--shiki-light:#39ADB5;--shiki-default:#EE9F6B;--shiki-dark:#89DDFF}html pre.shiki code .sN-8n, html code.shiki .sN-8n{--shiki-light:#91B859;--shiki-default:#EE9F6B;--shiki-dark:#C3E88D}html pre.shiki code .skXKP, html code.shiki .skXKP{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#7D8C80;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}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 .s8ClO, html code.shiki .s8ClO{--shiki-light:#9C3EDA;--shiki-default:#93CFC0;--shiki-dark:#C792EA}html pre.shiki code .sWI7z, html code.shiki .sWI7z{--shiki-light:#E2931D;--shiki-default:#93CFC0;--shiki-dark:#FFCB6B}html pre.shiki code .sV8pK, html code.shiki .sV8pK{--shiki-light:#E2931D;--shiki-default:#C9B6EA;--shiki-dark:#FFCB6B}html pre.shiki code .sy9f4, html code.shiki .sy9f4{--shiki-light:#90A4AE;--shiki-default:#93CFC0;--shiki-dark:#BABED8}",{"title":43,"searchDepth":109,"depth":109,"links":606},[607,608,609,610,611,612,613,614],{"id":19,"depth":109,"text":20},{"id":173,"depth":109,"text":174},{"id":332,"depth":109,"text":333},{"id":352,"depth":109,"text":353},{"id":416,"depth":109,"text":417},{"id":496,"depth":109,"text":497},{"id":560,"depth":109,"text":561},{"id":590,"depth":109,"text":591},"A receiver that admits only the fronds you signed.","md",[390,408],"task",{},true,"\u002Fdocs\u002Frun\u002Fsecure",{"title":8,"description":615},"docs\u002F6.run\u002F2.secure",null,[626,627],"configuration","frond","mNcKVJe8XgYR33i2SZejCXnoZDR1TiUvnWJ6a8QrS_M",[630,633,636,639,642,645,648,651,654,659,664,669,673,677,681,685,689,694,698,702,707,711,716,720,724,728,730,734,738,742,746,750,754,758,762,766,770,773,776,779,782,785,788,791,794,797,800],{"path":631,"title":632,"uses":624},"\u002Fdocs\u002Fconcepts\u002Fentity","Entity",{"path":634,"title":635,"uses":624},"\u002Fdocs\u002Fconcepts\u002Fhandler","Handler",{"path":637,"title":638,"uses":624},"\u002Fdocs\u002Fconcepts\u002Frepository","Repository",{"path":640,"title":641,"uses":624},"\u002Fdocs\u002Fconcepts\u002Ffrond","Frond",{"path":643,"title":644,"uses":624},"\u002Fdocs\u002Fconcepts\u002Ffacade","Facade",{"path":646,"title":647,"uses":624},"\u002Fdocs\u002Fconcepts\u002Ffact","Fact",{"path":649,"title":650,"uses":624},"\u002Fdocs\u002Fconcepts\u002Fport","Port",{"path":652,"title":653,"uses":624},"\u002Fdocs\u002Fconcepts\u002Fconfiguration","Configuration",{"path":655,"title":656,"uses":657},"\u002Fdocs\u002Faccess\u002Fauthentication","Authentication",[658,627],"port",{"path":660,"title":661,"uses":662},"\u002Fdocs\u002Faccess\u002Fstate","Keep a caller's state",[626,663],"handler",{"path":665,"title":666,"uses":667},"\u002Fdocs\u002Fdata\u002Fsql","SQLite or Postgres",[668,626],"entity",{"path":670,"title":671,"uses":672},"\u002Fdocs\u002Fdata\u002Fseveral-databases","Several databases",[626,668],{"path":674,"title":675,"uses":676},"\u002Fdocs\u002Fdata\u002Fcomputed-field","A computed field",[668,658],{"path":678,"title":679,"uses":680},"\u002Fdocs\u002Fdata\u002Fevolve","Evolve a schema",[668],{"path":682,"title":683,"uses":684},"\u002Fdocs\u002Fdata\u002Fseeds","Seed data",[668],{"path":686,"title":687,"uses":688},"\u002Fdocs\u002Fdata\u002Fvalues","Read settings and secrets",[668,626],{"path":690,"title":691,"uses":692},"\u002Fdocs\u002Fdata\u002Fmirror","Mirror a source you cannot query",[693],"repository",{"path":695,"title":696,"uses":697},"\u002Fdocs\u002Fdata\u002Ftogether","Two writes as one",[693],{"path":699,"title":700,"uses":701},"\u002Fdocs\u002Fbehaviour\u002Faround-every-call","Around every call",[658,627],{"path":703,"title":704,"uses":705},"\u002Fdocs\u002Fbehaviour\u002Ffinish-a-fact","Finish a fact",[706],"fact",{"path":708,"title":709,"uses":710},"\u002Fdocs\u002Fserve\u002Frest-graphql","REST, OpenAPI, GraphQL",[663,626],{"path":712,"title":713,"uses":714},"\u002Fdocs\u002Fserve\u002Fpages","Pages: queries and commands",[663,715],"facade",{"path":717,"title":718,"uses":719},"\u002Fdocs\u002Fserve\u002Fforms","A form",[668],{"path":721,"title":722,"uses":723},"\u002Fdocs\u002Fserve\u002Fadmin","An admin panel",[663],{"path":725,"title":726,"uses":727},"\u002Fdocs\u002Frun\u002Fdeploy","Deploy a split",[626,627],{"path":621,"title":8,"uses":729},[626,627],{"path":731,"title":732,"uses":733},"\u002Fdocs\u002Frun\u002Flifecycle","Reload and shut down",[626],{"path":735,"title":736,"uses":737},"\u002Fdocs\u002Frun\u002Fobserve","Observe",[626,663],{"path":739,"title":740,"uses":741},"\u002Fdocs\u002Frun\u002Fdev-panel","The dev panel",[663],{"path":743,"title":744,"uses":745},"\u002Fdocs\u002Frun\u002Ftest","Test",[668,658],{"path":747,"title":748,"uses":749},"\u002Fdocs\u002Fadopt\u002Fnew-project","Start a project",[627,626],{"path":751,"title":752,"uses":753},"\u002Fdocs\u002Fadopt\u002Fexisting-app","Add Fougere to an existing app",[627,626],{"path":755,"title":756,"uses":757},"\u002Fdocs\u002Fadopt\u002Fbring-your-schema","Bring your schema",[668],{"path":759,"title":760,"uses":761},"\u002Fdocs\u002Fadopt\u002Fhosts","Pick a host",[626],{"path":763,"title":764,"uses":765},"\u002Fdocs\u002Fadopt\u002Fanother-repository","A frond from another repository",[715,627],{"path":767,"title":768,"uses":769},"\u002Fdocs\u002Fadopt\u002Fdemos","Demos",[],{"path":771,"title":772,"uses":624},"\u002Fdocs\u002Fextending\u002Fscan","How the scan reads a project",{"path":774,"title":775,"uses":624},"\u002Fdocs\u002Fextending\u002Fwithout-compiler","Boot without the compiler",{"path":777,"title":778,"uses":624},"\u002Fdocs\u002Fextending\u002Fboot","The boot, step by step",{"path":780,"title":781,"uses":624},"\u002Fdocs\u002Fextending\u002Fcard-and-wire","The card and the wire",{"path":783,"title":784,"uses":624},"\u002Fdocs\u002Fextending\u002Fextension-points","Registries and extension points",{"path":786,"title":787,"uses":624},"\u002Fdocs\u002Fextending\u002Fvocabulary","Teach a word",{"path":789,"title":790,"uses":624},"\u002Fdocs\u002Fextending\u002Fextensions","Run code at boot and shutdown",{"path":792,"title":793,"uses":624},"\u002Fdocs\u002Fextending\u002Fsource-adapter","Write a source adapter",{"path":795,"title":796,"uses":624},"\u002Fdocs\u002Fextending\u002Fsurface","Write a surface",{"path":798,"title":799,"uses":624},"\u002Fdocs\u002Fextending\u002Fforeign-frond","A frond in another language",{"path":801,"title":802,"uses":624},"\u002Fdocs","What is Fougere",[804],{"title":805,"path":801,"stem":806,"children":807,"page":-1},"Docs","docs",[808,810,831,840,861,870,883,899,916],{"title":802,"path":801,"stem":809},"docs\u002Findex",{"title":811,"path":812,"stem":813,"children":814,"page":5},"Concepts","\u002Fdocs\u002Fconcepts","docs\u002F1.concepts",[815,817,819,821,823,825,827,829],{"title":632,"path":631,"stem":816},"docs\u002F1.concepts\u002F1.entity",{"title":635,"path":634,"stem":818},"docs\u002F1.concepts\u002F2.handler",{"title":638,"path":637,"stem":820},"docs\u002F1.concepts\u002F3.repository",{"title":641,"path":640,"stem":822},"docs\u002F1.concepts\u002F4.frond",{"title":644,"path":643,"stem":824},"docs\u002F1.concepts\u002F5.facade",{"title":647,"path":646,"stem":826},"docs\u002F1.concepts\u002F6.fact",{"title":650,"path":649,"stem":828},"docs\u002F1.concepts\u002F7.port",{"title":653,"path":652,"stem":830},"docs\u002F1.concepts\u002F8.configuration",{"title":832,"path":833,"stem":834,"children":835,"page":5},"Access","\u002Fdocs\u002Faccess","docs\u002F2.access",[836,838],{"title":656,"path":655,"stem":837},"docs\u002F2.access\u002F1.authentication",{"title":661,"path":660,"stem":839},"docs\u002F2.access\u002F2.state",{"title":841,"path":842,"stem":843,"children":844,"page":5},"Data","\u002Fdocs\u002Fdata","docs\u002F3.data",[845,847,849,851,853,855,857,859],{"title":666,"path":665,"stem":846},"docs\u002F3.data\u002F1.sql",{"title":671,"path":670,"stem":848},"docs\u002F3.data\u002F2.several-databases",{"title":675,"path":674,"stem":850},"docs\u002F3.data\u002F3.computed-field",{"title":679,"path":678,"stem":852},"docs\u002F3.data\u002F4.evolve",{"title":683,"path":682,"stem":854},"docs\u002F3.data\u002F5.seeds",{"title":687,"path":686,"stem":856},"docs\u002F3.data\u002F6.values",{"title":691,"path":690,"stem":858},"docs\u002F3.data\u002F7.mirror",{"title":696,"path":695,"stem":860},"docs\u002F3.data\u002F8.together",{"title":862,"path":863,"stem":864,"children":865,"page":5},"Behaviour","\u002Fdocs\u002Fbehaviour","docs\u002F4.behaviour",[866,868],{"title":700,"path":699,"stem":867},"docs\u002F4.behaviour\u002F1.around-every-call",{"title":704,"path":703,"stem":869},"docs\u002F4.behaviour\u002F2.finish-a-fact",{"title":871,"path":872,"stem":873,"children":874,"page":5},"Serve","\u002Fdocs\u002Fserve","docs\u002F5.serve",[875,877,879,881],{"title":709,"path":708,"stem":876},"docs\u002F5.serve\u002F1.rest-graphql",{"title":713,"path":712,"stem":878},"docs\u002F5.serve\u002F2.pages",{"title":718,"path":717,"stem":880},"docs\u002F5.serve\u002F3.forms",{"title":722,"path":721,"stem":882},"docs\u002F5.serve\u002F4.admin",{"title":884,"path":885,"stem":886,"children":887,"page":5},"Run","\u002Fdocs\u002Frun","docs\u002F6.run",[888,890,891,893,895,897],{"title":726,"path":725,"stem":889},"docs\u002F6.run\u002F1.deploy",{"title":8,"path":621,"stem":623},{"title":732,"path":731,"stem":892},"docs\u002F6.run\u002F3.lifecycle",{"title":736,"path":735,"stem":894},"docs\u002F6.run\u002F4.observe",{"title":740,"path":739,"stem":896},"docs\u002F6.run\u002F5.dev-panel",{"title":744,"path":743,"stem":898},"docs\u002F6.run\u002F6.test",{"title":900,"path":901,"stem":902,"children":903,"page":5},"Adopt","\u002Fdocs\u002Fadopt","docs\u002F7.adopt",[904,906,908,910,912,914],{"title":748,"path":747,"stem":905},"docs\u002F7.adopt\u002F1.new-project",{"title":752,"path":751,"stem":907},"docs\u002F7.adopt\u002F2.existing-app",{"title":756,"path":755,"stem":909},"docs\u002F7.adopt\u002F3.bring-your-schema",{"title":760,"path":759,"stem":911},"docs\u002F7.adopt\u002F4.hosts",{"title":764,"path":763,"stem":913},"docs\u002F7.adopt\u002F5.another-repository",{"title":768,"path":767,"stem":915},"docs\u002F7.adopt\u002F6.demos",{"title":917,"path":918,"stem":919,"children":920,"page":5},"Extending","\u002Fdocs\u002Fextending","docs\u002F8.extending",[921,923,925,927,929,931,933,935,937,939],{"title":772,"path":771,"stem":922},"docs\u002F8.extending\u002F1.scan",{"title":775,"path":774,"stem":924},"docs\u002F8.extending\u002F10.without-compiler",{"title":778,"path":777,"stem":926},"docs\u002F8.extending\u002F2.boot",{"title":781,"path":780,"stem":928},"docs\u002F8.extending\u002F3.card-and-wire",{"title":784,"path":783,"stem":930},"docs\u002F8.extending\u002F4.extension-points",{"title":787,"path":786,"stem":932},"docs\u002F8.extending\u002F5.vocabulary",{"title":790,"path":789,"stem":934},"docs\u002F8.extending\u002F6.extensions",{"title":793,"path":792,"stem":936},"docs\u002F8.extending\u002F7.source-adapter",{"title":796,"path":795,"stem":938},"docs\u002F8.extending\u002F8.surface",{"title":799,"path":798,"stem":940},"docs\u002F8.extending\u002F9.foreign-frond",1794396614675]