Files
MosisService/portal/internal/web/docs/guides/permissions.md

397 lines
7.5 KiB
Markdown

# 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
<div id="permission-explanation" style="display: none;">
<p>This app needs camera access to scan QR codes.</p>
<button onclick="requestCamera()">Enable Camera</button>
</div>
```
### 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