How Meetily Handles Audio Permissions Across macOS, Windows, and Linux
Meetily handles audio permissions through a centralized Rust module that checks platform-specific requirements—microphone and screen recording on macOS, WASAPI access on Windows, and ALSA/PulseAudio group membership on Linux—before allowing any audio capture to begin.
The open-source meeting assistant Meetily (Zackriya-Solutions/meetily) implements a cross-platform permission system to ensure compliant audio capture across operating systems. The architecture delegates permission requests to platform-specific modules while maintaining a unified interface for the frontend. This design prevents unauthorized recording by validating system-level consents before initializing the audio pipeline.
Platform-Specific Permission Architecture
Meetily's permission logic resides in frontend/src-tauri/src/audio/permissions.rs, which acts as a platform abstraction layer. The module implements conditional compilation to invoke OS-specific checks before granting recording access.
macOS: Microphone and Screen Recording
On macOS, the system requires explicit user consent for both microphone access and screen recording (for system audio capture). The permissions.rs module calls request_microphone_permission() to trigger the standard AVAudioSession prompt, then executes the Swift helper script frontend/src-tauri/check_screen_permission.swift to request screen recording privileges.
The Swift implementation uses the AXIsProcessTrustedWithOptions API to display the system permission dialog:
// frontend/src-tauri/check_screen_permission.swift
import Cocoa
let options = [kAXTrustedCheckOptionPrompt.takeRetainedValue() as String: true] as CFDictionary
let trusted = AXIsProcessTrustedWithOptions(options)
exit(trusted ? 0 : 1)
Device-level handling is managed in frontend/src-tauri/src/audio/devices/platform/macos.rs, which integrates with ScreenCaptureKit for system audio routing.
Windows: WASAPI Access Control
Windows handles microphone permissions through the Windows Audio Session API (WASAPI). The implementation in frontend/src-tauri/src/audio/devices/platform/windows.rs utilizes IMMDeviceEnumerator to enumerate audio devices. When the application attempts to access a capture device, Windows automatically triggers the system permission prompt if the user has not previously granted access.
If the OS denies access, the Rust code surfaces the error through the Tauri command layer, allowing the frontend to display an appropriate message.
Linux: ALSA and PulseAudio Group Requirements
Linux systems do not display modal permission dialogs for audio access. Instead, the implementation in frontend/src-tauri/src/audio/devices/platform/linux.rs attempts to open the default ALSA or PulseAudio device. Success depends on the user belonging to the audio group or having appropriate PolicyKit configurations.
The permission check validates device accessibility before initializing the capture stream, returning a clear error if the user lacks sufficient privileges.
Permission Flow from Frontend to Backend
The permission verification occurs automatically when the user initiates a recording. The React frontend invokes the start_recording command, which triggers a chain of permission checks before starting the audio pipeline.
Frontend Integration
The usePermissionCheck hook in frontend/src/hooks/usePermissionCheck.ts provides the UI with permission status and request methods:
import { invoke } from '@tauri-apps/api/tauri';
import { usePermissionCheck } from '@/hooks/usePermissionCheck';
const start = async () => {
const { hasPermission, requestPermission } = usePermissionCheck();
if (!hasPermission) {
await requestPermission();
}
try {
await invoke('start_recording', {
mic_device_name: 'Built-in Microphone',
system_device_name: 'BlackHole 2ch',
meeting_name: 'Team Sync',
});
} catch (e) {
console.error('Failed to start recording:', e);
}
};
Backend Permission Orchestration
The start_recording command defined in frontend/src-tauri/src/audio/recording_commands.rs calls audio::permissions::ensure_permissions() before initializing the capture pipeline. This function uses conditional compilation to execute platform-specific checks:
// frontend/src-tauri/src/audio/permissions.rs
pub async fn ensure_permissions() -> Result<(), String> {
#[cfg(target_os = "macos")]
{
macos::request_microphone_permission().await?;
macos::request_screen_recording_permission().await?;
}
#[cfg(target_os = "windows")]
{
windows::ensure_wasapi_access().await?;
}
#[cfg(target_os = "linux")]
{
linux::ensure_alsa_or_pulse_access().await?;
}
Ok(())
}
If any permission check fails, the function returns an error immediately, preventing the audio pipeline from starting and ensuring no unauthorized capture occurs.
Key Source Files
Summary
- Centralized enforcement: All recording operations must pass through
permissions.rs, ensuring consistent permission validation across platforms. - macOS dual requirements: The system explicitly requests both microphone and screen recording permissions using native Swift APIs before capturing system audio.
- Windows implicit prompts: WASAPI access relies on Windows' built-in permission dialogs triggered during device enumeration.
- Linux group-based access: Permission validation checks for ALSA/PulseAudio device accessibility, requiring proper user group membership rather than modal dialogs.
- Fail-fast architecture: Permission checks occur before audio pipeline initialization, preventing partial recordings or unauthorized captures.
Frequently Asked Questions
Why does Meetily require screen recording permission on macOS?
macOS routes system audio through virtual audio devices that require screen recording entitlements. The check_screen_permission.swift script invokes AXIsProcessTrustedWithOptions to trigger the system dialog, ensuring compliance with Apple's privacy requirements for capturing computer audio.
How does Meetily handle permission denials on Windows?
When Windows denies WASAPI access, the windows.rs module returns an error through the Tauri command layer. The frontend receives this error and displays a notification directing the user to enable microphone access in Windows Privacy settings, preventing the recording from starting without proper authorization.
What Linux configuration is required for Meetily to access audio?
Meetily requires the user to belong to the audio group or have equivalent PolicyKit permissions to access ALSA or PulseAudio devices. The linux.rs implementation attempts to open the default device and returns a permission error if the system denies access, prompting the user to configure their audio group membership.
Can Meetily record audio if permissions are granted after the app starts?
Yes. The ensure_permissions() function in permissions.rs executes dynamically when the user initiates recording. If permissions were previously denied, the user can grant them via system settings and retry—the permission check runs fresh on each start_recording invocation, allowing runtime permission changes without restarting the application.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →