docs: cover the ii-app-metadata well-known file in the II guide - #347
Merged
Conversation
Apps can now provide their own name, description, and logo for the Internet Identity sign-in screens by serving /.well-known/ii-app-metadata on the origin their identities are derived for, replacing the curated list that used to be the only way to get branded. Nothing in the guide covered it. The new section sits between Alternative origins and Common mistakes, which is where it belongs: it reuses the derivation origin the reader has just configured, and extends the same .ic-assets.json5 with CORS entries for the document and the logo. It carries the limits an integrator has to respect (field lengths, the raster-only logo rules, the document cap), the fact that one invalid field drops the whole document and why the browser console is the place to look, and the reminder that this metadata proves nothing about an app's identity, which is why the origin stays on screen next to it.
main now mirrors the App metadata section (#350 synced .sources/internetidentity to release-2026-08-21), so the guide can point at #app-metadata instead of the specification page root. This commit originally carried the submodule bump and the regenerated spec files. The rebase dropped them: #350 landed the identical sync first, so only the anchor change remains.
aterga
force-pushed
the
docs/guides-authentication-ii-app-metadata
branch
from
August 24, 2026 13:21
521a246 to
bb5bdc4
Compare
aterga
marked this pull request as ready for review
August 24, 2026 13:33
Member
Review: App metadata section (docs/guides/authentication/internet-identity.mdx)Must fix
Suggestions
Verified
|
Review feedback on #347. The bullet stating that a failed field invalidates the whole document sat directly above the logo requirements, which read as though a logo that fails to fetch or decode takes the name and description down with it. It does not: only the shape of `logo` is validated with the rest of the document, and an asset-level failure costs the logo alone. Someone debugging an intermittent 500 on their logo would have drawn the wrong conclusion. Also from the review, both optional: - `U+FEFF` is rejected alongside the control characters, and isolates must be balanced. - A missing or invalid document falls back to the curated entry II still ships for a small list of apps before falling back to the origin alone, so "exactly as they do without it" overstated it.
Contributor
Author
|
Feedback addressed in
Thanks for cross-checking the numbers against Generated by Claude Code |
marc0olo
approved these changes
Aug 24, 2026
aterga
added a commit
to dfinity/icskills
that referenced
this pull request
Aug 25, 2026
## What Documents Internet Identity's **app metadata** document (`/.well-known/ii-app-metadata`) in the `internet-identity` skill, based on [dfinity/developer-docs#347](dfinity/developer-docs#347) and the normative "App metadata" section of `docs/ii-spec.mdx` in `dfinity/internet-identity`. Any app can now publish its own name, description, and logo for the II sign-in screens — permissionlessly, superseding the curated list II ships for a handful of known apps. ## Changes **`skills/internet-identity/SKILL.md`** - New section **"Showing your app's name, description, and logo on the sign-in screen"**, placed after "Serving an app at more than one origin" since the two interact: - the document shape, and that II reads it from the **derivation origin** (so alternative origins inherit it — no per-origin copy) - the field rules that decide whether the document is used at all: 40/120 code-point limits, at least one visible character, rejected control/bidi-override characters, balanced isolates, and **one bad field invalidating the whole document** - `logo` requirements: raster only (SVG rejected), same origin, ≤ 1 MiB, ≤ 4096 px/axis, re-encoded by II at ≤ 512 px — and the split between failures that lose the whole document and failures that cost only the logo - transport rules: ≤ 8 KiB, `200`, no redirects, no credentials, 10 s timeout - CORS headers for **both** the document and the logo, which fail differently - Two new pitfalls in "Mistakes That Break Your Build": serving the document on the wrong origin or without CORS (13), and expecting a bad field to be dropped / confusing a rejected logo with a rejected document (14). - Description mentions the document so queries about the sign-in screen's name and logo route here. **Deviation from the upstream docs PR:** the docs PR configures CORS with `.ic-assets.json5`. This skill targets the `@dfinity/static-site` recipe, whose canister does not read that file (it isn't even uploaded), so the snippet uses the `_headers` file — matching the adjacent alternative-origins section and the `static-site` skill. The extension-less path also needs the bare `Content-Type:` form to get `application/json`. **`evaluations/internet-identity.json`** — three output evals (static-site file layout, adversarial SVG + partial-validation, which origin serves the document) and one trigger query. ## Evals All three added cases run with baseline; trigger evals re-run because the description changed. <details> <summary>Output evals — added cases (with skill vs baseline)</summary> ``` ━━━ App metadata document on the static-site recipe ━━━ WITH skill: 5/5 passed ✅ Serves a JSON document at .well-known/ii-app-metadata with name, description, and/or logo fields ✅ Adds a _headers entry setting Access-Control-Allow-Origin: * for /.well-known/ii-app-metadata AND for the logo asset ✅ Sets Content-Type: application/json for /.well-known/ii-app-metadata (the file has no extension) ✅ Uses a raster logo (PNG/JPEG/WebP/GIF/AVIF) on the same origin as the document — not an SVG and not a cross-origin URL ✅ Does NOT create a .ic-assets.json5 file WITHOUT skill: 1/5 passed ❌ Serves a JSON document at .well-known/ii-app-metadata with name, description, and/or logo fields → The assistant produced no files at all, only a request for WebFetch/WebSearch permission. ❌ Adds a _headers entry setting Access-Control-Allow-Origin: * for /.well-known/ii-app-metadata AND for the logo asset → No _headers file or any file content was output. ❌ Sets Content-Type: application/json for /.well-known/ii-app-metadata (the file has no extension) → No headers configuration was provided since no files were output. ❌ Uses a raster logo (PNG/JPEG/WebP/GIF/AVIF) on the same origin as the document → No logo file or reference to one was provided in the output. ✅ Does NOT create a .ic-assets.json5 file ━━━ Adversarial: SVG logo and partial validation of ii-app-metadata ━━━ (oracle sharpened after review — see the review thread on evaluations/internet-identity.json) WITH skill: 5/5 passed ✅ Says no — the over-long description is a field that fails validation, and one invalid field invalidates the WHOLE document rather than being dropped on its own ✅ States the description limit is 120 Unicode code points, so a 200-character description fails validation ✅ States that image/svg+xml is not accepted — the logo must be a raster image ✅ Distinguishes the two failure modes: an SVG logo on its own costs only the logo, so it is the description — not the SVG — that takes the whole document down ✅ Does NOT claim sign-in itself breaks, and does not assert the screen necessarily shows the bare origin WITHOUT skill: 0/5 passed ❌ Says no — description failure invalidates the whole document rather than being dropped alone → The claim is framed throughout as unverified speculation ('likely', 'best recollection') rather than a confident, correct statement of fact. ❌ States the description limit is 120 Unicode code points → No specific numeric limit is ever given anywhere in the output. ❌ States that image/svg+xml is not accepted and raster formats are required → The rejection of SVG is presented as a speculative guess and only PNG/JPEG are mentioned, not the full accepted raster set. ❌ Distinguishes the two failure modes → The output instead claims the SVG issue 'alone being sufficient to break' all branding, conflating it with the whole-document failure. ❌ Does not claim sign-in breaks or that the screen necessarily shows the bare origin → The output asserts the bare-origin fallback without mentioning the curated-entry fallback for known apps. ━━━ Which origin serves ii-app-metadata with alternative origins ━━━ WITH skill: 3/3 passed ✅ Says to publish it only on the derivation origin, because II fetches the document from the origin identities are derived for ✅ Explains that the alternative origins that derivation origin lists are then presented with the same name, description, and logo — no per-origin copy to keep in sync ✅ Does NOT tell the user to publish a copy on each alternative origin WITHOUT skill: 0/3 passed ❌ Says to publish it only on the derivation origin → The output instructs publishing on both origins and claims II reads from the relying party origin. ❌ Explains that alternative origins inherit the same metadata → The output instead describes two separate documents serving different purposes. ❌ Does NOT tell the user to publish a copy on each alternative origin → The output explicitly tells the user to publish the metadata file on both origins. ━━━ Summary ━━━ App metadata document on the static-site recipe: WITH 5/5 | WITHOUT 1/5 Adversarial: SVG logo and partial validation of ii-app-metadata: WITH 5/5 | WITHOUT 0/5 Which origin serves ii-app-metadata with alternative origins: WITH 3/3 | WITHOUT 0/3 ``` </details> <details> <summary>Trigger evals (description changed)</summary> ``` Should trigger: 7/7 correct ✅ "Add login to my ICP frontend app" ✅ "How do I integrate Internet Identity?" ✅ "I need passkey authentication for my dapp" ✅ "Set up sign-in with Internet Identity" ✅ "How does delegation work with II?" ✅ "Add auth to my canister frontend" ✅ "How do I get my app's name and logo to show on the Internet Identity sign-in screen?" Should NOT trigger: 6/6 correct ✅ "Connect a wallet to my dapp" ✅ "How do I deploy my canister?" ✅ "Implement ICRC-1 token transfers" ✅ "Set up inter-canister calls" ✅ "How does stable memory work?" ✅ "Add a frontend to my canister" Trigger evals: should-trigger 7/7 | should-not-trigger 6/6 ``` </details> Existing eval cases were not re-run: none of them cover content this PR touched (the alternative-origins case, #14, is unchanged and its section was not edited). `npm run validate` passes — 29 skills, no errors. The skill now trips the validator's "body > 500 lines" advisory warning (547 lines); the token-count advisory was already tripped before this change. ## Review round (1bc611e) Three findings from the Copilot review, all valid and all fixed: - Pitfall 13 conflated the two CORS failure modes. An unreadable **document** means none of your metadata is used; an unreadable **logo** costs only the logo. - "The app is shown with no metadata" skipped the curated fallback. Now: none of *your document* is applied, then the fallback order (curated entry for a known app, origin alone otherwise). - The adversarial eval's oracle did not test the distinction the section introduces. Sharpened, and the delta improved from 4/4 vs 2/4 to **5/5 vs 0/5**. Pitfall 14 also now splits `logo` across both modes explicitly: a cross-origin URL fails *document* validation and takes the whole document down, while an SVG, an oversized image, or one that cannot be fetched costs only the logo. ## Notes - The link to the II specification points at the spec page without an anchor: the App metadata section is on `main` in `dfinity/internet-identity` but has not yet been published to the docs site, so an `#app-metadata` fragment would currently be dead. --------- Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
docs/guides/authentication/internet-identity.mdx, between Alternative origins and Common mistakes, covering the/.well-known/ii-app-metadatadocument that lets an app supply its own name, description, and logo for the Internet Identity sign-in screens. Nothing in the guide covered it: until now the only way to get branded screens was to be in the curated list shipped inside II, which this mechanism replaces..ic-assets.json5with CORS entries for the document and the logo.200with no redirect, and the 10 second budget. It also states that a single invalid field drops the whole document and that II names the offending field in the browser console, since that is the first thing someone debugging missing metadata needs to know.#app-metadata) rather than at the page root.Scope
This PR is now a documentation change only:
docs/guides/authentication/internet-identity.mdx, +56 / -1.Earlier revisions of this branch also carried a bump of
.sources/internetidentitytorelease-2026-08-21and the regenerated spec files, because the mirrored specification did not yet have the section this guide links to. #350 has since landed the identical sync on main, so rebasing dropped those changes as already applied. The anchor works against main as it stands.docs/references/internet-identity-spec.mdon main now carries the App metadata section and its JSON Schema, and states the alternative origins limit as 100 (upstream dfinity/internet-identity#4221 and #4261, both inrelease-2026-08-21).Relationship to #349
#349 (merged) raised the same limit in the guide prose, on line 572. This branch inserts a section further down, so the two do not overlap. With #350 also merged, the guide and the specification now agree on 100.
Structural decisions
##section so it sits as a sibling of Alternative origins and Common mistakes rather than nesting under either. The mechanism is independent of alternative origins: apps that never set aderivationOriginuse it too.Verification
b21a283); the branch is two commits and merges cleanly.npm run buildpasses from a cleandist/(exit 0, 210 pages), and the builtdist/references/internet-identity-spec/index.htmlcontainsid="app-metadata", so the guide's anchor resolves against main's mirrored spec.node scripts/validate.js --all: no errors in the changed file. The 4 reported errors are pre-existing, indocs/guides/digital-assets/chain-key-tokens.mdxanddocs/guides/backends/data-persistence.mdx, both untouched here.src/frontend/src/lib/utils/appMetadata.tsin dfinity/internet-identity), not from memory, and match the mirrored spec section now on main.:::notein the new section renders as a plaindivrather than a styled callout. So does the page's pre-existing note under Alternative origins: the built page contains nostarlight-asideelements at all, so this is existing site behaviour and not something this change introduces. Left as is to match the page; happy to open a separate issue if the directive handling should be fixed.