| 1 | package domains |
| 2 | |
| 3 | // reservedSqids are the labels no account may ever be given as its sqid |
| 4 | // (#285, Paul's ruling 2026-10-14). |
| 5 | // |
| 6 | // Why: an account's apps live at <app>.<sqid>.<apps-domain>, and the |
| 7 | // deployment's own infrastructure also hangs labels directly under the apps |
| 8 | // domain. When the two meet, DNS answers for the infrastructure, not the |
| 9 | // account. On 2026-10-13 flagship gained `*.dev.oncarlos.com` pointing at the |
| 10 | // dev deployment's box, and Sqid(1168) is "dev": every app of account 1168 |
| 11 | // would have resolved to dev's edge, and dev's edge would have tried to |
| 12 | // issue certificates for them. |
| 13 | // |
| 14 | // The alphabet and the offset stay frozen. Instead, NextAccountID steps over |
| 15 | // any id whose sqid is listed here, so the id is simply never handed out. |
| 16 | // Existing accounts are untouched: console.MaterializeAccounts logs any live |
| 17 | // account that holds a listed sqid, so adding a label that some account |
| 18 | // already has shows up on the next console start rather than silently. |
| 19 | // |
| 20 | // Only list labels that Sqid can actually produce. TestReservedSqidsAreProducible |
| 21 | // fails on any other entry, so dead entries cannot creep in. A label cannot |
| 22 | // be produced when it: |
| 23 | // - contains i, l or o (not in the frozen alphabet): relay, platform, |
| 24 | // console, mail, tunnel, static; |
| 25 | // - has fewer than 3 letters (sqidOffset's floor): us, uk, au, eu; |
| 26 | // - starts with "a" (base 23 has no leading zero digit): acme, app, api, |
| 27 | // admin, assets, auth; |
| 28 | // - contains anything but lowercase letters: eu-west-1, _acme-challenge. |
| 29 | // |
| 30 | // Extending: add the label with a comment naming where it comes from. The |
| 31 | // skip only matters for ids that have not been minted yet, so adding a label |
| 32 | // is always safe. Removing one is safe too, but once the allocator has |
| 33 | // passed its id that id stays unused for good (allocation is "one past the |
| 34 | // highest id in the bucket", so nothing goes back for it). |
| 35 | var reservedSqids = []string{ |
| 36 | // dev.oncarlos.com: the dev deployment's apps domain. Flagship's Route53 |
| 37 | // zone has `*.dev.oncarlos.com A <dev edge>` (carloku-infrastructure |
| 38 | // dns53.tf, oncarlos_dev_wildcard, #9). Sqid(1168). |
| 39 | "dev", |
| 40 | // edge.<apps-domain>: the steering hostname the converger publishes and |
| 41 | // health-checks on every armed edge (steering.ConvergeDeployment, |
| 42 | // edge steeringprobe, console reservedDomains). Sqid(49868). |
| 43 | "edge", |
| 44 | // www.<apps-domain>: not served today, but it is the label anyone would |
| 45 | // add next for the apps domain's own apex site, and a tenant holding it |
| 46 | // would look like the platform's own website. Held back pre-emptively; |
| 47 | // Sqid(9978). |
| 48 | "www", |
| 49 | } |
| 50 | |
| 51 | // ReservedSqids returns a copy of the labels no account may be given as its |
| 52 | // sqid. A copy, so no caller can change what the allocator skips. |
| 53 | func ReservedSqids() []string { |
| 54 | return append([]string(nil), reservedSqids...) |
| 55 | } |
| 56 | |
| 57 | // IsReservedSqid reports whether s is a label no account may be given. |
| 58 | func IsReservedSqid(s string) bool { |
| 59 | for _, r := range reservedSqids { |
| 60 | if s == r { |
| 61 | return true |
| 62 | } |
| 63 | } |
| 64 | return false |
| 65 | } |
| 66 | |
| 67 | // skipReservedIDs returns id, or the first id after it whose sqid is not |
| 68 | // reserved. A pure function of the id and the list, which is what makes the |
| 69 | // skip safe without any stored state: every minter, on every box and after |
| 70 | // every restart, steps over exactly the same ids. |
| 71 | func skipReservedIDs(id int64) int64 { |
| 72 | for IsReservedSqid(Sqid(id)) { |
| 73 | id++ |
| 74 | } |
| 75 | return id |
| 76 | } |
| 77 | |