From ccc568aea36dde6738fac35ab417644126a6b0b9 Mon Sep 17 00:00:00 2001 From: Yusef Habib Fernandez Date: Fri, 7 Aug 2026 18:53:28 +0200 Subject: [PATCH] docs(custom-domains): name the ordering trap in the II pitfall MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pitfall 9 described the symptom (II principals change with the origin) and pointed at internet-identity for the fix, but omitted the part that decides whether the fix is still available: it has to happen before the domain collects sign-ins. Once accounts exist under the new domain, repointing it at a derivation origin orphans them. Also names the canister address as the origin to pin, so the reader is not left to pick, and drops the "switching from a canister URL" framing — the canister address does not go away when a custom domain is added. Co-Authored-By: Claude Opus 5 --- evaluations/custom-domains.json | 12 ++++++++++-- skills/custom-domains/SKILL.md | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/evaluations/custom-domains.json b/evaluations/custom-domains.json index c2497b9..4a9659d 100644 --- a/evaluations/custom-domains.json +++ b/evaluations/custom-domains.json @@ -1,7 +1,6 @@ { "skill": "custom-domains", "description": "Evaluation cases for the custom-domains skill. Tests whether agents produce correct DNS records, use the right registration API endpoints, and warn about common pitfalls like provider SSL interference and stale ACME records.", - "output_evals": [ { "name": "DNS record configuration", @@ -77,9 +76,18 @@ "Uses DELETE https://icp.net/custom-domains/v1/DOMAIN to notify the service", "Does NOT suggest only removing DNS records without calling the API" ] + }, + { + "name": "Adversarial: custom domain on an app that already has II users", + "prompt": "My IC app already has a few hundred users signed in with Internet Identity at its canister URL. I am about to point a custom domain at it. Anything I should watch out for? Short answer.", + "expected_behaviors": [ + "Warns that II principals are per-origin, so existing users would get brand-new accounts at the custom domain", + "Says to pin the canister address as the derivation origin and list the custom domain in .well-known/ii-alternative-origins BEFORE the domain goes live", + "Notes that a domain which has already collected sign-ins cannot be repointed without orphaning those accounts", + "Does NOT present the custom domain switch as principal-neutral or a pure DNS change" + ] } ], - "trigger_evals": { "description": "Queries to test whether the skill activates correctly.", "should_trigger": [ diff --git a/skills/custom-domains/SKILL.md b/skills/custom-domains/SKILL.md index d968b68..c5ec812 100644 --- a/skills/custom-domains/SKILL.md +++ b/skills/custom-domains/SKILL.md @@ -42,7 +42,7 @@ Custom domains work at the boundary node level — they map a domain to any cani 8. **Setting `HttpAgent`'s `host` to your custom domain.** `host` is the **API endpoint** canister calls go to, not the domain your frontend is served from. Your custom domain is the HTTP gateway — it does not serve `/api/v2`, so pointing `host` at it (or at `window.location.origin`) makes calls fail. You do not need to set `host`: a recent `@icp-sdk/core` `HttpAgent` resolves an omitted `host` to `https://icp-api.io` (the mainnet API boundary nodes) on a custom domain. Leave it unset, or set it explicitly to `https://icp-api.io` — never the gateway domain. -9. **Forgetting alternative origins for Internet Identity.** II principals depend on the origin domain. Switching from a canister URL to a custom domain changes principals. Configure `.well-known/ii-alternative-origins` to keep the same principals. See the `internet-identity` skill. +9. **Adding a custom domain to an app that already has users.** II principals are per-origin, so the new domain hands every returning user a brand-new account. Pin a derivation origin — the canister address, which a custom domain can never displace — and list the domain in `.well-known/ii-alternative-origins` **before** the domain goes live. A domain that has already collected sign-ins cannot be repointed without orphaning those accounts. See the `internet-identity` skill. ## Implementation