Permissions
Feature code calls plugin events instead of raw platform APIs. The canonical
core.permissions plugin exposes two invokes:
permissions.request(permission)→{ permission, status }permissions.status(permission)→{ permission, status }
where permission is 'storage' | 'camera' and status is
granted | denied | notDetermined | unsupported.
import type { PluginBus } from '@ekrooh/bare/core';import { mediaEvents } from '@ekrooh/bare/plugins/media/events';import { permissionEvents } from '@ekrooh/bare/plugins/permissions/events';
declare const bus: PluginBus; // createPluginBus(messenger), see Transports
const [err, result] = await bus.invoke( permissionEvents.permissions.request('camera'),);if (!err && result.status === 'granted') { await bus.invoke(mediaEvents.media.capture('image'));}Why a plugin
Section titled “Why a plugin”- The web runtime can answer
unsupporteddeterministically. - The native hosts answer with real system permissions
(e.g.
AVCaptureDevice.requestAccesson iOS). - Shared UI code never branches on the runtime — it reads the plugin result.
Untrusted ids
Section titled “Untrusted ids”The permission id is page input. Hosts allowlist it: a missing or unknown id is
answered unsupported on both Android and iOS, never granted. A permission
prompt waits for the user, so the worklet waits up to 5 minutes for the host
(hostTimeoutMs on the permissions.request spec).