Prompt and context
An HTTPS page helps users configure a USB device. After the user clicks “Connect device,” the browser should show an explicit permission prompt. The page must handle unsupported browsers, embedded iframes, disconnects, denied permission, and refresh recovery.
Explain capability detection, user gestures, origin and Permissions Policy, device filters, data minimization, errors, progressive enhancement, and tests. The page must not silently scan on load or send raw device data to third-party analytics.
What the interviewer tests
The interviewer wants you to treat WebUSB as a permission-controlled powerful Web API, not an ordinary DOM device list. MDN describes a browser prompt when requesting a device; the Permissions API result is affected by secure context, Permissions Policy, user interaction, and prompt state.
Strong answers connect the permission-granting origin, top-level page, embedding policy, device filters, and connection lifecycle. Chrome recommends explicitly setting Permissions Policy and keeps the final allow decision with the user. Progressive enhancement gives users without WebUSB a readable explanation, native-tool link, or support path.
30-second answer
“First detect HTTPS and navigator.usb; offer documentation or a native tool when unsupported. Call requestDevice() only from the user’s Connect button and use precise vendor and product filters. Set a response Permissions Policy that permits only trusted origins; embedded frames must be checked too. After connection, access only the interfaces needed for the task, validate responses, and listen for disconnects. Treat denial, policy blocking, no match, and unsupported browsers as distinct actionable states, not server errors.”
Step-by-step design
Step 1: Establish the trust boundary and goal
Define commands and data the page actually needs, whether the device contains sensitive information, and whether WebUSB is required. Prefer a more specific browser API or native tool when one exists. Do not read every interface for convenience.
Step 2: Detect capability and progressively enhance
Check HTTPS, browser capability, and required methods. Without support, provide documentation, driver or native-app guidance, and human support. Detection chooses an enhancement branch; an API existing does not imply permission or device compatibility.
Step 3: Bind permission to a user gesture
Call requestDevice() from a clear click or keyboard action, and explain that a browser permission prompt will appear. Never request during load, a timer, a hidden iframe, or an unrelated async callback. Distinguish cancellation, policy blocking, unsupported browsers, and no matching devices while giving a useful next step.
Step 4: Restrict origins and Permissions Policy
Set an explicit header such as Permissions-Policy: usb=(self) or a narrower trusted-origin list. For an embed, verify the top-level origin, iframe allow attribute, and policy together; do not grant every third party. CSP, Trusted Types, and dependency review still protect the page itself.
Step 5: Filter devices and minimize access
Filter by vendor, product, or protocol so unrelated devices are not shown. After connection, enumerate only required configurations and interfaces, enforce read/write timeouts and message-size limits, and validate response formats. Release interfaces after the task and keep serial numbers, raw packets, and identity data out of analytics.
Step 6: Handle connection, disconnect, and refresh
Listen for connect and disconnect, showing device name, current step, and a reconnect action. Stop polling and clear handles on disconnect. A reconnect repeats filtering and task confirmation. After refresh, do not assume a previous connection or permission remains usable; let the user select again.
Step 7: Design error and privacy UX
“You cancelled permission” should not look like a server outage. A policy block should point to an administrator or embedding owner; no match should explain how to connect the intended model. Log stable categories and correlation IDs, not raw device data. Obtain separate consent before sending redacted diagnostics to a third party.
Step 8: Verify environments and security regressions
Test insecure context, multiple browsers, iframes, policy blocking, denial, no match, double clicks, disconnect, sleep and wake, and malicious device responses. Verify every prompt follows a user gesture, policies allow only expected origins, and the fallback still completes the help path.
Trade-offs, boundaries, and information gain
Narrow filters reduce mis-selection and privacy exposure but can exclude old firmware; versioned compatibility rules make that trade explicit. Automatic reconnect improves UX but must not bypass a new user choice or treat an old handle as trusted state.
Permissions Policy restricts embedding origins but is not device authorization; the browser still asks the user. Progressive enhancement costs design and test time, yet turns capability differences into a clear next step instead of a blank page.
Model high-quality answer
“I would treat WebUSB as an enhancement constrained by origin and user permission. Detect the API in HTTPS and offer a native tool when unsupported. Only the Connect button calls requestDevice(), with precise filters. The response header allows USB to trusted origins; embedded frames must satisfy the top-level policy and allow attribute.
After connection, access only required interfaces, validate responses, bound time and message size, and never log raw packets. Listen for disconnect, clean handles, and ask the user to reconnect; after refresh, ask them to select again. Cancellation, policy block, no match, and unsupported browsers each get a specific next action. Tests cover browsers, iframes, disconnects, malicious responses, and fallback UX.”
Common mistakes
- Call
requestDevice()on page load. Permission requests must follow an explicit user gesture. - Treat WebUSB like ordinary enumeration. Secure context, policy, and browser permission all matter.
- Use empty or broad filters. Users can select unrelated devices and expose unnecessary data.
- Grant USB to every iframe. Third-party origins gain a larger device attack surface.
- Restore an old handle automatically. Refresh, disconnect, and permission state may have changed.
- Log raw device packets. Diagnostics can contain sensitive data or serial numbers.
- Support only one browser. Users without WebUSB need a working fallback.
- Show denial as a server error. The user needs a retry or administrator action.
Follow-up questions and answers
Why must permission follow a user gesture?
Device access affects privacy and security. The browser needs the user to know which origin requests which device, and the gesture constrains when a prompt can appear.
How does Permissions Policy relate to the browser prompt?
Policy decides whether the document is eligible to use the capability. Even when allowed, the browser applies origin, context, and user choice before showing a prompt. Both layers must pass.
How do you reconnect after a disconnect?
Stop I/O and polling, clear handles, listen for reconnection, and ask the user to confirm a matching device. Never retry forever in the background.
Why not read every interface for diagnostics?
Least access reduces privacy, protocol-misoperation, and driver-compatibility risk. Diagnostics should require a clear action, minimal fields, and separate log consent.
What do you do without WebUSB support?
Offer documentation, drivers or a native tool, compatibility guidance, and human support. The core goal should not collapse into “use another browser.”