diff --git a/public/connect/schemas/connect-protocol.v1.schema.json b/public/connect/schemas/connect-protocol.v1.schema.json index 49560f2..42786c8 100644 --- a/public/connect/schemas/connect-protocol.v1.schema.json +++ b/public/connect/schemas/connect-protocol.v1.schema.json @@ -28,7 +28,7 @@ "grantScope": { "type": "object", "additionalProperties": false, - "required": ["contracts"], + "required": ["access", "contracts"], "properties": { "access": { "enum": ["contract", "full_collection"] }, "contracts": { diff --git a/src/data/conformance.json b/src/data/conformance.json index 08f83bc..82d4009 100644 --- a/src/data/conformance.json +++ b/src/data/conformance.json @@ -1,5 +1,5 @@ { - "generated_at": "2026-07-25", + "generated_at": "2026-07-26", "spec_version": "0.3.0", "implementations": [ { diff --git a/src/pages/sdk/manifest/index.astro b/src/pages/sdk/manifest/index.astro index 31142af..e16118d 100644 --- a/src/pages/sdk/manifest/index.astro +++ b/src/pages/sdk/manifest/index.astro @@ -122,9 +122,9 @@ const portableManifest = `{

- Portable manifests use key-bound short-code authorization, accept local - collections only, and keep their credentials in memory when opened from - {" "}file://. See the + Portable manifests use key-bound short-code authorization, can accept local + or hosted collections, and keep their credentials in memory when opened + from file://. See the {" "}portable HTML application guide.

@@ -155,15 +155,15 @@ const portableManifest = `{ collection_kind: "hosted" - Offer only provider-backed collections; unavailable to portable files + Offer only provider-backed collections, including to portable files
Leave collection_kind out when either authority is acceptable.

- The SDK selects direct or relay transport automatically within a local - grant. + The SDK selects direct, relay, or hosted transport automatically after + approval.

diff --git a/src/pages/sdk/portable-apps/index.astro b/src/pages/sdk/portable-apps/index.astro index dd73d9d..755c1a6 100644 --- a/src/pages/sdk/portable-apps/index.astro +++ b/src/pages/sdk/portable-apps/index.astro @@ -16,7 +16,7 @@ const manifest = `{ const browserBundle = ``; const application = ` @@ -95,18 +95,20 @@ const application = `

Connect identifies the normalized manifest by its SHA-256 digest. Changing any declared field creates a different application identity and requires a - new approval. Portable applications currently authorize computer-owned - collections only. A manifest that requests - {" "}collection_kind: "hosted" is rejected. + new approval. Portable applications can authorize local or hosted + collections through the same connection API. Add + {" "}collection_kind: "hosted" when the app specifically needs + a durable provider-backed collection; omit it to offer every compatible + authority.

Authorize with a short code and installation key

    -
  1. The file registers its inline manifest and generates a P-256 relay key.
  2. +
  3. The file registers its inline manifest and generates an ephemeral P-256 key so a local collection remains available as a choice.
  4. Connect returns a short-lived device code and an eight-character user code.
  5. The SDK opens the Connect approval page in a popup and reports the code through onDeviceCode.
  6. -
  7. The signed-in user confirms the code, reviews the downloaded-file warning, chooses a local collection, and narrows the operations.
  8. -
  9. The SDK polls at the server-provided interval and accepts only the grant bound to its application key.
  10. +
  11. The signed-in user confirms the code, reviews the downloaded-file warning, chooses a compatible local or hosted collection, and narrows the operations.
  12. +
  13. The SDK polls at the server-provided interval and accepts only an exact opaque-origin grant: key-bound encrypted relay for local access, or a scoped provider capability for hosted access.

Device codes expire after ten minutes, are stored as hashes by the control @@ -125,9 +127,11 @@ const application = `

Browsers serialize local-file origins as null. For a portable manifest opened from file://, the SDK stores the authorization - token and non-extractable private key in process memory. Another downloaded - file cannot inherit them through localStorage or IndexedDB. - Reloading or reopening the file requires authorization again. + token and non-extractable private key in process memory. The key is + discarded after a hosted collection is selected. Another downloaded file + cannot inherit the refresh credential or hosted capability through + {" "}localStorage or IndexedDB. Reloading or reopening the file + requires authorization again.

An embedding shell can inject custom storage and @@ -162,14 +166,28 @@ dist/browser/mdbase-connect.min.js.sha384`}

Connect from one HTML file

+

+ Application code does not choose a transport. The returned + {" "}MdbaseConnection uses direct, relay, or hosted access as + required while describe(), query(), + {" "}create(), and the other operation methods stay the same. + Read connection.route only for diagnostics or status UI. +

Keep the application page inside the grant boundary

- The local connector is the final authorization boundary. It accepts + For local access, the connector is the final authorization boundary. It accepts {" "}Origin: null only for an active portable grant with the exact encrypted relay binding. Every operation authenticates the grant, application, connector, collection, key ID, epoch, counter, request ID, and - ciphertext. CORS permission alone does not authorize an operation. + ciphertext. +

+

+ For hosted access, the provider receives a short-lived bearer capability + limited to one replica, collection, grant, operation set, record scope, + expiry, and the exact Origin: null value. Refresh rotates both + the Connect credential and provider capability. CORS permission alone does + not authorize an operation.

Code already running inside an approved page can use that page's diff --git a/src/pages/sdk/routing/index.astro b/src/pages/sdk/routing/index.astro index 7484b58..d86af2a 100644 --- a/src/pages/sdk/routing/index.astro +++ b/src/pages/sdk/routing/index.astro @@ -95,12 +95,13 @@ const options = `const mdbase = new MdbaseConnect({ a trusted data processor.

-

Portable files use local authority only

+

Portable files use the same route-neutral connection

- A downloaded file uses the same direct and encrypted-relay routes after its - short-code approval. Portable manifests cannot request a hosted collection. - This restriction keeps hosted renewal capabilities out of an opaque browser - origin until they have an equivalent sender constraint. + A downloaded file can use direct, encrypted-relay, or hosted-provider access + after its short-code approval. For hosted access, its short-lived capability + is bound to the exact grant, collection, scope, operations, expiry, and + opaque Origin: null, and remains in process memory. The + consuming operation API is identical across all three routes.

Native shells

diff --git a/src/pages/sdk/security/index.astro b/src/pages/sdk/security/index.astro index 40ab4e6..33d9926 100644 --- a/src/pages/sdk/security/index.astro +++ b/src/pages/sdk/security/index.astro @@ -50,9 +50,12 @@ import DocsLayout from "../../../components/DocsLayout.astro";

Treat downloaded application code as authorized code

Every local file has the opaque browser origin null. Connect - does not trust that origin by itself. The connector accepts it only when - the request matches an active portable grant, the P-256 application key, - and the encrypted relay envelope. + does not trust that origin by itself. For a local grant, the connector also + requires the P-256 application key and encrypted relay envelope. For a + hosted grant, the provider requires a short-lived bearer capability scoped + to one grant, collection, operation set, record scope, expiry, and that + exact opaque origin. Both refresh credentials and provider capabilities + remain in process memory for file://.

Code already running in an approved page has that page's access. Keep @@ -91,7 +94,7 @@ import DocsLayout from "../../../components/DocsLayout.astro";

Application release checklist