Docs sweep: align install / integrate / operate / pricing / wire-format
Five-page sweep to match the current daemon state. install.html: - Step 6 (first product): "Price (sats)" → reflects the currency picker (sats / USD / EUR) shipped in migration 0010. - Step 7 (first policy): drop the "default slug is consumed by public flow" myth — buy page renders a tier picker for any product with ≥2 public policies. Add references to entitlements catalog, hide-on-buy toggles, marketing bullets, recurring subscriptions, and the drag-to-reorder policy grid. integrate.html: - "Three official SDKs" → "Four official SDKs" + Go tab + install snippet. Notes the daemon's cross-check fixtures assert byte-for-byte parity across all four. - Admin API table: drop "by npub" from the licenses search description (backend supports it; UI hasn't surfaced it yet since the purchase flow doesn't capture npubs). operate.html: - Backups section: drop the imaginary `/data/issuer-key.pem` file — the signing keypair lives in the `server_keys` SQLite table, not in a PEM file on disk. Mention the self-license file path (`/data/keysat-license.txt`). - Rotation: drop the "v0.1 doesn't support / v0.2 will" framing; rotation isn't on the v0.2 / v0.3 roadmap and the v0.1 caveat is misleading. Update steps to reflect SQLite-as-keystore. - Webhook troubleshooting: point at the dedicated Webhooks → Failed (DLQ) view rather than the audit log. pricing.html: - Creator: 21,000 sats one-time → Free forever (matches actual master Keysat configuration). - Pro: 250,000 sats/yr → 100,000 sats/yr (recurring). Note recurring + tier upgrades have shipped; only Zaprite remains v0.3. - Patron: 500,000 sats/yr → 250,000 sats one-time perpetual. Differentiation rewritten: perpetual license + direct 1:1 support (not just "Pro with a badge"). - Active discount-code cap: 5 → 10 (real cap). - New "Prices shown are a snapshot" note pointing at the canonical live source (keysat.xyz#tiers + the buy page). - Updated unlicensed-caps line to show 5/5/10 with units. wire-format.html: - Replace the entirely-fabricated "KS-base32-blob with KSAT magic bytes" layout with the actual LIC1 envelope: `LIC1-<base32 payload>-<base32 signature>` split on dashes. - Document BOTH payload versions: v1 (legacy 74-byte fixed) and v2 (current default, 83-byte head + variable entitlements table). Field offsets, flag bits, signature scope all match the daemon source. - Drop the bogus Crockford-base32 + dash-grouping sections — the daemon uses RFC 4648 base32 with single-dash structure separators, not grouped-dashes for readability. - Drop the fabricated hex-dump worked example. - Porting section now points at `licensing-service/tests/crosscheck/` (the actual fixtures location) instead of a Python-SDK path. - Versioning policy: clarify envelope-tag vs payload-version cadence.
This commit is contained in:
+8
-8
@@ -55,9 +55,9 @@
|
||||
<p>The Keysat backup payload is intentionally tiny. It contains:</p>
|
||||
|
||||
<ul>
|
||||
<li>The signing keypair (<code>/data/issuer-key.pem</code>).</li>
|
||||
<li>The SQLite database (<code>/data/keysat.db</code>).</li>
|
||||
<li>The SQLite database (<code>/data/keysat.db</code>), which holds the Ed25519 signing keypair in the <code>server_keys</code> table along with all products, policies, licenses, invoices, audit log, webhook subscribers, and operator settings.</li>
|
||||
<li>Migration history.</li>
|
||||
<li>The self-license file at <code>/data/keysat-license.txt</code>, if you've activated a paid Keysat tier.</li>
|
||||
</ul>
|
||||
|
||||
<p>That’s it. No log files (those rotate locally), no caches.</p>
|
||||
@@ -83,19 +83,19 @@
|
||||
<p>The signing keypair restores along with the database, so all previously-issued licenses verify identically against the same public key. You don’t need to re-distribute the public key to your customers.</p>
|
||||
|
||||
<h2 id="signing-key">Rotating the signing key</h2>
|
||||
<p>You generally don’t want to rotate the signing key — doing so invalidates every license you’ve ever issued. v0.1 doesn’t support rotation; the key is generated once at first start and never changed.</p>
|
||||
<p>You generally don’t want to rotate the signing key — doing so invalidates every license you’ve ever issued. There is no admin-UI affordance for rotation today; the key is generated once on first start (and persisted to the <code>server_keys</code> SQLite table) and stays there for the life of the instance.</p>
|
||||
|
||||
<p>If you absolutely need to rotate (e.g. you suspect the keypair has leaked off the box):</p>
|
||||
|
||||
<ol>
|
||||
<li>Stop Keysat.</li>
|
||||
<li>Move <code>/data/issuer-key.pem</code> aside.</li>
|
||||
<li>Drop the row in the <code>server_keys</code> table (or move the database aside entirely if you also want to start clean).</li>
|
||||
<li>Restart Keysat — it will generate a fresh keypair on first run.</li>
|
||||
<li>Re-issue all active licenses to existing customers using the new key. The admin UI doesn’t support bulk re-issuance yet; this is a manual SQL exercise.</li>
|
||||
<li>Push a software update that swaps the embedded public key.</li>
|
||||
<li>Re-issue all active licenses to existing customers using the new key. The admin UI doesn’t support bulk re-issuance yet; this is a manual SQL + scripted-API exercise.</li>
|
||||
<li>Push a software update that swaps the embedded public key in your downstream apps.</li>
|
||||
</ol>
|
||||
|
||||
<p>The cleaner path, for v0.2 onward, will be to support a rolling rotation where both keys verify for a transition period.</p>
|
||||
<p>A future release may support rolling rotation (two keys verifying during a transition window). It's not on the v0.2 / v0.3 roadmap.</p>
|
||||
|
||||
<h2 id="troubleshooting">Troubleshooting</h2>
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
<p>BTCPay rejects the invoice request because the store has no configured wallet. Open BTCPay, find your store, and configure either an on-chain wallet or a Lightning node before retrying.</p>
|
||||
|
||||
<h3 id="t-webhook">Webhook deliveries failing</h3>
|
||||
<p>Check the audit log in the admin UI — failed deliveries land there with the response status. Common causes:</p>
|
||||
<p>In the admin UI go to <strong>Webhooks</strong> — failed deliveries past the 10-attempt retry budget land in the "Failed" filter (the DLQ), with the response status and an inline "Retry" button. The audit log is a secondary source. Common causes:</p>
|
||||
<ul>
|
||||
<li>Endpoint URL no longer reachable. Hit it manually with <code>curl</code> from your laptop to confirm.</li>
|
||||
<li>Endpoint rejecting on signature mismatch. Verify your endpoint is HMAC-validating against the secret you registered with.</li>
|
||||
|
||||
Reference in New Issue
Block a user