Connect SDK
Portable HTML applications
Connect one downloaded HTML file through a key-bound approval flow, with no web origin, redirect URI, build step, or application backend.Release status
The production service accepts the portable manifest and device flow. The version-pinned CDN URL below becomes available when @mdbase/connect and @mdbase/connect-protocol are published. Until then, build the browser artifact from the Connect repository for development.
Connect remains pre-release, so the manifest and encrypted wire protocol stay labelled v1. A later public release can establish a new compatibility boundary when one is needed.
Declare a portable application inline
{
"manifest_version": 1,
"distribution": "portable",
"id": "dev.example.portable-notes",
"name": "Portable notes",
"project_url": "https://example.dev/portable-notes",
"requirements": {
"access": "full_collection",
"contracts": []
}
}distribution: "portable" replaces homepage and redirect_uris. The optional project_url gives the user somewhere to inspect the project or source. It must use HTTPS, but it does not verify the publisher or prove where the downloaded file came from.
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 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
- The file registers its inline manifest and generates an ephemeral P-256 key so a local collection remains available as a choice.
- Connect returns a short-lived device code and an eight-character user code.
- The SDK opens the Connect approval page in a popup and reports the code through
onDeviceCode. - The signed-in user confirms the code, reviews the downloaded-file warning, chooses a compatible local or hosted collection, and narrows the operations.
- 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 plane, and can be consumed once. PKCE prevents another installation from exchanging a copied code. Polling faster than the returned interval produces slow_down.
Start authorize() from a user action so the browser permits the popup. Supply openVerification when an embedding shell owns the approval window. If the default popup is blocked, the SDK throws approval_window_blocked with the verification URL and code.
Treat file:// as an opaque, session-only origin
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. 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 keyStore adapters as an explicit trust decision. connect.environment() reports the active distribution, application origin, and whether credential storage is memory, persistent, or custom.
Pin the browser bundle and its integrity hash
The npm package contains one dependency-free IIFE bundle plus its generated SHA-384 metadata:
dist/browser/mdbase-connect.min.js
dist/browser/integrity.json
dist/browser/mdbase-connect.min.js.sha384Use an exact package version and copy the integrity value from that same version's integrity.json. The browser global is MdbaseConnect.
<script
src="https://cdn.jsdelivr.net/npm/@mdbase/connect@0.1.0-beta.12/dist/browser/mdbase-connect.min.js"
integrity="sha384-PD+lazz69NHRGmB9iNPltd6StRK0fJ5hockUI2jyoYwSu3ti0AnRQNrjWMXlHs2D"
crossorigin="anonymous"></script>Do not use an unversioned CDN URL, a moving tag, or a script without Subresource Integrity in a downloaded application.
Connect from one HTML file
<button id="connect">Connect a collection</button>
<output id="code" aria-live="polite"></output>
<script>
const manifest = {
manifest_version: 1,
distribution: "portable",
id: "dev.example.portable-notes",
name: "Portable notes",
requirements: {
access: "full_collection",
contracts: []
}
};
const connect = new MdbaseConnect.MdbaseConnect({
serverUrl: "https://connect.mdbase.dev",
manifest
});
document.querySelector("#connect").onclick = async () => {
const { connection } = await connect.authorize({
operations: ["describe", "read", "query"],
onDeviceCode: ({ userCode }) => {
document.querySelector("#code").textContent =
"Confirm " + userCode + " in mdbase Connect";
}
});
console.log(await connection.describe());
};
</script>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
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.
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 authorization. Keep untrusted scripts out of the file, pin every external resource, and request only the operations used by the current feature.