---
title: "Ask for system permissions only when a · Agent Wranglers"
url: https://agentwranglers.se/playbook/desktop-apps/installs-and-local-privileges/privacy-prompts
id: DSK-39
level: Recommended
updated: 2026-10-27
build: a2a6bdfed830
tokens: 1080
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Ask for system permissions only when a feature needs them

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Installs and local privileges](https://agentwranglers.se/playbook/desktop-apps/installs-and-local-privileges.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-27.

- ID: DSK-39
- Level: Recommended
- Chapter: [Installs and local privileges](https://agentwranglers.se/playbook/desktop-apps/installs-and-local-privileges.md)
- Rule: Request each system permission, such as camera, microphone, screen recording, location or contacts, at the moment the user starts the feature that needs it. Give each one a purpose string that names the feature, and keep the app working when the user says no.
- Check: On a fresh install, the app shows no permission prompt before the user starts a feature that needs one. Each usage key in the built `Info.plist` names a feature in its text. With each permission refused, a test runs the app's main flows and none crashes.
- How: macOS asks the user before an app reaches the camera, microphone, contacts, photos or protected folders. A prompt at first launch with no context is the one users refuse. On a Mac, the `Info.plist` holds a usage string for each resource, such as `NSCameraUsageDescription`. Apple's documentation says that starting capture without that string raises an exception. A hardened runtime app also needs the matching entitlement, such as `com.apple.security.device.camera`. Keep that list short, as [keep hardened runtime exceptions to the few the app uses](https://agentwranglers.se/playbook/desktop-apps/signing-and-notarisation/mac-entitlements.md) says. On Windows, packaged apps declare device capabilities in the manifest, and users switch each one off in privacy settings. Check the current status before each use, since users can withdraw access at any time. When access is off, show a short message with the way to turn it back on.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### Plain text example

```swift
func startScan() async {
    switch AVCaptureDevice.authorizationStatus(for: .video) {
    case .authorized: scanner.start()
    case .notDetermined: if await AVCaptureDevice.requestAccess(for: .video) { scanner.start() } else { showCameraOffHint() }
    default: showCameraOffHint()
    }
}
```

### JavaScript example

```js
// Electron main process on macOS: ask when the user opens the receipt scanner
import { systemPreferences } from 'electron';

export async function startScan(window) {
  const allowed = systemPreferences.getMediaAccessStatus('camera') === 'granted' || await systemPreferences.askForMediaAccess('camera');
  window.webContents.send(allowed ? 'scanner:start' : 'scanner:camera-off');
}
```

## Sources

- [Apple, Hardened Runtime](https://developer.apple.com/documentation/security/hardened-runtime)
- [Apple, AVCaptureDevice requestAccess](https://developer.apple.com/documentation/avfoundation/avcapturedevice/requestaccess%28for:completionhandler:%29)

## Related rules

- DSK-33 [Keep hardened runtime exceptions to the few the app uses](https://agentwranglers.se/playbook/desktop-apps/signing-and-notarisation/mac-entitlements.md) in Desktop apps and extensions

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/desktop-apps/installs-and-local-privileges/privacy-prompts">Agent Wranglers desktop apps and extensions playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Start at login only after the user turns it on](https://agentwranglers.se/playbook/desktop-apps/installs-and-local-privileges/login-item-consent.md)
- Next: [Ask the Linux sandbox for the fewest permissions](https://agentwranglers.se/playbook/desktop-apps/installs-and-local-privileges/linux-sandbox-permissions.md)
- [Installs and local privileges](https://agentwranglers.se/playbook/desktop-apps/installs-and-local-privileges.md)
