-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsecurity.html
More file actions
38 lines (36 loc) · 62.7 KB
/
Copy pathsecurity.html
File metadata and controls
38 lines (36 loc) · 62.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!DOCTYPE html>
<html lang="en-US" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Security | Sovereign</title>
<meta name="description" content="Sovereign is an open-source workspace runtime for hosting private, multi-user apps on infrastructure you control.">
<meta name="generator" content="VitePress v1.6.4">
<link rel="preload stylesheet" href="/assets/style.zwcujjeL.css" as="style">
<link rel="preload stylesheet" href="/vp-icons.css" as="style">
<script type="module" src="/assets/app.6EG36zm-.js"></script>
<link rel="preload" href="/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
<link rel="modulepreload" href="/assets/chunks/theme.uZs-Jr1G.js">
<link rel="modulepreload" href="/assets/chunks/framework.CHeM0PsO.js">
<link rel="modulepreload" href="/assets/security.md.C_hafUnD.lean.js">
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
<script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
<link rel="canonical" href="https://sovereignfs.github.io/security">
<meta property="og:type" content="website">
<meta property="og:site_name" content="Sovereign">
<meta property="og:title" content="Security | Sovereign">
<meta property="og:description" content="Sovereign is an open-source workspace runtime for hosting private, multi-user apps on infrastructure you control.">
<meta property="og:url" content="https://sovereignfs.github.io/security">
<meta property="og:image" content="https://sovereignfs.github.io/social-preview.png">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Security | Sovereign">
<meta name="twitter:description" content="Sovereign is an open-source workspace runtime for hosting private, multi-user apps on infrastructure you control.">
<meta name="twitter:image" content="https://sovereignfs.github.io/social-preview.png">
</head>
<body>
<div id="app"><div class="Layout" data-v-715c0237><!--[--><!--]--><!--[--><span tabindex="-1" data-v-c20d2363></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-c20d2363>Skip to content</a><!--]--><!----><header class="VPNav" data-v-715c0237 data-v-a762df62><div class="VPNavBar" data-v-a762df62 data-v-b6b841c0><div class="wrapper" data-v-b6b841c0><div class="container" data-v-b6b841c0><div class="title" data-v-b6b841c0><div class="VPNavBarTitle has-sidebar" data-v-b6b841c0 data-v-27bf94fe><a class="title" href="/" data-v-27bf94fe><!--[--><!--]--><!----><span data-v-27bf94fe>Sovereign</span><!--[--><!--]--></a></div></div><div class="content" data-v-b6b841c0><div class="content-body" data-v-b6b841c0><!--[--><!--]--><div class="VPNavBarSearch search" data-v-b6b841c0><!--[--><!----><div id="local-search"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><span class="vp-icon DocSearch-Search-Icon"></span><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div><!--]--></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-b6b841c0 data-v-7f9a5953><span id="main-nav-aria-label" class="visually-hidden" data-v-7f9a5953> Main Navigation </span><!--[--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-7f9a5953 data-v-2c06edda><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-2c06edda><span class="text" data-v-2c06edda><!----><span data-v-2c06edda>Product</span><span class="vpi-chevron-down text-icon" data-v-2c06edda></span></span></button><div class="menu" data-v-2c06edda><div class="VPMenu" data-v-2c06edda data-v-aa41a574><div class="items" data-v-aa41a574><!--[--><!--[--><div class="VPMenuLink" data-v-aa41a574 data-v-7e2521cb><a class="VPLink link" href="/" data-v-7e2521cb><!--[--><span data-v-7e2521cb>Sovereign</span><!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-aa41a574 data-v-7e2521cb><a class="VPLink link" href="/sovereign-os/" data-v-7e2521cb><!--[--><span data-v-7e2521cb>Sovereign OS</span><!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-aa41a574 data-v-7e2521cb><a class="VPLink link" href="/sovereign-edge/" data-v-7e2521cb><!--[--><span data-v-7e2521cb>Sovereign Edge</span><!--]--></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/instances.html" tabindex="0" data-v-7f9a5953 data-v-63942258><!--[--><span data-v-63942258>Instances</span><!--]--></a><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-7f9a5953 data-v-2c06edda><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-2c06edda><span class="text" data-v-2c06edda><!----><span data-v-2c06edda>Docs</span><span class="vpi-chevron-down text-icon" data-v-2c06edda></span></span></button><div class="menu" data-v-2c06edda><div class="VPMenu" data-v-2c06edda data-v-aa41a574><div class="items" data-v-aa41a574><!--[--><!--[--><div class="VPMenuLink" data-v-aa41a574 data-v-7e2521cb><a class="VPLink link" href="/get-started/" data-v-7e2521cb><!--[--><span data-v-7e2521cb>Get Started</span><!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-aa41a574 data-v-7e2521cb><a class="VPLink link" href="/docs/" data-v-7e2521cb><!--[--><span data-v-7e2521cb>Full Documentation</span><!--]--></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/product-roadmap.html" tabindex="0" data-v-7f9a5953 data-v-63942258><!--[--><span data-v-63942258>Roadmap</span><!--]--></a><!--]--><!--[--><a class="VPLink link vp-external-link-icon VPNavBarMenuLink" href="https://github.com/sovereignfs/sovereign" target="_blank" rel="noreferrer" tabindex="0" data-v-7f9a5953 data-v-63942258><!--[--><span data-v-63942258>GitHub</span><!--]--></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-b6b841c0 data-v-ea9437ab><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-ea9437ab data-v-d11a2ca1 data-v-545e19d1><span class="check" data-v-545e19d1><span class="icon" data-v-545e19d1><!--[--><span class="vpi-sun sun" data-v-d11a2ca1></span><span class="vpi-moon moon" data-v-d11a2ca1></span><!--]--></span></span></button></div><div class="VPSocialLinks VPNavBarSocialLinks social-links" data-v-b6b841c0 data-v-78fc8d62 data-v-b533a98f><!--[--><a class="VPSocialLink no-icon" href="https://github.com/sovereignfs/sovereign" aria-label="github" target="_blank" rel="noopener" data-v-b533a98f data-v-4522f3d9><span class="vpi-social-github"></span></a><!--]--></div><div class="VPFlyout VPNavBarExtra extra" data-v-b6b841c0 data-v-0d5ff54f data-v-2c06edda><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-2c06edda><span class="vpi-more-horizontal icon" data-v-2c06edda></span></button><div class="menu" data-v-2c06edda><div class="VPMenu" data-v-2c06edda data-v-aa41a574><!----><!--[--><!--[--><!----><div class="group" data-v-0d5ff54f><div class="item appearance" data-v-0d5ff54f><p class="label" data-v-0d5ff54f>Appearance</p><div class="appearance-action" data-v-0d5ff54f><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-0d5ff54f data-v-d11a2ca1 data-v-545e19d1><span class="check" data-v-545e19d1><span class="icon" data-v-545e19d1><!--[--><span class="vpi-sun sun" data-v-d11a2ca1></span><span class="vpi-moon moon" data-v-d11a2ca1></span><!--]--></span></span></button></div></div></div><div class="group" data-v-0d5ff54f><div class="item social-links" data-v-0d5ff54f><div class="VPSocialLinks social-links-list" data-v-0d5ff54f data-v-b533a98f><!--[--><a class="VPSocialLink no-icon" href="https://github.com/sovereignfs/sovereign" aria-label="github" target="_blank" rel="noopener" data-v-b533a98f data-v-4522f3d9><span class="vpi-social-github"></span></a><!--]--></div></div></div><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-b6b841c0 data-v-ce597b2c><span class="container" data-v-ce597b2c><span class="top" data-v-ce597b2c></span><span class="middle" data-v-ce597b2c></span><span class="bottom" data-v-ce597b2c></span></span></button></div></div></div></div><div class="divider" data-v-b6b841c0><div class="divider-line" data-v-b6b841c0></div></div></div><!----></header><div class="VPLocalNav has-sidebar empty" data-v-715c0237 data-v-f158f50d><div class="container" data-v-f158f50d><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-f158f50d><span class="vpi-align-left menu-icon" data-v-f158f50d></span><span class="menu-text" data-v-f158f50d>Menu</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-v-f158f50d data-v-4d8a5c57><button data-v-4d8a5c57>Return to top</button><!----></div></div></div><aside class="VPSidebar" data-v-715c0237 data-v-360d37b6><div class="curtain" data-v-360d37b6></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-360d37b6><span class="visually-hidden" id="sidebar-aria-label" data-v-360d37b6> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="no-transition group" data-v-f954693f><section class="VPSidebarItem level-0" data-v-f954693f data-v-aeb3effe><div class="item" role="button" tabindex="0" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><h2 class="text" data-v-aeb3effe>Operator Guides</h2><!----></div><div class="items" data-v-aeb3effe><!--[--><div class="VPSidebarItem level-1 is-link" data-v-aeb3effe><div class="item" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><a class="VPLink link link" href="/self-hosting.html" data-v-aeb3effe><!--[--><p class="text" data-v-aeb3effe>Self-Hosting</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-aeb3effe><div class="item" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><a class="VPLink link link" href="/upgrade.html" data-v-aeb3effe><!--[--><p class="text" data-v-aeb3effe>Upgrade Guide</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-aeb3effe><div class="item" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><a class="VPLink link link" href="/troubleshooting.html" data-v-aeb3effe><!--[--><p class="text" data-v-aeb3effe>Troubleshooting</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-f954693f><section class="VPSidebarItem level-0" data-v-f954693f data-v-aeb3effe><div class="item" role="button" tabindex="0" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><h2 class="text" data-v-aeb3effe>App Developer Guides</h2><!----></div><div class="items" data-v-aeb3effe><!--[--><div class="VPSidebarItem level-1 is-link" data-v-aeb3effe><div class="item" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><a class="VPLink link link" href="/plugin-development.html" data-v-aeb3effe><!--[--><p class="text" data-v-aeb3effe>Overview</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-aeb3effe><div class="item" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><a class="VPLink link link" href="/sdk-stability.html" data-v-aeb3effe><!--[--><p class="text" data-v-aeb3effe>SDK Stability</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-aeb3effe><div class="item" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><a class="VPLink link link" href="/plugin-database.html" data-v-aeb3effe><!--[--><p class="text" data-v-aeb3effe>Plugin Database</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-aeb3effe><div class="item" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><a class="VPLink link link" href="/design-system.html" data-v-aeb3effe><!--[--><p class="text" data-v-aeb3effe>Design System</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-f954693f><section class="VPSidebarItem level-0 has-active" data-v-f954693f data-v-aeb3effe><div class="item" role="button" tabindex="0" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><h2 class="text" data-v-aeb3effe>Architecture & Security</h2><!----></div><div class="items" data-v-aeb3effe><!--[--><div class="VPSidebarItem level-1 is-link" data-v-aeb3effe><div class="item" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><a class="VPLink link link" href="/architecture.html" data-v-aeb3effe><!--[--><p class="text" data-v-aeb3effe>Architecture</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-aeb3effe><div class="item" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><a class="VPLink link link" href="/security.html" data-v-aeb3effe><!--[--><p class="text" data-v-aeb3effe>Security</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-aeb3effe><div class="item" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><a class="VPLink link link" href="/repositories.html" data-v-aeb3effe><!--[--><p class="text" data-v-aeb3effe>Repository Map</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-f954693f><section class="VPSidebarItem level-0" data-v-f954693f data-v-aeb3effe><div class="item" role="button" tabindex="0" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><h2 class="text" data-v-aeb3effe>Core Plugins</h2><!----></div><div class="items" data-v-aeb3effe><!--[--><div class="VPSidebarItem level-1 is-link" data-v-aeb3effe><div class="item" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><a class="VPLink link link" href="/plugins/console.html" data-v-aeb3effe><!--[--><p class="text" data-v-aeb3effe>Console</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-aeb3effe><div class="item" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><a class="VPLink link link" href="/plugins/launcher.html" data-v-aeb3effe><!--[--><p class="text" data-v-aeb3effe>Launcher</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-aeb3effe><div class="item" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><a class="VPLink link link" href="/plugins/account.html" data-v-aeb3effe><!--[--><p class="text" data-v-aeb3effe>Account</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-f954693f><section class="VPSidebarItem level-0" data-v-f954693f data-v-aeb3effe><div class="item" role="button" tabindex="0" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><h2 class="text" data-v-aeb3effe>Contributor Guides</h2><!----></div><div class="items" data-v-aeb3effe><!--[--><div class="VPSidebarItem level-1 is-link" data-v-aeb3effe><div class="item" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><a class="VPLink link link" href="/documentation-structure.html" data-v-aeb3effe><!--[--><p class="text" data-v-aeb3effe>Documentation Structure</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-aeb3effe><div class="item" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><a class="VPLink link link" href="/development-workflow.html" data-v-aeb3effe><!--[--><p class="text" data-v-aeb3effe>Development Workflow</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-aeb3effe><div class="item" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><a class="VPLink link link" href="/agent-first-documentation.html" data-v-aeb3effe><!--[--><p class="text" data-v-aeb3effe>Agent-First Documentation</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-aeb3effe><div class="item" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><a class="VPLink link link" href="/architecture-rules.html" data-v-aeb3effe><!--[--><p class="text" data-v-aeb3effe>Architecture Rules</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-aeb3effe><div class="item" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><a class="VPLink link link" href="/testing-e2e.html" data-v-aeb3effe><!--[--><p class="text" data-v-aeb3effe>Testing E2E</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-aeb3effe><div class="item" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><a class="VPLink link link" href="/pwa-real-device-testing.html" data-v-aeb3effe><!--[--><p class="text" data-v-aeb3effe>PWA Device Testing</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-f954693f><section class="VPSidebarItem level-0 collapsible collapsed" data-v-f954693f data-v-aeb3effe><div class="item" role="button" tabindex="0" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><h2 class="text" data-v-aeb3effe>RFCs</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-aeb3effe><span class="vpi-chevron-right caret-icon" data-v-aeb3effe></span></div></div><div class="items" data-v-aeb3effe><!--[--><div class="VPSidebarItem level-1 is-link" data-v-aeb3effe><div class="item" data-v-aeb3effe><div class="indicator" data-v-aeb3effe></div><a class="VPLink link link" href="/rfcs/README.html" data-v-aeb3effe><!--[--><p class="text" data-v-aeb3effe>RFC Index</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-715c0237 data-v-41cd1916><div class="VPDoc has-sidebar has-aside" data-v-41cd1916 data-v-d9bf7dc2><!--[--><!--]--><div class="container" data-v-d9bf7dc2><div class="aside" data-v-d9bf7dc2><div class="aside-curtain" data-v-d9bf7dc2></div><div class="aside-container" data-v-d9bf7dc2><div class="aside-content" data-v-d9bf7dc2><div class="VPDocAside" data-v-d9bf7dc2 data-v-a7bc4d01><!--[--><!--]--><!--[--><!--]--><nav aria-labelledby="doc-outline-aria-label" class="VPDocAsideOutline" data-v-a7bc4d01 data-v-77892794><div class="content" data-v-77892794><div class="outline-marker" data-v-77892794></div><div aria-level="2" class="outline-title" id="doc-outline-aria-label" role="heading" data-v-77892794>On this page</div><ul class="VPDocOutlineItem root" data-v-77892794 data-v-9a6a84b8><!--[--><!--]--></ul></div></nav><!--[--><!--]--><div class="spacer" data-v-a7bc4d01></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-d9bf7dc2><div class="content-container" data-v-d9bf7dc2><!--[--><!--]--><main class="main" data-v-d9bf7dc2><div style="position:relative;" class="vp-doc _security" data-v-d9bf7dc2><div><h1 id="security" tabindex="-1">Security <a class="header-anchor" href="#security" aria-label="Permalink to "Security""></a></h1><p>This document describes Sovereign's <strong>security posture</strong> — the threat model, the hardening that ships in v1, and a checklist for self-hosters. It complements <a href="https://github.com/sovereignfs/sovereign/blob/main/SECURITY.md" target="_blank" rel="noreferrer"><code>SECURITY.md</code></a> (vulnerability disclosure) and implements <a href="./rfcs/0008-security-encryption-architecture.html">RFC 0008</a> / SRS §3.17.</p><p>Sovereign is <strong>self-hosted and privacy-first</strong>: you run it, you own the data.</p><h2 id="no-telemetry" tabindex="-1">No telemetry <a class="header-anchor" href="#no-telemetry" aria-label="Permalink to "No telemetry""></a></h2><p>Sovereign sends <strong>no analytics, telemetry, or usage data</strong> anywhere. There is no outbound "phone home", no third-party scripts, and no tracking. The only network calls a deployment makes are the ones you configure: the database, the SMTP server (if email is enabled), and the browser ↔ your instance. This is a guarantee, not a default you can toggle.</p><h2 id="logging-and-telemetry" tabindex="-1">Logging and telemetry <a class="header-anchor" href="#logging-and-telemetry" aria-label="Permalink to "Logging and telemetry""></a></h2><p>Sovereign's structured logger (RFC 0020) writes newline-delimited JSON to the process's own <strong>stdout/stderr</strong> — controlled by the <code>LOG_LEVEL</code> env var (<code>warn</code> by default). No log data is sent to any third party. Operators read logs via <code>docker logs</code>, <code>journalctl</code>, or their own log aggregator on the same host.</p><p>This is <strong>logging, not telemetry</strong>: everything stays on the operator's infrastructure. The no-telemetry guarantee is intact — the distinction is where the data goes, not whether it exists.</p><h2 id="production-dev-mode-isolation" tabindex="-1">Production dev-mode isolation <a class="header-anchor" href="#production-dev-mode-isolation" aria-label="Permalink to "Production dev-mode isolation""></a></h2><p>The optional <a href="./self-hosting.html#production-dev-mode-rfc-0020">production dev-mode</a> feature routes platform database reads and writes for a single request to a mock database, leaving all other concurrent requests unaffected. The isolation properties that make this safe to run on a live instance:</p><ul><li><strong>Off unless explicitly enabled.</strong> <code>SOVEREIGN_DEV_MODE_ENABLED</code> must be <code>true</code>; without it the <code>X-Sovereign-Dev-Mode-Secret</code> header is silently ignored.</li><li><strong>Secret-gated per request.</strong> Switching to the mock DB requires both a valid session cookie (authenticated caller) and the <code>SOVEREIGN_DEV_MODE_SECRET</code> header.</li><li><strong>Per-request, never global.</strong> The mock client is selected inside <code>getPlatformDb()</code> by reading the forwarded <code>x-sovereign-dev-mode</code> request header for that request's Next.js context only. A concurrent real-user request with no such header sees the production database as normal.</li><li><strong>Hard isolation between clients.</strong> The mock DB is a separate Drizzle <code>createClient()</code> instance. There is no code path from a dev-mode request back to the production <code>PlatformDb</code> singleton.</li><li><strong>Audited.</strong> Every activation is logged as a JSON line (level <code>info</code>) to server stdout, including the user ID and path, so operators can review usage via <code>docker logs</code>.</li></ul><h2 id="threat-model" tabindex="-1">Threat model <a class="header-anchor" href="#threat-model" aria-label="Permalink to "Threat model""></a></h2><p>Security controls are only meaningful against a stated adversary. <strong>Assets:</strong> the identity database (<code>auth.db</code>), the platform database (<code>sovereign.db</code>), plugin data, avatars/blobs, backups, secrets, and live sessions.</p><table tabindex="0"><thead><tr><th>Threat</th><th>Addressed by</th><th>Ships in</th><th>Residual risk</th></tr></thead><tbody><tr><td>Network sniffing / MITM</td><td>Transport: TLS/HSTS at the edge, Postgres SSL</td><td><strong>v1</strong></td><td>Endpoint compromise.</td></tr><tr><td>XSS / injected scripts</td><td>Strict nonce-based CSP + security headers</td><td><strong>v1</strong></td><td>A bug that echoes a valid nonce.</td></tr><tr><td>Clickjacking</td><td><code>X-Frame-Options: DENY</code> + <code>frame-ancestors 'none'</code></td><td><strong>v1</strong></td><td>—</td></tr><tr><td>Stolen or guessed password</td><td>TOTP / passkey second factor (opt-in per user)</td><td><strong>v1</strong></td><td>Users who haven't enrolled MFA have password-only auth.</td></tr><tr><td>Forged session cookie</td><td>HMAC-signed cookie cache; Argon2id passwords (better-auth)</td><td><strong>v1</strong></td><td>Stolen live cookie from a compromised device.</td></tr><tr><td>Compromised / curious plugin</td><td>SDK boundary (plugins can't import runtime internals)</td><td><strong>v1</strong></td><td>A plugin still sees its own users' data.</td></tr><tr><td>Stolen disk / leaked backup / VPS snapshot</td><td><strong>Opt-in SQLite at-rest encryption</strong> (RFC 0071, <code>SOVEREIGN_DB_ENCRYPTION_KEY</code>) for <code>sovereign.db</code>/<code>auth.db</code> always, plus any isolated plugin DB whose manifest requests it (<code>database.requireEncryption</code>, per-database enforcement — task 8.15); host-level disk encryption for everything else (Postgres, avatars/blobs, non-requesting plugin DBs); full envelope/field-level at-rest post-v1 (Task 8.5)</td><td><strong>v1 (opt-in, SQLite)</strong> / post-v1 (rest)</td><td>Off by default — without it enabled, rely on host-level disk encryption. Even enabled, server-held keys never defend against a curious operator or RCE (see the client-side row below for that).</td></tr><tr><td>Curious/malicious host or hosting provider</td><td>Field-level encryption; opt-in client-side encryption (RFC 0060), adopted today by <strong>Account</strong> (the encryption profile itself) and <strong>Sovereign Wallet</strong> (card/document contents) only</td><td><strong>v1 (opt-in, 2 plugins)</strong> / post-v1 (field-level)</td><td>Everything outside those two plugins' encrypted fields — which is the large majority of platform and plugin data — still relies on host-level protection in v1.</td></tr><tr><td>RCE / compromised server process</td><td>Client-side encryption (RFC 0060) for the specific objects Account/Wallet protect this way</td><td><strong>v1 (opt-in, 2 plugins)</strong></td><td>Data not passed through client-side encryption — i.e. nearly everything except Wallet's card/document fields — is still readable by an attacker with code execution.</td></tr><tr><td>Malicious/open-redirect via a registered external OAuth client (RFC 0072)</td><td>Exact-string <code>redirect_uri</code> matching per registered client; client secrets stored hashed, never re-displayed; client registration restricted to platform admins/owner (no dynamic/self-service registration)</td><td><strong>v1 (opt-in feature)</strong></td><td>A compromised admin account can register a client with an attacker-controlled redirect URI — the same trust boundary as every other Console admin action. Revoking a client stops new token issuance immediately; already-issued access tokens are left to expire naturally.</td></tr></tbody></table><p><strong>Honest framing.</strong> v1 ships Tiers 0–1 of RFC 0008 (hardening + transport) plus Tier 4 (client-side/zero-knowledge encryption, RFC 0060) as an <strong>opt-in capability</strong> the SDK makes available to any plugin — but only two plugins have actually adopted it so far: <strong>Account</strong> (its own encryption-profile setup/ recovery UX) and <strong>Sovereign Wallet</strong> (card metadata and ID/document images). For the fields those two plugins chose to encrypt, the runtime and server-side plugin code can never decrypt them, even with full server access. This is <strong>not a blanket guarantee</strong> and should not be read as "Sovereign has client-side encryption" in the general sense: every other plugin (Tasks, Ledger, Docs, PlainWrite, HealthLog, Shopper, Tally, TriText) currently stores its data with no client-side or at-rest protection, and most platform data overall is <strong>not</strong> encrypted at rest by default — anyone who can read the server's disk or a raw backup can still read the bulk of it, including all non-Wallet plugin data. Protect the host accordingly (see the checklist). At-rest and field-level encryption for the rest of the data model are specified and deferred to Task 1.0.1. Extending Tier 4 to another plugin is a per-plugin engineering decision — most plugins' core functionality depends on server-side search, aggregation, or cross-user sharing that ciphertext-only storage would break (see the per-plugin sensitivity assessment referenced in the RFC 0060 adoption notes) — not something that broadens automatically.</p><h2 id="what-v1-enforces" tabindex="-1">What v1 enforces <a class="header-anchor" href="#what-v1-enforces" aria-label="Permalink to "What v1 enforces""></a></h2><ul><li><strong>Security headers on every response</strong> (both the runtime and the auth app): <ul><li><code>Content-Security-Policy</code> — strict and <strong>nonce-based</strong>: inline scripts run only with a per-request nonce (set in middleware); no <code>'unsafe-inline'</code> for scripts. <code>object-src 'none'</code>, <code>base-uri 'self'</code>, <code>frame-ancestors 'none'</code>.</li><li><code>Strict-Transport-Security</code> (production only) — <code>max-age</code> 2 years, <code>includeSubDomains; preload</code>.</li><li><code>X-Frame-Options: DENY</code>, <code>X-Content-Type-Options: nosniff</code>, <code>Referrer-Policy: strict-origin-when-cross-origin</code>, <code>Permissions-Policy</code> (camera/microphone/geolocation/topics disabled).</li></ul></li><li><strong>No secrets with defaults.</strong> <code>AUTH_SECRET</code> / <code>SOVEREIGN_AUTH_SECRET</code>, <code>SOVEREIGN_ADMIN_KEY</code>, and vault encryption keys have no plaintext fallback. Features that require them fail closed when unset.</li><li><strong>Session cookies</strong> are <code>httpOnly</code>; the signed <code>session_data</code> cache cookie is HMAC-verified offline and carries <code>Secure</code> in production (<code>__Secure-</code> prefix).</li><li><strong>Transport:</strong> Postgres connects over TLS when the connection string sets <code>sslmode</code> (see below); the public edge must terminate TLS with HSTS.</li><li><strong>Login rate limiting</strong> is active in all environments (dev + production): the auth server enforces 3 sign-in attempts per 10 seconds per IP address and 3 password-reset requests per 60 seconds per IP (via better-auth's built-in per-path rate limiter). Responses above the limit return <code>429 Too Many Requests</code> with an <code>X-Retry-After</code> header. Rate limiting is stored in-memory per process (sufficient for single-instance deployments); a shared secondary storage (e.g. Redis) would be needed for multi-instance setups.</li><li><strong>Email verification is required by default</strong> (<code>AUTH_REQUIRE_EMAIL_VERIFICATION=true</code>). A new account must click an emailed link before it can sign in; registration does not grant a session until then. Operators can disable this (<code>AUTH_REQUIRE_EMAIL_VERIFICATION=false</code>) for air-gapped/internal deployments. Accounts that existed before this shipped are grandfathered automatically — the requirement only applies to new registrations.</li><li><strong>Console-managed SMTP settings (platform:owner only)</strong>: an owner can view and change SMTP host/port/user/password/from-address from Console → Settings, with changes taking effect immediately (no restart). The password is encrypted at rest with the same AES-256-GCM scheme (<code>SOVEREIGN_VAULT_KEY</code>) used by the plugin secret vault — never stored in plaintext, never logged, never returned to the client after saving (the form shows only whether a password is set, not its value). Non-owners see the current settings read-only and cannot save or send a test email.</li><li><strong>External OAuth/OIDC provider (RFC 0072, opt-in feature)</strong>: the auth server can act as an identity provider for standalone external apps not composed as Sovereign plugins. Client registration/rotation/revocation is restricted to platform admins and the owner — there is no dynamic or self-service client registration. <code>redirect_uri</code> matching is exact-string only (no prefix/wildcard), and client secrets are stored <strong>hashed</strong>, never reversibly encrypted or re-displayed after creation — see <a href="./self-hosting.html#external-oauthoidc-provider-rfc-0072">self-hosting.md</a>. This is new externally-reachable attack surface (arbitrary registered redirect targets, not just same-origin plugin routes) — see the threat model row above.</li><li><strong>Client-side encryption (RFC 0060) has no operator recovery path, by design.</strong> A user unlocks their Client Master Key with a recorded recovery secret or an already-enrolled device — the server never holds a plaintext copy or an escrow key. <strong>Resetting a user's password does not recover their encrypted data</strong>; a lost recovery secret plus every enrolled device being lost means that data is permanently unrecoverable, for anyone, including the operator. Account deletion removes all client-side encryption material (profile, recovery wrapper, device enrollments) unconditionally — this is always safe, since none of it is ever plaintext. Account export includes this same wrapped material (still ciphertext-only) so a user's ability to unlock their data can travel with a data export/migration, provided they still have their recovery secret.</li></ul><h2 id="self-hoster-hardening-checklist" tabindex="-1">Self-hoster hardening checklist <a class="header-anchor" href="#self-hoster-hardening-checklist" aria-label="Permalink to "Self-hoster hardening checklist""></a></h2><ul><li>[ ] <strong>Terminate TLS at a reverse proxy</strong> (Caddy/nginx/Traefik) and redirect HTTP → HTTPS. See <a href="./self-hosting.html#reverse-proxy">self-hosting.md</a>. HSTS is emitted automatically by the apps in production.</li><li>[ ] <strong>Generate strong secrets</strong> (<code>openssl rand -base64 32</code>) for <code>AUTH_SECRET</code> and <code>SOVEREIGN_ADMIN_KEY</code>; never reuse or commit them.</li><li>[ ] <strong>Encrypt the host disk / volume</strong> — nothing is encrypted at rest by default, so this is your baseline protection for a stolen disk or snapshot. For SQLite deployments, an opt-in, single-key at-rest option is available — see <a href="./self-hosting.html#sqlite-at-rest-encryption-rfc-0071">SQLite at-rest encryption</a> (RFC 0071, <code>SOVEREIGN_DB_ENCRYPTION_KEY</code>). Postgres has no equivalent; host-level encryption remains the only protection there. Either way, back up the encryption key separately from the data.</li><li>[ ] <strong>Use Postgres over TLS</strong> for non-local databases: add <code>?sslmode=require</code> (or <code>verify-full</code> with a CA) to <code>DATABASE_URL</code> / <code>AUTH_DATABASE_URL</code>.</li><li>[ ] <strong>Enable MFA for all admin accounts</strong> — enroll TOTP or a passkey from Account → Security. MFA is opt-in; admins are not automatically required to use it in v1. Until mandatory-MFA enforcement lands, treat admin enrollment as a manual policy step.</li><li>[ ] <strong>Restrict network exposure</strong> — only the reverse proxy should be public; keep the auth server, database, and Mailpit on the internal network.</li><li>[ ] <strong>Configure <code>SMTP_HOST</code></strong> if you keep <code>AUTH_REQUIRE_EMAIL_VERIFICATION</code> at its default (<code>true</code>) — without SMTP, new registrations fail closed rather than issuing an unverifiable account.</li><li>[ ] <strong>Keep backups encrypted and off-host</strong>, and test restores.</li><li>[ ] <strong>Update regularly</strong> and watch the repository's security advisories.</li></ul><h2 id="reporting-a-vulnerability" tabindex="-1">Reporting a vulnerability <a class="header-anchor" href="#reporting-a-vulnerability" aria-label="Permalink to "Reporting a vulnerability""></a></h2><p>See <a href="https://github.com/sovereignfs/sovereign/blob/main/SECURITY.md" target="_blank" rel="noreferrer"><code>SECURITY.md</code></a>. Please do not file public issues for security reports.</p></div></div></main><footer class="VPDocFooter" data-v-d9bf7dc2 data-v-83d8eeda><!--[--><!--]--><!----><nav class="prev-next" aria-labelledby="doc-footer-aria-label" data-v-83d8eeda><span class="visually-hidden" id="doc-footer-aria-label" data-v-83d8eeda>Pager</span><div class="pager" data-v-83d8eeda><a class="VPLink link pager-link prev" href="/architecture.html" data-v-83d8eeda><!--[--><span class="desc" data-v-83d8eeda>Previous page</span><span class="title" data-v-83d8eeda>Architecture</span><!--]--></a></div><div class="pager" data-v-83d8eeda><a class="VPLink link pager-link next" href="/repositories.html" data-v-83d8eeda><!--[--><span class="desc" data-v-83d8eeda>Next page</span><span class="title" data-v-83d8eeda>Repository Map</span><!--]--></a></div></nav></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><footer class="VPFooter has-sidebar" data-v-715c0237 data-v-0094cebd><div class="container" data-v-0094cebd><p class="message" data-v-0094cebd>Open source under AGPL-3.0. Each Sovereign instance is independently operated.</p><p class="copyright" data-v-0094cebd>Sovereign</p></div></footer><!--[--><!--]--></div></div>
<script>window.__VP_HASH_MAP__=JSON.parse("{\"agent-first-documentation.md\":\"CmQ9uZ2U\",\"architecture-rules.md\":\"Cx4aTRzE\",\"architecture.md\":\"pHZYMije\",\"design-system.md\":\"BCuXfBph\",\"development-workflow.md\":\"DSt8dR4f\",\"docs_architecture.md\":\"CTvtqEJD\",\"docs_contributing.md\":\"B42xq8z5\",\"docs_developers.md\":\"u0c0kF0l\",\"docs_index.md\":\"C1416hhU\",\"docs_operators.md\":\"BzmbkU9Y\",\"docs_pwa.md\":\"C5wA0Xg-\",\"docs_users.md\":\"CkufVO3w\",\"documentation-structure.md\":\"C8TjlHhZ\",\"get-started_developers.md\":\"Cd21BajS\",\"get-started_index.md\":\"wEQNAJKH\",\"get-started_operators.md\":\"DfsGlfLb\",\"get-started_users.md\":\"DvHHggUB\",\"index.md\":\"C7tElUdp\",\"instances.md\":\"BF3w1-Ow\",\"plugin-database.md\":\"B0HKu7yT\",\"plugin-development.md\":\"CwXd-zw0\",\"plugins_account.md\":\"BTJtLwJt\",\"plugins_console.md\":\"C29qkKyl\",\"plugins_launcher.md\":\"BX-BziDV\",\"product-roadmap.md\":\"-EY1dEXj\",\"product_apps.md\":\"Dif68fZ2\",\"product_features.md\":\"BVncgaJX\",\"product_how-it-works.md\":\"Bu8Ef18G\",\"product_index.md\":\"D0cgdprY\",\"product_why-sovereign.md\":\"DEHJ0FlN\",\"pwa-real-device-testing.md\":\"CItwnEQF\",\"repositories.md\":\"CljuMT6q\",\"rfcs_0001-overlay-shell-variant.md\":\"vvJidCFH\",\"rfcs_0002-cross-plugin-data-sharing.md\":\"DM5YxVRN\",\"rfcs_0003-plugin-monetization.md\":\"cq6Tk2-Y\",\"rfcs_0004-per-plugin-database.md\":\"CwnzpSci\",\"rfcs_0005-activity-log.md\":\"DYzfMNp9\",\"rfcs_0006-deployment-upgrade-strategy.md\":\"CM6iGaWr\",\"rfcs_0007-user-data-portability.md\":\"sXYh6TM7\",\"rfcs_0008-security-encryption-architecture.md\":\"DcoOkSLt\",\"rfcs_0009-internal-package-codenames.md\":\"BWHdFpI2\",\"rfcs_0010-test-organization.md\":\"Bqc9joPJ\",\"rfcs_0011-icon-system.md\":\"5Sv8QWaY\",\"rfcs_0012-passkeys-and-mfa.md\":\"DjI-taH4\",\"rfcs_0013-mobile-responsiveness-pwa.md\":\"DwZoKtJb\",\"rfcs_0014-minimal-shell-mode.md\":\"D7ZykUa0\",\"rfcs_0015-notification-center.md\":\"QNs0dD6A\",\"rfcs_0016-web-push.md\":\"CGSa5XX2\",\"rfcs_0017-plugin-starter-and-examples.md\":\"BAri0NZb\",\"rfcs_0018-plugin-scoped-env.md\":\"CZwRAMom\",\"rfcs_0019-test-setup-and-seeding.md\":\"DpwFekRi\",\"rfcs_0020-production-dev-mode.md\":\"Di6ptx6Y\",\"rfcs_0021-platform-roles-and-capabilities.md\":\"8HUNQr4u\",\"rfcs_0022-plugin-capabilities.md\":\"Dob9F4yZ\",\"rfcs_0023-sdk-distribution.md\":\"Bj-eYkYo\",\"rfcs_0024-plugin-compatibility.md\":\"CshTbJfZ\",\"rfcs_0025-accessibility.md\":\"jCEAUNa-\",\"rfcs_0026-non-docker-deployment.md\":\"CRQvrbmp\",\"rfcs_0027-white-labeling.md\":\"B7WSxyFt\",\"rfcs_0028-operator-fork-model.md\":\"D4VfDNFP\",\"rfcs_0029-internationalization.md\":\"BzpEhgCU\",\"rfcs_0030-privacy-first-analytics.md\":\"X7QiqoZ5\",\"rfcs_0031-email-templates.md\":\"Dn1TDcGo\",\"rfcs_0032-instance-identity-rename.md\":\"Cgcv5Ppw\",\"rfcs_0033-user-data-deletion.md\":\"TRHdaPr0\",\"rfcs_0034-notification-transport.md\":\"DRD3C2o2\",\"rfcs_0035-progressive-user-verification.md\":\"BNvXOJIB\",\"rfcs_0036-per-plugin-dialect.md\":\"BigHhmEf\",\"rfcs_0037-vitepress-docs-site.md\":\"BEx8SX-o\",\"rfcs_0038-desktop-app-shell.md\":\"Dt0samoy\",\"rfcs_0039-instance-id-and-terminology.md\":\"DPzX0tQF\",\"rfcs_0040-sovereign-harness.md\":\"CMAO2wm4\",\"rfcs_0041-user-directory.md\":\"DE8UEQ26\",\"rfcs_0042-public-plugin-routes.md\":\"CuN3jeiW\",\"rfcs_0043-plugin-secret-vault.md\":\"CYVwkrzl\",\"rfcs_0044-plugin-storage.md\":\"f2OlNBqK\",\"rfcs_0045-plugin-events.md\":\"1eXtUWDm\",\"rfcs_0046-plugin-jobs.md\":\"C7ZB6kYP\",\"rfcs_0047-plugin-tools.md\":\"9VhGqGjO\",\"rfcs_0048-messages-and-notification-detail.md\":\"BxempQdG\",\"rfcs_0049-plugin-external-connections.md\":\"DDs1tJNq\",\"rfcs_0050-public-plugin-webhooks.md\":\"CZqrqXr1\",\"rfcs_0051-cross-plugin-references.md\":\"CxcbuQRM\",\"rfcs_0052-plugin-portability-hooks.md\":\"CG3w5i84\",\"rfcs_0053-plugin-flow-handoffs.md\":\"p9jyXoOp\",\"rfcs_0054-plugin-scoped-roles-and-grants.md\":\"6FQAVqyQ\",\"rfcs_0055-sovereign-council.md\":\"C24pgP24\",\"rfcs_0056-sovereign-guide.md\":\"MYmlqvzs\",\"rfcs_0057-plugin-dep-hoisting.md\":\"DT5r1KJO\",\"rfcs_0058-native-mobile-app-shell.md\":\"BbQWeRx4\",\"rfcs_0059-local-visual-regression-testing.md\":\"BoVadqeA\",\"rfcs_0060-client-side-encryption-core.md\":\"CYSfngI_\",\"rfcs_0061-sovereign-wallet.md\":\"3-YMVh3T\",\"rfcs_0062-email-delivery-coverage.md\":\"BvhhuQrj\",\"rfcs_0063-core-assistant-jarvis.md\":\"CtWnYbDP\",\"rfcs_0064-git-backed-operator-backups.md\":\"CPFMz5c2\",\"rfcs_0065-user-groups-plugin-access.md\":\"BI6AH5kN\",\"rfcs_0066-sovereign-chat-p2p-identity.md\":\"Bnqamz2T\",\"rfcs_0067-product-led-docs-site.md\":\"C90FKbj5\",\"rfcs_0068-export-completeness-hardening.md\":\"P1Kcc-5s\",\"rfcs_0069-bring-your-own-database.md\":\"BCtSkrVT\",\"rfcs_0070-per-user-capability-grants.md\":\"Cr5mZ3uV\",\"rfcs_0071-sqlite-at-rest-encryption.md\":\"D30oSdgW\",\"rfcs_0072-external-oauth-provider.md\":\"CPD3TrpW\",\"rfcs_0073-standalone-ui-package.md\":\"EMqC_8lx\",\"rfcs_0074-offline-capable-plugins.md\":\"BF_6VrJ7\",\"rfcs_0075-mobile-chrome-toggle.md\":\"CvSkwFS_\",\"rfcs_0076-ds-sizing-alignment-and-new-primitives.md\":\"GNuVs8zd\",\"rfcs_0077-instance-radius-control.md\":\"B7BB5aCj\",\"rfcs_0078-offline-plugin-writes.md\":\"rKKRaOKS\",\"rfcs_0079-mobile-pwa-layout-overlay-gesture-consistency.md\":\"DmpNSvEA\",\"rfcs_0080-plugin-surface-model.md\":\"BDPyngLw\",\"rfcs_0081-per-plugin-installable-pwa.md\":\"DJMWhDxn\",\"rfcs_0082-focused-plugin-app-shell.md\":\"D4_iPPcb\",\"rfcs_0083-device-bridge-capability-contract.md\":\"DQaUiEy_\",\"rfcs_readme.md\":\"MMMnqIGc\",\"sdk-stability.md\":\"AzSRLjD0\",\"security.md\":\"C_hafUnD\",\"self-hosting.md\":\"PAzKm1dp\",\"sovereign-edge_concept.md\":\"DtQrQOij\",\"sovereign-edge_development-workflow.md\":\"CKICNWtv\",\"sovereign-edge_epics_connector-framework.md\":\"aGMb644A\",\"sovereign-edge_epics_connector-store-sdk.md\":\"DeeWv2oF\",\"sovereign-edge_epics_core-inference-chat.md\":\"Bx4iN8-l\",\"sovereign-edge_epics_design-system.md\":\"T1iUS4ot\",\"sovereign-edge_epics_desktop-app.md\":\"CeXa6frv\",\"sovereign-edge_epics_infrastructure.md\":\"DBGFmEHg\",\"sovereign-edge_epics_mobile-app-shell.md\":\"DUyJewX1\",\"sovereign-edge_epics_monetization.md\":\"C5vBmuod\",\"sovereign-edge_epics_readme.md\":\"CJKDjtBD\",\"sovereign-edge_epics_search-connector.md\":\"kO5AXuQr\",\"sovereign-edge_epics_sovereign-tasks-connector.md\":\"IZLBbOxo\",\"sovereign-edge_index.md\":\"CVLqJ6G1\",\"sovereign-edge_research_0001-concept-and-connector-architecture.md\":\"CBLKABPV\",\"sovereign-edge_research_0002-react-native-framework-choice.md\":\"BdzEE9tA\",\"sovereign-edge_research_0003-model-verification-hashing.md\":\"4pbrthF-\",\"sovereign-edge_research_readme.md\":\"B1_HyndM\",\"sovereign-edge_roadmap.md\":\"CpWcYP2A\",\"sovereign-os_adrs_0001-phase-01-appliance-architecture.md\":\"D46xajjU\",\"sovereign-os_adrs_0002-install-images-and-update-artifacts.md\":\"C3L2S8mQ\",\"sovereign-os_adrs_0003-preview-bootstrap-access.md\":\"DIKCmAT8\",\"sovereign-os_adrs_0004-provider-neutral-assistant-and-web-search.md\":\"BLaVS-YP\",\"sovereign-os_adrs_0005-sovereign-console-and-health-boundary.md\":\"C2niKl8U\",\"sovereign-os_adrs_0006-production-signing-key-custody.md\":\"CWVIjHYQ\",\"sovereign-os_adrs_0007-console-authentication.md\":\"fPbnw3nN\",\"sovereign-os_adrs_0008-console-privileged-action-invocation.md\":\"DqdDv2uh\",\"sovereign-os_adrs_0009-console-triggered-install.md\":\"BjgqurX0\",\"sovereign-os_adrs_readme.md\":\"BLFKdZXp\",\"sovereign-os_concept.md\":\"BhHrt-cM\",\"sovereign-os_index.md\":\"533qWSwP\",\"sovereign-os_product_core-use-cases.md\":\"CRe30f0V\",\"sovereign-os_product_preview-scope.md\":\"JgpI2elD\",\"sovereign-os_product_target-user.md\":\"D_eNIS0o\",\"sovereign-os_product_terminology.md\":\"D0XrNM2B\",\"sovereign-os_rfcs_0010-raspberry-pi-image-deployment.md\":\"ZsxEbkml\",\"sovereign-os_rfcs_0014-appliance-update-system.md\":\"CvAyD5DN\",\"sovereign-os_rfcs_0015-update-discovery.md\":\"DL-9_SMg\",\"sovereign-os_rfcs_readme.md\":\"Cuxysy6k\",\"sovereign-os_roadmap.md\":\"dqbKdRM7\",\"testing-e2e.md\":\"Dc-biHyn\",\"troubleshooting.md\":\"BxCe9Han\",\"upgrade.md\":\"DZuTHIBf\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"Sovereign\",\"description\":\"Sovereign is an open-source workspace runtime for hosting private, multi-user apps on infrastructure you control.\",\"base\":\"/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"nav\":[{\"text\":\"Product\",\"items\":[{\"text\":\"Sovereign\",\"link\":\"/\"},{\"text\":\"Sovereign OS\",\"link\":\"/sovereign-os/\"},{\"text\":\"Sovereign Edge\",\"link\":\"/sovereign-edge/\"}]},{\"text\":\"Instances\",\"link\":\"/instances\"},{\"text\":\"Docs\",\"items\":[{\"text\":\"Get Started\",\"link\":\"/get-started/\"},{\"text\":\"Full Documentation\",\"link\":\"/docs/\"}]},{\"text\":\"Roadmap\",\"link\":\"/product-roadmap\"},{\"text\":\"GitHub\",\"link\":\"https://github.com/sovereignfs/sovereign\"}],\"sidebar\":{\"/product/\":[{\"text\":\"Product\",\"items\":[{\"text\":\"What is Sovereign?\",\"link\":\"/product/\"},{\"text\":\"Why Sovereign?\",\"link\":\"/product/why-sovereign\"},{\"text\":\"How It Works\",\"link\":\"/product/how-it-works\"},{\"text\":\"Features\",\"link\":\"/product/features\"},{\"text\":\"Apps\",\"link\":\"/product/apps\"}]}],\"/get-started/\":[{\"text\":\"Get Started\",\"items\":[{\"text\":\"Choose a Path\",\"link\":\"/get-started/\"},{\"text\":\"Use Sovereign\",\"link\":\"/get-started/users\"},{\"text\":\"Host Sovereign\",\"link\":\"/get-started/operators\"},{\"text\":\"Build an App\",\"link\":\"/get-started/developers\"}]}],\"/docs/\":[{\"text\":\"Documentation\",\"items\":[{\"text\":\"Documentation Home\",\"link\":\"/docs/\"},{\"text\":\"Use Sovereign\",\"link\":\"/docs/users\"},{\"text\":\"Install as an App\",\"link\":\"/docs/pwa\"},{\"text\":\"Operate Sovereign\",\"link\":\"/docs/operators\"},{\"text\":\"Build Apps\",\"link\":\"/docs/developers\"},{\"text\":\"Architecture & Security\",\"link\":\"/docs/architecture\"},{\"text\":\"Contribute\",\"link\":\"/docs/contributing\"}]}],\"/rfcs/\":[{\"text\":\"RFCs\",\"items\":[{\"text\":\"RFC Index\",\"link\":\"/rfcs/README\"},{\"text\":\"RFC 0001 — Overlay shell variant\",\"link\":\"/rfcs/0001-overlay-shell-variant\"},{\"text\":\"RFC 0002 — Cross-plugin data sharing\",\"link\":\"/rfcs/0002-cross-plugin-data-sharing\"},{\"text\":\"RFC 0003 — Plugin monetization\",\"link\":\"/rfcs/0003-plugin-monetization\"},{\"text\":\"RFC 0004 — Per-plugin database\",\"link\":\"/rfcs/0004-per-plugin-database\"},{\"text\":\"RFC 0005 — Activity log\",\"link\":\"/rfcs/0005-activity-log\"},{\"text\":\"RFC 0006 — Deployment & upgrade strategy\",\"link\":\"/rfcs/0006-deployment-upgrade-strategy\"},{\"text\":\"RFC 0007 — User data export & portability\",\"link\":\"/rfcs/0007-user-data-portability\"},{\"text\":\"RFC 0008 — Security & encryption architecture\",\"link\":\"/rfcs/0008-security-encryption-architecture\"},{\"text\":\"RFC 0009 — Internal package codenames\",\"link\":\"/rfcs/0009-internal-package-codenames\"},{\"text\":\"RFC 0010 — Test file organization\",\"link\":\"/rfcs/0010-test-organization\"},{\"text\":\"RFC 0011 — Icon system (Lucide)\",\"link\":\"/rfcs/0011-icon-system\"},{\"text\":\"RFC 0012 — Passkeys & TOTP multi-factor auth\",\"link\":\"/rfcs/0012-passkeys-and-mfa\"},{\"text\":\"RFC 0013 — Mobile responsiveness & PWA hardening\",\"link\":\"/rfcs/0013-mobile-responsiveness-pwa\"},{\"text\":\"RFC 0014 — Minimal shell mode\",\"link\":\"/rfcs/0014-minimal-shell-mode\"},{\"text\":\"RFC 0015 — Notification Center\",\"link\":\"/rfcs/0015-notification-center\"},{\"text\":\"RFC 0016 — Web Push notifications\",\"link\":\"/rfcs/0016-web-push\"},{\"text\":\"RFC 0017 — Plugin starter template & example plugins\",\"link\":\"/rfcs/0017-plugin-starter-and-examples\"},{\"text\":\"RFC 0018 — Plugin-scoped environment variables\",\"link\":\"/rfcs/0018-plugin-scoped-env\"},{\"text\":\"RFC 0019 — Test setup & seeding\",\"link\":\"/rfcs/0019-test-setup-and-seeding\"},{\"text\":\"RFC 0020 — Production dev-mode & diagnostics\",\"link\":\"/rfcs/0020-production-dev-mode\"},{\"text\":\"RFC 0021 — Platform roles & capabilities\",\"link\":\"/rfcs/0021-platform-roles-and-capabilities\"},{\"text\":\"RFC 0022 — Plugin-declared capabilities\",\"link\":\"/rfcs/0022-plugin-capabilities\"},{\"text\":\"RFC 0023 — SDK distribution & the plugin isolation boundary\",\"link\":\"/rfcs/0023-sdk-distribution\"},{\"text\":\"RFC 0024 — Plugin compatibility & versioning\",\"link\":\"/rfcs/0024-plugin-compatibility\"},{\"text\":\"RFC 0025 — Accessibility (WCAG 2.1 AA)\",\"link\":\"/rfcs/0025-accessibility\"},{\"text\":\"RFC 0026 — Non-Docker production deployment\",\"link\":\"/rfcs/0026-non-docker-deployment\"},{\"text\":\"RFC 0027 — White-labeling (tenant branding)\",\"link\":\"/rfcs/0027-white-labeling\"},{\"text\":\"RFC 0028 — Operator Fork Model & Upstream Sync\",\"link\":\"/rfcs/0028-operator-fork-model\"},{\"text\":\"RFC 0029 — Internationalization / Localization (i18n)\",\"link\":\"/rfcs/0029-internationalization\"},{\"text\":\"RFC 0030 — Privacy-First Analytics\",\"link\":\"/rfcs/0030-privacy-first-analytics\"},{\"text\":\"RFC 0031 — Email Template System\",\"link\":\"/rfcs/0031-email-templates\"},{\"text\":\"RFC 0032 — Instance Identity Rename\",\"link\":\"/rfcs/0032-instance-identity-rename\"},{\"text\":\"RFC 0033 — User data deletion (Right to erasure)\",\"link\":\"/rfcs/0033-user-data-deletion\"},{\"text\":\"RFC 0034 — Notification Center — Pluggable transport (pub/sub)\",\"link\":\"/rfcs/0034-notification-transport\"},{\"text\":\"RFC 0035 — Progressive user verification\",\"link\":\"/rfcs/0035-progressive-user-verification\"},{\"text\":\"RFC 0036 — Per-plugin database dialect selection\",\"link\":\"/rfcs/0036-per-plugin-dialect\"},{\"text\":\"RFC 0037 — VitePress public docs site and project landing page\",\"link\":\"/rfcs/0037-vitepress-docs-site\"},{\"text\":\"RFC 0038 — Desktop app shell (Tauri, macOS-first)\",\"link\":\"/rfcs/0038-desktop-app-shell\"},{\"text\":\"RFC 0039 — Instance identity — instanceId field and terminology cleanup\",\"link\":\"/rfcs/0039-instance-id-and-terminology\"},{\"text\":\"RFC 0040 — Sovereign Harness — AI assistant and orchestration layer\",\"link\":\"/rfcs/0040-sovereign-harness\"},{\"text\":\"RFC 0041 — User directory and member selection SDK\",\"link\":\"/rfcs/0041-user-directory\"},{\"text\":\"RFC 0042 — Public plugin page routes\",\"link\":\"/rfcs/0042-public-plugin-routes\"},{\"text\":\"RFC 0043 — Plugin secret vault\",\"link\":\"/rfcs/0043-plugin-secret-vault\"},{\"text\":\"RFC 0044 — Plugin file storage\",\"link\":\"/rfcs/0044-plugin-storage\"},{\"text\":\"RFC 0045 — Plugin events and realtime channels\",\"link\":\"/rfcs/0045-plugin-events\"},{\"text\":\"RFC 0046 — Plugin background jobs and schedules\",\"link\":\"/rfcs/0046-plugin-jobs\"},{\"text\":\"RFC 0047 — Plugin tool contracts\",\"link\":\"/rfcs/0047-plugin-tools\"},{\"text\":\"RFC 0048 — Messages and notification detail\",\"link\":\"/rfcs/0048-messages-and-notification-detail\"},{\"text\":\"RFC 0049 — Plugin external connections\",\"link\":\"/rfcs/0049-plugin-external-connections\"},{\"text\":\"RFC 0050 — Public plugin webhooks\",\"link\":\"/rfcs/0050-public-plugin-webhooks\"},{\"text\":\"RFC 0051 — Cross-plugin references and dependency discovery\",\"link\":\"/rfcs/0051-cross-plugin-references\"},{\"text\":\"RFC 0052 — Plugin portability hooks\",\"link\":\"/rfcs/0052-plugin-portability-hooks\"},{\"text\":\"RFC 0053 — Plugin flow handoffs\",\"link\":\"/rfcs/0053-plugin-flow-handoffs\"},{\"text\":\"RFC 0054 — Plugin-scoped roles and grants\",\"link\":\"/rfcs/0054-plugin-scoped-roles-and-grants\"},{\"text\":\"RFC 0055 — Sovereign Council — multi-model deliberation workspace\",\"link\":\"/rfcs/0055-sovereign-council\"},{\"text\":\"RFC 0056 — Sovereign Guide — first-run guide platform plugin\",\"link\":\"/rfcs/0056-sovereign-guide\"},{\"text\":\"RFC 0057 — Plugin external dependency resolution — automatic runtime dep hoisting on plugin add/remove\",\"link\":\"/rfcs/0057-plugin-dep-hoisting\"},{\"text\":\"RFC 0058 — Native mobile app shell (Capacitor)\",\"link\":\"/rfcs/0058-native-mobile-app-shell\"},{\"text\":\"RFC 0059 — Local visual regression testing\",\"link\":\"/rfcs/0059-local-visual-regression-testing\"},{\"text\":\"RFC 0060 — Client-side encryption core\",\"link\":\"/rfcs/0060-client-side-encryption-core\"},{\"text\":\"RFC 0061 — Sovereign Wallet platform plugin\",\"link\":\"/rfcs/0061-sovereign-wallet\"},{\"text\":\"RFC 0062 — Email delivery coverage\",\"link\":\"/rfcs/0062-email-delivery-coverage\"},{\"text\":\"RFC 0063 — Core Assistant, Jarvis UI, and Local Inference Sidecar\",\"link\":\"/rfcs/0063-core-assistant-jarvis\"},{\"text\":\"RFC 0064 — Git-backed operator backups\",\"link\":\"/rfcs/0064-git-backed-operator-backups\"},{\"text\":\"RFC 0065 — User groups and plugin access policy\",\"link\":\"/rfcs/0065-user-groups-plugin-access\"},{\"text\":\"RFC 0066 — Sovereign Chat companion app, peer identity, and P2P transport\",\"link\":\"/rfcs/0066-sovereign-chat-p2p-identity\"},{\"text\":\"RFC 0067 — Product-led docs site and instance directory\",\"link\":\"/rfcs/0067-product-led-docs-site\"},{\"text\":\"RFC 0068 — Export completeness hardening\",\"link\":\"/rfcs/0068-export-completeness-hardening\"},{\"text\":\"RFC 0069 — Bring-your-own database (per-user external Postgres)\",\"link\":\"/rfcs/0069-bring-your-own-database\"},{\"text\":\"RFC 0070 — Per-user capability grants\",\"link\":\"/rfcs/0070-per-user-capability-grants\"},{\"text\":\"RFC 0071 — SQLite at-rest encryption (opt-in, single-key)\",\"link\":\"/rfcs/0071-sqlite-at-rest-encryption\"},{\"text\":\"RFC 0072 — External OAuth/OIDC provider for non-plugin apps\",\"link\":\"/rfcs/0072-external-oauth-provider\"},{\"text\":\"RFC 0073 — Standalone usage of `@sovereignfs/ui` outside the plugin runtime\",\"link\":\"/rfcs/0073-standalone-ui-package\"},{\"text\":\"RFC 0074 — Offline-capable plugin routes\",\"link\":\"/rfcs/0074-offline-capable-plugins\"},{\"text\":\"RFC 0075 — Per-plugin mobile header/footer toggle\",\"link\":\"/rfcs/0075-mobile-chrome-toggle\"},{\"text\":\"RFC 0076 — Design system sizing alignment and new primitive components\",\"link\":\"/rfcs/0076-ds-sizing-alignment-and-new-primitives\"},{\"text\":\"RFC 0077 — Instance-level corner radius control\",\"link\":\"/rfcs/0077-instance-radius-control\"},{\"text\":\"RFC 0078 — Generic offline read+write for plugins\",\"link\":\"/rfcs/0078-offline-plugin-writes\"},{\"text\":\"RFC 0079 — Mobile PWA layout, overlay, and gesture consistency\",\"link\":\"/rfcs/0079-mobile-pwa-layout-overlay-gesture-consistency\"},{\"text\":\"RFC 0080 — Plugin surface model (`sdk.device.*` and `x-sovereign-surface`)\",\"link\":\"/rfcs/0080-plugin-surface-model\"},{\"text\":\"RFC 0081 — Per-plugin installable PWA\",\"link\":\"/rfcs/0081-per-plugin-installable-pwa\"},{\"text\":\"RFC 0082 — Focused plugin app shell (single-plugin native apps)\",\"link\":\"/rfcs/0082-focused-plugin-app-shell\"},{\"text\":\"RFC 0083 — Device bridge and capability contract\",\"link\":\"/rfcs/0083-device-bridge-capability-contract\"}]}],\"/sovereign-os/product/\":[{\"text\":\"← Sovereign\",\"link\":\"/\"},{\"text\":\"Product\",\"items\":[{\"text\":\"Target User\",\"link\":\"/sovereign-os/product/target-user\"},{\"text\":\"Core Use Cases\",\"link\":\"/sovereign-os/product/core-use-cases\"},{\"text\":\"Preview Scope\",\"link\":\"/sovereign-os/product/preview-scope\"},{\"text\":\"Terminology\",\"link\":\"/sovereign-os/product/terminology\"}]}],\"/sovereign-os/rfcs/\":[{\"text\":\"← Sovereign\",\"link\":\"/\"},{\"text\":\"RFCs\",\"items\":[{\"text\":\"RFC Index\",\"link\":\"/sovereign-os/rfcs/README\"},{\"text\":\"RFC-0010: Raspberry Pi Image Deployment\",\"link\":\"/sovereign-os/rfcs/0010-raspberry-pi-image-deployment\"},{\"text\":\"RFC-0014: Appliance Update System\",\"link\":\"/sovereign-os/rfcs/0014-appliance-update-system\"},{\"text\":\"RFC-0015: Update Discovery — Channel Metadata and Device-Side Checking\",\"link\":\"/sovereign-os/rfcs/0015-update-discovery\"}]}],\"/sovereign-os/adrs/\":[{\"text\":\"← Sovereign\",\"link\":\"/\"},{\"text\":\"ADRs\",\"items\":[{\"text\":\"ADR Index\",\"link\":\"/sovereign-os/adrs/README\"},{\"text\":\"ADR-0001: Phase 01 Pi-hole Appliance Architecture\",\"link\":\"/sovereign-os/adrs/0001-phase-01-appliance-architecture\"},{\"text\":\"ADR-0002: Separate Installation Images from Update Artifacts\",\"link\":\"/sovereign-os/adrs/0002-install-images-and-update-artifacts\"},{\"text\":\"ADR-0003: Preview Bootstrap Access\",\"link\":\"/sovereign-os/adrs/0003-preview-bootstrap-access\"},{\"text\":\"ADR-0004: Provider-Neutral Assistant and Web Search\",\"link\":\"/sovereign-os/adrs/0004-provider-neutral-assistant-and-web-search\"},{\"text\":\"ADR-0005: Sovereign Console Namespace and Health Boundary\",\"link\":\"/sovereign-os/adrs/0005-sovereign-console-and-health-boundary\"},{\"text\":\"ADR-0006: Production Update Signing-Key Custody\",\"link\":\"/sovereign-os/adrs/0006-production-signing-key-custody\"},{\"text\":\"ADR-0007: Sovereign Console Authentication\",\"link\":\"/sovereign-os/adrs/0007-console-authentication\"},{\"text\":\"ADR-0008: Console Privileged Action Invocation\",\"link\":\"/sovereign-os/adrs/0008-console-privileged-action-invocation\"},{\"text\":\"ADR-0009: Console-Triggered Update Install\",\"link\":\"/sovereign-os/adrs/0009-console-triggered-install\"}]}],\"/sovereign-os/\":[{\"text\":\"← Sovereign\",\"link\":\"/\"},{\"text\":\"Sovereign OS\",\"items\":[{\"text\":\"Concept\",\"link\":\"/sovereign-os/concept\"},{\"text\":\"Product\",\"link\":\"/sovereign-os/product/target-user\"},{\"text\":\"Roadmap\",\"link\":\"/sovereign-os/roadmap\"},{\"text\":\"RFCs\",\"link\":\"/sovereign-os/rfcs/README\"},{\"text\":\"ADRs\",\"link\":\"/sovereign-os/adrs/README\"}]}],\"/sovereign-edge/research/\":[{\"text\":\"← Sovereign\",\"link\":\"/\"},{\"text\":\"Research\",\"items\":[{\"text\":\"Research Index\",\"link\":\"/sovereign-edge/research/README\"},{\"text\":\"Research 0001 — Sovereign Edge: concept, positioning, and connector architecture\",\"link\":\"/sovereign-edge/research/0001-concept-and-connector-architecture\"},{\"text\":\"Research 0002 — React Native framework choice: Expo vs. Community CLI\",\"link\":\"/sovereign-edge/research/0002-react-native-framework-choice\"},{\"text\":\"Research 0003 — Model download verification: hashing strategy\",\"link\":\"/sovereign-edge/research/0003-model-verification-hashing\"}]}],\"/sovereign-edge/epics/\":[{\"text\":\"← Sovereign\",\"link\":\"/\"},{\"text\":\"Epics\",\"items\":[{\"text\":\"Epics Overview\",\"link\":\"/sovereign-edge/epics/README\"},{\"text\":\"0 — Infrastructure\",\"link\":\"/sovereign-edge/epics/infrastructure\"},{\"text\":\"1 — Core Inference & Chat\",\"link\":\"/sovereign-edge/epics/core-inference-chat\"},{\"text\":\"2 — Connector Framework\",\"link\":\"/sovereign-edge/epics/connector-framework\"},{\"text\":\"3 — Search Connector\",\"link\":\"/sovereign-edge/epics/search-connector\"},{\"text\":\"4 — Sovereign Tasks Connector\",\"link\":\"/sovereign-edge/epics/sovereign-tasks-connector\"},{\"text\":\"5 — Connector Store & SDK\",\"link\":\"/sovereign-edge/epics/connector-store-sdk\"},{\"text\":\"6 — Monetization\",\"link\":\"/sovereign-edge/epics/monetization\"},{\"text\":\"7 — Design System & Branding\",\"link\":\"/sovereign-edge/epics/design-system\"},{\"text\":\"8 — Mobile App Shell\",\"link\":\"/sovereign-edge/epics/mobile-app-shell\"},{\"text\":\"9 — Desktop App\",\"link\":\"/sovereign-edge/epics/desktop-app\"}]}],\"/sovereign-edge/\":[{\"text\":\"← Sovereign\",\"link\":\"/\"},{\"text\":\"Sovereign Edge\",\"items\":[{\"text\":\"Concept\",\"link\":\"/sovereign-edge/concept\"},{\"text\":\"Roadmap\",\"link\":\"/sovereign-edge/roadmap\"},{\"text\":\"Development Workflow\",\"link\":\"/sovereign-edge/development-workflow\"},{\"text\":\"Research\",\"link\":\"/sovereign-edge/research/README\"},{\"text\":\"Epics\",\"link\":\"/sovereign-edge/epics/README\"}]}],\"/\":[{\"text\":\"Operator Guides\",\"items\":[{\"text\":\"Self-Hosting\",\"link\":\"/self-hosting\"},{\"text\":\"Upgrade Guide\",\"link\":\"/upgrade\"},{\"text\":\"Troubleshooting\",\"link\":\"/troubleshooting\"}]},{\"text\":\"App Developer Guides\",\"items\":[{\"text\":\"Overview\",\"link\":\"/plugin-development\"},{\"text\":\"SDK Stability\",\"link\":\"/sdk-stability\"},{\"text\":\"Plugin Database\",\"link\":\"/plugin-database\"},{\"text\":\"Design System\",\"link\":\"/design-system\"}]},{\"text\":\"Architecture & Security\",\"items\":[{\"text\":\"Architecture\",\"link\":\"/architecture\"},{\"text\":\"Security\",\"link\":\"/security\"},{\"text\":\"Repository Map\",\"link\":\"/repositories\"}]},{\"text\":\"Core Plugins\",\"items\":[{\"text\":\"Console\",\"link\":\"/plugins/console\"},{\"text\":\"Launcher\",\"link\":\"/plugins/launcher\"},{\"text\":\"Account\",\"link\":\"/plugins/account\"}]},{\"text\":\"Contributor Guides\",\"items\":[{\"text\":\"Documentation Structure\",\"link\":\"/documentation-structure\"},{\"text\":\"Development Workflow\",\"link\":\"/development-workflow\"},{\"text\":\"Agent-First Documentation\",\"link\":\"/agent-first-documentation\"},{\"text\":\"Architecture Rules\",\"link\":\"/architecture-rules\"},{\"text\":\"Testing E2E\",\"link\":\"/testing-e2e\"},{\"text\":\"PWA Device Testing\",\"link\":\"/pwa-real-device-testing\"}]},{\"text\":\"RFCs\",\"collapsed\":true,\"items\":[{\"text\":\"RFC Index\",\"link\":\"/rfcs/README\"}]}]},\"search\":{\"provider\":\"local\"},\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://github.com/sovereignfs/sovereign\"}],\"footer\":{\"message\":\"Open source under AGPL-3.0. Each Sovereign instance is independently operated.\",\"copyright\":\"Sovereign\"}},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":false}");</script>
</body>
</html>