NAP-CONNECT: User-gated direct network access - #19
Draft
dskvr wants to merge 4 commits into
Draft
Conversation
dskvr
added a commit
that referenced
this pull request
Apr 21, 2026
dskvr
marked this pull request as draft
April 22, 2026 08:56
This was referenced Jun 14, 2026
Rebased onto current master; spec only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
NAP-CONNECT has no postMessage wire protocol, but its injected runtime state is still normative. The state shape now uses a CDDL-style record instead of TypeScript declarations. Constraint: Keep this branch scoped to NAP-CONNECT. Confidence: high Scope-risk: narrow Directive: Do not describe NAP-CONNECT runtime state with implementation-language types. Tested: git diff --check Tested: rg found no TypeScript code fences or declarations in naps/NAP-CONNECT.md
The NappletConnect runtime state is now described with a Markdown field table instead of a CDDL-style block. The grant and origins semantics are unchanged. Constraint: PR #19 owns NAP-CONNECT; keep this change scoped to that spec file. Confidence: high Scope-risk: narrow Tested: rg for cddl/typescript schema fences and type assignment patterns in NAP-CONNECT Tested: git diff --check -- naps/NAP-CONNECT.md
Open NAP proposal branches need reader-visible changelogs that track semantic spec changes without recording formatting-only migrations. Constraint: Changelog entries are one bullet per semantic commit-change. Rejected: Include schema-table or formatting-only commits | they do not change the spec contract or boundary. Confidence: high Scope-risk: narrow Directive: Keep future changelog entries semantic; omit changelog-only and formatting-only commits. Tested: git diff --check Not-tested: Rendered Markdown
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.
Status: Draft
Namespace:
window.napplet.connectDiscovery:
shell.supports("connect")Class posture: NAP-CLASS-2 (class-contributing NAP)
Summary
NAP-CONNECT provides sandboxed napplets with user-gated direct network access (
fetch,WebSocket,SSE,EventSource) to a pre-declared list of origins. Origins are declared at build time via["connect", "<origin>"]tags in the NIP-5A manifest. The shell reads those tags, prompts the user for approval at first load of a given(dTag, aggregateHash), persists the decision, and emits a runtime Content Security Policy whoseconnect-srcdirective contains the approved origin list. The user's decision is expressed through the HTTP-response CSP the shell serves with the napplet's HTML — not through any postMessage traffic.A napplet declaring any
connecttag takes on the posture defined inNAP-CLASS-2.md. A napplet declaring noconnecttags takes on the default posture defined inNAP-CLASS-1.md. This NAP does not redefine those class postures — see the sub-track documents for CSP shapes, consent-flow MUSTs, grant-persistence semantics, residual-meta-CSP refusal requirements, and revocation responsibilities.NAP-CONNECT has no postMessage wire protocol. Grants are expressed entirely through the runtime CSP the shell emits in the HTTP response for the napplet's HTML, plus a shell-injected discovery meta tag (
<meta name="napplet-connect-granted" content="...">) read synchronously by the napplet shim at install time. There are noconnect.*envelopes.Scope
["connect", "<origin>"], one tag per origin.\n-join → UTF-8 → SHA-256 → lowercase hex) with copy-pasteable conformance fixture (cc7c1b1903fb23ecb909d2427e1dccd7d398a5c63dd65160edb0bb8b231aa742for the 3-origin fixture). Folded into the signed NIP-5A aggregateHash via a syntheticconnect:originsxTag that changes grant key on origin-list modification.window.napplet.connectresolves to{ granted: boolean, origins: readonly string[] }; graceful-degradation default{granted: false, origins: []}.<meta name="napplet-connect-granted" content="<space-separated-origins>">read synchronously by the shim at install time. Name is shell-authoritative; distinct from any dev-mode-onlynapplet-connect-requiresinjection.nap:connect,connect:scheme:http,connect:scheme:ws; shells MAY refuse cleartext by advertisingconnect:scheme:http === false.(dTag, aggregateHash); napplet rebuild with changedconnecttags produces new aggregateHash (viaconnect:originsfold) and auto-invalidates prior grant.NAP-CLASS-2.md).Non-Goals
Guidance
Authors SHOULD default to shell-mediated resource fetching for everything the mediated primitive can express (avatars, static assets, one-shot byte fetches, bech32 resolution); NAP-CONNECT exists specifically for the cases that cannot be expressed that way (
POST/PUT/PATCH, WebSocket, SSE, streaming, custom headers, long-lived connections, third-party libraries callingfetchdirectly). The two surfaces are complementary, not competing.Implementations
(none yet)Changelog
fdf6c3e- Introduced NAP-CONNECT for user-gated direct network access.