7.5 KiB
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:
- Informing users what an app can access before installation
- Limiting damage if an app misbehaves
- Maintaining trust in the Mosis ecosystem
Declaring Permissions
Add permissions to your manifest.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:
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:
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:
clipboard.write(text)
clipboard.read(callback)
notifications
Description: Display system notifications to the user.
Use cases:
- Reminders
- Alerts
- Background updates
API access:
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:
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:
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:
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:
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:
-- 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
-- Check if permission is granted
if permissions.check("camera") then
-- Already have permission
showCameraButton()
else
-- Need to request
showRequestButton()
end
Requesting at Runtime
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:
-- 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:
<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:
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:
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:
- Justify the need in submission notes
- Use the permission appropriately
- Respect user privacy
Troubleshooting
"Permission not declared"
Error: Cannot use camera without 'camera' permission
Add the permission to your manifest:
"permissions": ["camera"]
"Permission denied by user"
Handle this gracefully in your code:
if result.denied then
showAlternativeUI()
end
"Permission blocked"
The user permanently blocked the permission. Direct them to settings:
if result.blocked then
showMessage("Please enable camera in system settings")
end
See Also
- Manifest Reference - Full manifest documentation
- Security Guide - App security best practices
- Publishing Guide - App review process