# Permissions Guide Mosis apps run in a secure sandbox with limited access to device features. To access sensitive capabilities, apps must declare permissions in their manifest. ## Why Permissions? Permissions protect user privacy and security by: 1. **Informing users** what an app can access before installation 2. **Limiting damage** if an app misbehaves 3. **Maintaining trust** in the Mosis ecosystem ## Declaring Permissions Add permissions to your `manifest.json`: ```json { "id": "com.example.myapp", "name": "My App", "permissions": [ "storage", "network" ] } ``` Only request permissions your app actually needs. Users are more likely to trust apps with fewer permissions. ## Available Permissions ### storage **Description:** Persist data locally between app sessions. **Use cases:** - Save user preferences - Cache data for offline use - Store app state **API access:** ```lua storage.set("key", value) storage.get("key") storage.remove("key") storage.clear() ``` **Note:** All apps have access to in-memory storage during a session. The `storage` permission enables persistence across sessions. --- ### network **Description:** Make HTTP/HTTPS requests to external servers. **Use cases:** - Fetch data from APIs - Submit form data - Load remote content **API access:** ```lua http.get(url, callback) http.post(url, options, callback) http.request(options, callback) ``` **Restrictions:** - HTTPS only (HTTP blocked for security) - Cannot access localhost or internal IPs - Subject to CORS policies --- ### clipboard **Description:** Read from and write to the system clipboard. **Use cases:** - Copy text or data - Paste user content - Share functionality **API access:** ```lua clipboard.write(text) clipboard.read(callback) ``` --- ### notifications **Description:** Display system notifications to the user. **Use cases:** - Reminders - Alerts - Background updates **API access:** ```lua notifications.show({ title = "Reminder", body = "Your timer is done!", icon = "icons/alarm.png" }) ``` **Restrictions:** - Notifications may be rate-limited - Users can disable notifications per-app --- ### camera **Description:** Capture photos using the device camera. **Use cases:** - Photo capture - QR code scanning - Augmented reality **API access:** ```lua camera.capture({ quality = "high", facing = "back" }, function(result) if result.success then local imageData = result.data end end) ``` **Restrictions:** - User prompt before first access - Cannot record video (photo only) --- ### microphone **Description:** Record audio from the device microphone. **Use cases:** - Voice notes - Audio messages - Voice commands **API access:** ```lua microphone.start() microphone.stop(function(result) local audioData = result.data end) ``` **Restrictions:** - User prompt before first access - Maximum recording duration enforced --- ### location **Description:** Access device location information. **Use cases:** - Weather apps - Maps - Location-based features **API access:** ```lua location.get(function(result) if result.success then print(result.latitude, result.longitude) end end) location.watch(function(result) -- Called on location changes end) ``` **Restrictions:** - User prompt before first access - Approximate location only (no precise GPS) - Battery impact warning --- ### contacts **Description:** Read device contacts. **Use cases:** - Contact picker - Address book integration - Sharing with friends **API access:** ```lua contacts.pick(function(result) if result.success then print(result.name, result.phone) end end) contacts.getAll(function(result) for i, contact in ipairs(result.contacts) do print(contact.name) end end) ``` **Restrictions:** - Read-only access - User prompt before first access ## Permission Levels | Level | Description | Example | |-------|-------------|---------| | **Normal** | Low risk, minimal review | storage | | **Sensitive** | Requires user prompt | camera, microphone, location | | **Dangerous** | Extensive review required | contacts | ## Runtime Behavior ### First-Time Prompts Some permissions trigger a user prompt on first use: ```lua -- First call triggers prompt camera.capture(options, function(result) if result.denied then -- User denied permission showPermissionExplanation() elseif result.success then -- Permission granted handlePhoto(result.data) end end) ``` ### Checking Permission Status ```lua -- Check if permission is granted if permissions.check("camera") then -- Already have permission showCameraButton() else -- Need to request showRequestButton() end ``` ### Requesting at Runtime ```lua permissions.request("camera", function(granted) if granted then startCamera() else showAlternative() end end) ``` ## Best Practices ### 1. Minimize Permissions Only request what you need. An app with fewer permissions: - Builds more user trust - Passes review faster - Has smaller attack surface ### 2. Request at the Right Time Don't request all permissions at startup. Request when the user takes an action that needs it: ```lua -- Bad: Request on app start function onAppStart() permissions.request("camera") -- Why? end -- Good: Request when needed function onTakePhotoClicked() permissions.request("camera", function(granted) if granted then camera.capture(options, handlePhoto) end end) end ``` ### 3. Explain Why Tell users why you need a permission before requesting: ```xml ``` ### 4. Handle Denial Gracefully Apps should work (with reduced functionality) even if permissions are denied: ```lua function capturePhoto() if not permissions.check("camera") then -- Offer alternative showManualEntryOption() return end -- Proceed with camera end ``` ### 5. Don't Ask Again Immediately If a user denies a permission, don't immediately ask again: ```lua local lastDenied = storage.get("camera_denied_time") if lastDenied and os.time() - lastDenied < 86400 then -- Wait at least 24 hours before asking again return end ``` ## Review Impact Permission requests affect app review: | Permission | Review Impact | |------------|---------------| | storage, network | Automatic approval | | clipboard | Quick review | | notifications | Standard review | | camera, microphone | Extended review | | location | Extended review | | contacts | Manual review required | Apps requesting sensitive permissions must: 1. Justify the need in submission notes 2. Use the permission appropriately 3. Respect user privacy ## Troubleshooting ### "Permission not declared" ``` Error: Cannot use camera without 'camera' permission ``` Add the permission to your manifest: ```json "permissions": ["camera"] ``` ### "Permission denied by user" Handle this gracefully in your code: ```lua if result.denied then showAlternativeUI() end ``` ### "Permission blocked" The user permanently blocked the permission. Direct them to settings: ```lua if result.blocked then showMessage("Please enable camera in system settings") end ``` ## See Also - [Manifest Reference](../api/manifest.md) - Full manifest documentation - [Security Guide](security.md) - App security best practices - [Publishing Guide](publishing.md) - App review process