docs: add Service discoverability guide under Frontends#323
Conversation
Add a guide describing what a canister app exposes so an AI agent can discover and use it from just its URL, organized as five layers: composition (/.well-known/ic-architecture manifest), interface (candid:service), behavior (getApiDoc), data (OQL), and identity (/.well-known/ii-derivation-origin). Placed after Custom domains; bump Response certification and Frontend frameworks sidebar order to follow.
|
🤖 Here's your preview: https://soxyi-6iaaa-aaaam-ai2ra-cai.icp0.io |
There was a problem hiding this comment.
Pull request overview
Note: live brand rules (/rules.json) could not be reached, so this review applied the bundled icp-brand-voice rules (authored against brand guide v2.25).
Adds a new frontend guide that defines a structured, layered approach for making canister apps discoverable to AI agents from only an app URL, and updates the Frontends guide ordering so the new page sits after Custom domains.
Changes:
- Add
Service discoverabilityguide underdocs/guides/frontends/describing five discovery layers (composition, interface, behavior, data, identity) and anti-patterns. - Adjust Frontends sidebar ordering to insert the new guide after Custom domains.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| docs/guides/frontends/service-discoverability.md | New guide documenting URL-first discovery signals and a deployment/verification checklist for agent consumption. |
| docs/guides/frontends/certification.md | Sidebar order update to accommodate the new guide in the Frontends sequence. |
| docs/guides/frontends/frameworks.md | Sidebar order update to accommodate the new guide in the Frontends sequence. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
curl -s exits 0 on an HTTP 404, so the '|| echo default' branch never ran when the ii-derivation-origin file is absent (the documented default case). Use curl -sf so a non-2xx response is treated as an error and the fallback fires.
| - Serve real JSON with `Content-Type: application/json`. The most common failure is a single-page-app catch-all returning `index.html` for unknown paths. Exempt `/.well-known/*` from the SPA rewrite in your asset canister configuration. | ||
| - Generate it at deploy time. Canister IDs differ per network (local, staging, mainnet), so the file must be produced by the deploy pipeline (which already knows the IDs) rather than committed with hard-coded values. | ||
|
|
||
| To serve `/.well-known/*` from an asset canister, add a rule to `.ic-assets.json5` so the hidden directory is included, exactly as for the `ic-domains` file: |
There was a problem hiding this comment.
perhaps these instructions are too specific to the old asset canister and we can keep the instructions more generic.
There was a problem hiding this comment.
Good point. Made the serving guidance implementation-neutral in c3a7683: dropped the inline .ic-assets.json5 rule, so the serving rule now just states the requirement (serve /.well-known/* as a static file, exempt it from the SPA rewrite) and defers the concrete asset-canister config to the Asset canister and Custom domains pages already linked. Happy to pare it back further if you'd like.
Generated by Claude Code
Address review feedback: the Layer 1 serving rules pinned the specific .ic-assets.json5 rule inline, which is asset-canister-specific. State the requirement generically (serve /.well-known/* as a static file, exempt it from the SPA rewrite) and defer the concrete config to the Asset canister and Custom domains pages already linked.
|
|
||
| If you use the default (the app's own origin), omit the file. Its absence means "derive for the app origin itself." Serve it with no file extension and exempt `/.well-known/*` from the SPA catch-all, exactly as for the manifest. Generate it at deploy time when the origin is a per-network canister URL. | ||
|
|
||
| **What a well-behaved agent does with it.** It fetches `/.well-known/ii-derivation-origin` (falling back to the app origin itself when the file is absent), signs the delegation for that canonical origin, and echoes back both the origin it derived for and the app URL it was asked about with every identity result. An origin mismatch is then visible at a glance instead of hiding behind a plausible-looking principal. |
There was a problem hiding this comment.
I don't understand this part - is it just saying that a well behaved agent would log this information out to the console?
It's not clear during the authentication who is making the call to get this file (I would think it's the II frontend) and are there specific headers the app needs to have to allow those XHR fetches.
There was a problem hiding this comment.
Fair, that paragraph was doing too much. Clarified in ffa4ca7. To answer directly:
- Who fetches it: the agent (or the connector acting for it), the same consumer that reads the other
/.well-knownfiles in this guide, not the Internet Identity frontend. It fetches the file directly, out of band (the waycurlwould), before it constructs the delegation. - Headers / CORS: none needed. It is a plain GET of a public, plain-text file, not a browser XHR issued during the interactive login flow, so it does not depend on CORS or special response headers.
- The "echoes back" part: not a console log the app can see. The agent returns both the origin it derived for and the app URL it was asked about alongside the resulting principal, so a human (or the calling system) can spot an origin mismatch instead of trusting a plausible-looking principal.
The commit splits the paragraph into "who reads this file, and when" versus "what the agent does with it." Happy to adjust further if it still reads unclearly.
Generated by Claude Code
There was a problem hiding this comment.
I don't like this part.
For ex, with icp-cli if it wants to be well behaved - As a user I ask to link a web identity for nns.internetcomputer.org, the cli would lookup the .well-known/ii-delegationOrigin and actually make a request to link nns.ic0.app. Then tell me that it gave me an identity for nns.ic0.app which does not appear to be what I wanted and assumes I understand the history of hostnames of the NNS.
I don't get why II doesn't do that lookup itself - in the end, I just want my principal for that app, I don't really care what the derivation origin is as long as it is the correct one for this site regardless of the name the developer chose to use.
Address review feedback on Layer 5: split the dense 'well-behaved agent' paragraph into who reads the file (the agent/connector, out of band like curl, not the II frontend during login, so no CORS or special headers) and what it does with it (report both origins alongside the principal so a mismatch is visible; a report in the agent's result, not a console log).
Summary
Adds a new guide, Service discoverability, under
guides/frontends/, placed immediately after Custom domains in the sidebar.The page describes what a canister app should expose so an AI agent can discover and use it end to end from just its URL, organized as five independently adoptable layers:
/.well-known/ic-architectureJSON manifest listing every canister and its role, served at the extensionless well-known path and generated at deploy time.candid:servicemetadata.getApiDoc/get_api_docquery method returning a markdown guide to units, lifecycle, and gotchas the types cannot convey.schema+executequery surface for data-rich apps./.well-known/ii-derivation-origin, and why theii-alternative-originsfile is the inverse relation and must not be read backwards.It also covers discovery anti-patterns (HTML-embedded metadata, the forgeable
x-ic-canister-idheader, runtime cookie config, JS-bundle mining, SPA catch-all responses), a precedence table of who produces what, a deployment checklist, and acceptance tests.Changes
docs/guides/frontends/service-discoverability.md(sidebar.order: 3).docs/guides/frontends/certification.md: sidebar order3→4.docs/guides/frontends/frameworks.md: sidebar order4→5.Notes
candid:service,ii-alternative-origins) and which are proposed..ic-assets.json5/ SPA routing), Custom domains (theic-domainswell-known pattern), Internet Identity (derivationOrigin/ alternative origins), and the Candid interface guide.npm run buildpasses; the new page builds with no validation warnings. Prose follows the docs style rules (no em-dashes, US spelling, sentence-case headings, relative.mdlinks).