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

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:

  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:

{
  "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:

  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:

"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