diff --git a/scripts/build-site.mjs b/scripts/build-site.mjs index fc6e948b..324aa40b 100755 --- a/scripts/build-site.mjs +++ b/scripts/build-site.mjs @@ -285,13 +285,14 @@ pages.push({ file: "pricing/index.html", path: "/pricing/", title: "Pricing · O ``).join("")}
${ic("i-users")}Teams ${planned}${TEAMS_PRICE}Planned prices in US dollars. They may change before launch.
` }); +const PLANNED = 'Planned'; const SEC_ROWS = [ - ["Who holds the keys", "Your trusted devices, and a copy in Orbyn’s key service, kept in hardware security modules", "Only your trusted devices"], - ["Can Orbyn read your data?", "Technically yes, for account recovery and server features such as reminder email. Staff access needs approval and is logged.", "No"], - ["You lose every device", "Recover with your email, a trusted phone number and a waiting period", "Your recovery key or a recovery contact. Without them, the data is lost."], + ["Who holds the keys", `Your trusted devices. A recovery copy in Orbyn’s key service, kept in hardware security modules, is ${PLANNED}`, "Only your trusted devices"], + ["Can Orbyn read your data?", `Not today: the key service is not built, so Orbyn holds no copy of your keys. When Standard’s recovery copy ships, Orbyn will technically be able to read your data, for account recovery and server features such as reminder email, and staff access will need approval and be logged. ${PLANNED}`, 'No1'], + ["You lose every device", `Recover with your email, a trusted phone number and a waiting period. Account recovery is ${PLANNED}`, "Your recovery key or a recovery contact. Without them, the data is lost."], ["Adding a device", "Sign in, then approve with a code on a trusted device", "The same. The keys come from a trusted device, your recovery key or a recovery contact."], ["On the web", "Works after sign-in", "Off by default. Each sign-in is approved on a trusted device and lasts one hour."], - ["Reminders", "On the device, plus push and email from the server", "On the device. The push says only when; the phone decrypts the text."], + ["Reminders", `On the device today. Server push and email reminders are ${PLANNED}`, `On the device. Phone push, which says only when, is ${PLANNED}`], ["Search", "On the device", "On the device"], ["Shared lists and projects", "Standard", "End-to-end when everyone sharing uses Advanced"], ["Calendars other apps use", "Standard", "Standard, so calendar apps and invitations keep working"], @@ -308,7 +309,8 @@ pages.push({ file: "security/index.html", path: "/security/", title: "Security
  1. Saved on the deviceA new task is saved in the device’s own database at once, so it works with no signal.
  2. Encrypted before it leavesThe device encrypts the record with its own key before uploading it.
  3. Stored as ciphertextThe server keeps a new encrypted version and tells your other devices something changed, without saying what.
  4. Decrypted on your devicesEach device fetches the change and decrypts it. If two devices edited the same thing, they merge field by field.

Standard or Advanced protection

Every account has one of two levels. Sync and the apps work the same in both; what changes is who can hold the keys. Advanced will be in every paid plan.

QuestionStandard (default)Advanced
-${SEC_ROWS.map(([k, s, a]) => `
${k}${s}${a}
`).join("\n")}
+${SEC_ROWS.map(([k, s, a]) => `
${k}${s}${a}
`).join("\n")} +

1 Switching from Standard to Advanced deletes Orbyn’s copy of your keys at once. Server backups made before the switch may keep a copy until the keys are rotated, which is Planned. An account that starts on Advanced never had a server copy.

What it looks like in your account

Your protection level lives in your Orbyn account, and you can change it there. Early designs; they may change.Early design; it may change.

${fig("account-protection", b("Protection", "Protection level: Standard or Advanced, and what each app encrypts."))}${fig("account-advanced-flow", b("Advanced, step 2 of 3", "Turning on Advanced: save your recovery key first."))}
${fig("account-protection", b("Protection", "Protection level: Standard or Advanced."))}
diff --git a/site/src/styles.css b/site/src/styles.css index 101d7c0c..740023e9 100644 --- a/site/src/styles.css +++ b/site/src/styles.css @@ -242,6 +242,10 @@ html.th-anim,html.th-anim *,html.th-anim *::before,html.th-anim *::after{transit .copyerr{margin:0;font-size:12.5px} .link{color:var(--t1);text-decoration:underline;text-decoration-color:var(--line2);text-underline-offset:3px} .link:focus-visible{outline:0;box-shadow:0 0 0 2px var(--main),0 0 0 4px var(--t1);border-radius:4px} +.sec-limit{margin:10px 0 0;font-size:12.5px;line-height:1.6;color:var(--t2);max-width:68ch;background:var(--main);border-radius:12px;padding:10px 14px} +.sec-limit sup{color:var(--t3)} +.sec-row sup a{color:var(--t3);text-decoration:none} +.sec-row sup a:focus-visible{outline:0;box-shadow:0 0 0 2px var(--main),0 0 0 4px var(--t1);border-radius:4px} .sec-sees{margin:0;padding:0;list-style:none;display:flex;flex-wrap:wrap;gap:8px} .sec-sees li{display:inline-flex;gap:7px;align-items:flex-start;min-height:30px;padding:6px 12px;border-radius:16px;background:var(--main);color:var(--t1);font-size:12.5px;line-height:1.4;max-width:100%} .sec-sees li .ic{margin-top:2px}