[{"data":1,"prerenderedAt":569},["ShallowReactive",2],{"navigation_docs":3,"-licensing-how-licensing-works":136,"-licensing-how-licensing-works-surround":564},[4,26,47,68,89,110,123],{"title":5,"path":6,"stem":7,"children":8,"page":25},"Getting Started","\u002Fgetting-started","1.getting-started",[9,13,17,21],{"title":10,"path":11,"stem":12},"What you are running","\u002Fgetting-started\u002Fwhat-you-are-running","1.getting-started\u002F1.what-you-are-running",{"title":14,"path":15,"stem":16},"Architecture","\u002Fgetting-started\u002Farchitecture","1.getting-started\u002F2.architecture",{"title":18,"path":19,"stem":20},"Prerequisites","\u002Fgetting-started\u002Fprerequisites","1.getting-started\u002F3.prerequisites",{"title":22,"path":23,"stem":24},"Quickstart","\u002Fgetting-started\u002Fquickstart","1.getting-started\u002F4.quickstart",false,{"title":27,"path":28,"stem":29,"children":30,"page":25},"Install","\u002Finstall","2.install",[31,35,39,43],{"title":32,"path":33,"stem":34},"Install the chart","\u002Finstall\u002Finstall-the-chart","2.install\u002F1.install-the-chart",{"title":36,"path":37,"stem":38},"Activation","\u002Finstall\u002Factivation","2.install\u002F2.activation",{"title":40,"path":41,"stem":42},"DNS and TLS","\u002Finstall\u002Fdns-and-tls","2.install\u002F3.dns-and-tls",{"title":44,"path":45,"stem":46},"Verify your install","\u002Finstall\u002Fverify-your-install","2.install\u002F4.verify-your-install",{"title":48,"path":49,"stem":50,"children":51,"page":25},"Configure","\u002Fconfigure","3.configure",[52,56,60,64],{"title":53,"path":54,"stem":55},"Data services","\u002Fconfigure\u002Fdata-services","3.configure\u002F1.data-services",{"title":57,"path":58,"stem":59},"Secrets","\u002Fconfigure\u002Fsecrets","3.configure\u002F2.secrets",{"title":61,"path":62,"stem":63},"Registry and air-gapped installs","\u002Fconfigure\u002Fregistry-and-airgap","3.configure\u002F3.registry-and-airgap",{"title":65,"path":66,"stem":67},"Integrations","\u002Fconfigure\u002Fintegrations","3.configure\u002F4.integrations",{"title":69,"path":70,"stem":71,"children":72,"page":25},"Licensing","\u002Flicensing","4.licensing",[73,77,81,85],{"title":74,"path":75,"stem":76},"How licensing works","\u002Flicensing\u002Fhow-licensing-works","4.licensing\u002F1.how-licensing-works",{"title":78,"path":79,"stem":80},"Your key never leaves","\u002Flicensing\u002Fyour-key-never-leaves","4.licensing\u002F2.your-key-never-leaves",{"title":82,"path":83,"stem":84},"What phones home","\u002Flicensing\u002Fwhat-phones-home","4.licensing\u002F3.what-phones-home",{"title":86,"path":87,"stem":88},"Revoke and recover","\u002Flicensing\u002Frevoke-and-recover","4.licensing\u002F4.revoke-and-recover",{"title":90,"path":91,"stem":92,"children":93,"page":25},"Operate","\u002Foperate","5.operate",[94,98,102,106],{"title":95,"path":96,"stem":97},"Upgrade","\u002Foperate\u002Fupgrade","5.operate\u002F1.upgrade",{"title":99,"path":100,"stem":101},"Backup and restore","\u002Foperate\u002Fbackup-and-restore","5.operate\u002F2.backup-and-restore",{"title":103,"path":104,"stem":105},"Observability","\u002Foperate\u002Fobservability","5.operate\u002F3.observability",{"title":107,"path":108,"stem":109},"High availability","\u002Foperate\u002Fhigh-availability","5.operate\u002F4.high-availability",{"title":111,"path":112,"stem":113,"children":114,"page":25},"Troubleshooting","\u002Ftroubleshooting","6.troubleshooting",[115,119],{"title":116,"path":117,"stem":118},"Install failures","\u002Ftroubleshooting\u002Finstall-failures","6.troubleshooting\u002F1.install-failures",{"title":120,"path":121,"stem":122},"Licensing failures","\u002Ftroubleshooting\u002Flicensing-failures","6.troubleshooting\u002F2.licensing-failures",{"title":124,"path":125,"stem":126,"children":127,"page":25},"Reference","\u002Freference","9.reference",[128,132],{"title":129,"path":130,"stem":131},"Helm values","\u002Freference\u002Fhelm-values","9.reference\u002F1.helm-values",{"title":133,"path":134,"stem":135},"Environment variables","\u002Freference\u002Fenvironment","9.reference\u002F2.environment",{"id":137,"title":74,"body":138,"description":557,"extension":558,"links":559,"meta":560,"navigation":561,"path":75,"seo":562,"stem":76,"__hash__":563},"docs\u002F4.licensing\u002F1.how-licensing-works.md",{"type":139,"value":140,"toc":548},"minimark",[141,145,149,152,157,160,235,249,256,260,267,283,293,296,380,390,400,404,411,418,425,428,432,435,438,454,458,461,464,473,477,480,511,518,522,544],[142,143,74],"h1",{"id":144},"how-licensing-works",[146,147,148],"p",{},"Your deployment runs under a license issued by the Solvegio Hub. The license is a signed token that lives in a Kubernetes Secret in your namespace. A small Deployment called the license agent obtains it, keeps it fresh, and writes every successor back into that Secret.",[146,150,151],{},"Everything below happens inside your cluster, driven by outbound HTTPS calls. Nothing is pushed to you.",[153,154,156],"h2",{"id":155},"you-get-a-code","You get a code",[146,158,159],{},"We mint a one-time activation code for your deployment. You pass it to the chart:",[161,162,167],"pre",{"className":163,"code":164,"language":165,"meta":166,"style":166},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","helm install my-mvno solvegio\u002Fplatform \\\n  --set platform.kind=mvno \\\n  --set platform.host=platform.example.com \\\n  --set activation.code=\u003Ccode-from-the-hub-console>\n","bash","",[168,169,170,193,204,214],"code",{"__ignoreMap":166},[171,172,175,179,183,186,189],"span",{"class":173,"line":174},"line",1,[171,176,178],{"class":177},"sBMFI","helm",[171,180,182],{"class":181},"sfazB"," install",[171,184,185],{"class":181}," my-mvno",[171,187,188],{"class":181}," solvegio\u002Fplatform",[171,190,192],{"class":191},"sTEyZ"," \\\n",[171,194,196,199,202],{"class":173,"line":195},2,[171,197,198],{"class":181},"  --set",[171,200,201],{"class":181}," platform.kind=mvno",[171,203,192],{"class":191},[171,205,207,209,212],{"class":173,"line":206},3,[171,208,198],{"class":181},[171,210,211],{"class":181}," platform.host=platform.example.com",[171,213,192],{"class":191},[171,215,217,219,222,226,229,232],{"class":173,"line":216},4,[171,218,198],{"class":181},[171,220,221],{"class":181}," activation.code=",[171,223,225],{"class":224},"sMK4o","\u003C",[171,227,228],{"class":181},"code-from-the-hub-consol",[171,230,231],{"class":191},"e",[171,233,234],{"class":224},">\n",[146,236,237,240,241,244,245,248],{},[168,238,239],{},"activation.code"," is the one licensing value you set. The chart writes it into the platform Secret (",[168,242,243],{},"\u003Crelease>-platform-env",") under ",[168,246,247],{},"ACTIVATION_CODE",".",[146,250,251,252,255],{},"The code is single-use. It also carries a fingerprint of the Hub's own signing key, packed into the code string. The agent checks that fingerprint against the key set published by ",[168,253,254],{},"activation.parentUrl"," before it enrolls, so a code minted for you cannot be redeemed against an impostor Hub.",[153,257,259],{"id":258},"the-agent-generates-a-key-and-enrolls","The agent generates a key and enrolls",[146,261,262,263,266],{},"The license agent (",[168,264,265],{},"\u003Crelease>-platform-license-agent",") starts alongside the API. On its first pass it finds no license in the Secret, so it enrolls.",[146,268,269,270,274,275,278,279,282],{},"It generates a 32-byte Ed25519 seed with the cluster's own randomness, derives a keypair from it, and posts the activation code plus the ",[271,272,273],"strong",{},"public"," half of that key to ",[168,276,277],{},"POST \u002Fv1\u002Fdeployments\u002Factivate"," on the Hub. The private half stays in your namespace. See ",[280,281,78],"a",{"href":79}," for what that guarantee rests on.",[146,284,285,286,289,290,292],{},"The Hub redeems the code and mints a license bound to the key you presented. Binding means the license carries a ",[168,287,288],{},"cnf"," claim holding the thumbprint of your public key. A license with a ",[168,291,288],{}," is worth nothing to anyone who does not hold the matching private key, because every later call has to prove possession of it.",[146,294,295],{},"The agent then writes the result back into the platform Secret. Six keys, and this is the complete set the agent ever owns:",[297,298,299,312],"table",{},[300,301,302],"thead",{},[303,304,305,309],"tr",{},[306,307,308],"th",{},"Secret key",[306,310,311],{},"What it holds",[313,314,315,326,336,346,356,370],"tbody",{},[303,316,317,323],{},[318,319,320],"td",{},[168,321,322],{},"PARENT_LEASE_TOKEN",[318,324,325],{},"The license itself",[303,327,328,333],{},[318,329,330],{},[168,331,332],{},"SIGNING_SEED",[318,334,335],{},"The seed the enrollment key was derived from",[303,337,338,343],{},[318,339,340],{},[168,341,342],{},"POP_SIGNING_SEED",[318,344,345],{},"The seed of the key the current license is bound to",[303,347,348,353],{},[318,349,350],{},[168,351,352],{},"PARENT_BASE_URL",[318,354,355],{},"The Hub the deployment is pinned to",[303,357,358,363],{},[318,359,360],{},[168,361,362],{},"REQUIRE_PARENT_LEASE",[318,364,365,366,369],{},"Set to ",[168,367,368],{},"true",", which is what makes the API fail closed",[303,371,372,377],{},[318,373,374],{},[168,375,376],{},"ACTIVATION_CODE_CONSUMED",[318,378,379],{},"The code that was spent, so the same one is never replayed",[146,381,382,383,386,387,389],{},"A revoked deployment carries a seventh, ",[168,384,385],{},"LEASE_STATUS",", which the agent sets and then clears again on recovery. See ",[280,388,86],{"href":87},". Every other key in that Secret comes from the chart or from you.",[146,391,392,393,396,397,399],{},"The API Deployment has been sitting behind a ",[168,394,395],{},"wait-for-lease"," initContainer this whole time. ",[168,398,322],{}," landing in the Secret is what releases it. An unlicensed deployment never serves a request.",[153,401,403],{"id":402},"from-then-on-it-renews","From then on, it renews",[146,405,406,407,410],{},"The license has a finite term. The Hub sets it (two weeks, by default) and stamps it into the token's ",[168,408,409],{},"exp"," claim, so you can always read your own expiry out of the token you hold.",[146,412,413,414,417],{},"The agent renews well before that. It calls ",[168,415,416],{},"POST \u002Fv1\u002Flicenses\u002F{jti}\u002Frenew",", signing the request with the key the current license is bound to. That signature is the proof of possession: only the holder of the private key can produce it.",[146,419,420,421,424],{},"Every renewal also rotates the key. Before it calls, the agent generates a ",[271,422,423],{},"new"," keypair and puts that new key's thumbprint in the request body. The Hub verifies the proof made with the old key, mints a successor license bound to the new one, and returns it. So each renewal is two things at once: an extension of the term, and a handover to a key that has never been used before.",[146,426,427],{},"The agent then persists both halves of the result, the successor license and the seed of the key it is bound to, in a single patch to the Secret.",[153,429,431],{"id":430},"why-the-write-back-is-the-whole-point","Why the write-back is the whole point",[146,433,434],{},"This is the part that matters operationally.",[146,436,437],{},"The lease in your Secret is always the most recent one the agent obtained, not the one you installed with. A pod that restarts eight months after install reads whatever the agent last wrote. It finds a current license, bound to a current key, and it boots and serves.",[146,439,440,441,443,444,446,447,443,450,453],{},"The API does not even need the restart. It mounts ",[168,442,322],{}," and ",[168,445,342],{}," from the Secret at ",[168,448,449],{},"\u002Fetc\u002Fplatform\u002Flease",[168,451,452],{},"\u002Fetc\u002Fplatform\u002Fpop_seed"," and watches those files, so a rotation the agent performs at 3am is picked up in place, with no rollout and no dropped requests.",[153,455,457],{"id":456},"grace-and-what-happens-when-the-hub-is-unreachable","Grace, and what happens when the Hub is unreachable",[146,459,460],{},"Renewal fires early in the license term, leaving most of the term unused. That gap is deliberate: it is the grace window.",[146,462,463],{},"If the Hub is briefly unreachable, the renew attempt fails, the agent retries with exponential backoff, and your deployment keeps serving the whole time on the license it already holds. The failure is not a licensing event, it is a network event, and it costs you nothing until the license you hold actually expires. The window is wide enough to absorb an outage on either side without an operator noticing.",[146,465,466,467,470,471,248],{},"The agent publishes ",[168,468,469],{},"license_expiry_seconds"," on its metrics port, which is the number to alert on if you want warning. See ",[280,472,103],{"href":104},[153,474,476],{"id":475},"fail-closed","Fail closed",[146,478,479],{},"If there is no valid license, the deployment does not serve business traffic.",[481,482,483,490,505],"ul",{},[484,485,486,487,489],"li",{},"No license in the Secret at boot: the ",[168,488,395],{}," initContainer never completes, and the API pod never starts.",[484,491,492,493,496,497,500,501,504],{},"License present but expired, or cleared because the Hub revoked it: every gated business route answers ",[168,494,495],{},"424 Failed Dependency",". The body says ",[168,498,499],{},"parent lease not loaded"," or ",[168,502,503],{},"parent lease revoked"," depending on which it is.",[484,506,507,510],{},[168,508,509],{},"\u002Fhealth"," keeps answering, in every one of those states. The process does not crash and Kubernetes does not restart-loop it. A deployment without a license is quiet, not broken, and your data is untouched.",[146,512,513,514,517],{},"Requests that fail authentication still get their usual ",[168,515,516],{},"401"," first. The license gate sits behind auth, not in front of it.",[153,519,521],{"id":520},"where-to-go-next","Where to go next",[481,523,524,529,534,539],{},[484,525,526,528],{},[280,527,78],{"href":79},": the trust guarantees and the agent's exact Kubernetes permissions.",[484,530,531,533],{},[280,532,82],{"href":83},": the exact fields that leave your cluster.",[484,535,536,538],{},[280,537,86],{"href":87},": what a revocation does, and the one command that undoes it.",[484,540,541,543],{},[280,542,120],{"href":121},": when the agent will not enroll.",[545,546,547],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}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);}",{"title":166,"searchDepth":174,"depth":195,"links":549},[550,551,552,553,554,555,556],{"id":155,"depth":195,"text":156},{"id":258,"depth":195,"text":259},{"id":402,"depth":195,"text":403},{"id":430,"depth":195,"text":431},{"id":456,"depth":195,"text":457},{"id":475,"depth":195,"text":476},{"id":520,"depth":195,"text":521},"The full lifecycle of your license, from the activation code you paste into helm install to the renewals that keep your deployment serving.","md",null,{},true,{"title":74,"description":557},"lvS_Tnc-s8AksAqfA2Pjxe6fDV_RoNBMwdzywGm3e1c",[565,567],{"title":65,"path":66,"stem":67,"description":566,"children":-1},"The optional pieces: outbound email, object storage, error reporting and the AI translation keys.",{"title":78,"path":79,"stem":80,"description":568,"children":-1},"The signing key is generated in your cluster and never transmitted, and the license agent can touch exactly two objects in your namespace.",1783967741116]