# How Meetily Handles Audio Permissions Across macOS, Windows, and Linux

> Discover how Meetily manages audio permissions on macOS, Windows, and Linux using a central Rust module that ensures platform-specific requirements are met for seamless audio capture.

- Repository: [Zackriya Solutions/meetily](https://github.com/Zackriya-Solutions/meetily)
- Tags: how-to-guide
- Published: 2026-07-28

---

**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`](https://github.com/Zackriya-Solutions/meetily/blob/main/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`](https://github.com/Zackriya-Solutions/meetily/blob/main/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`](https://github.com/Zackriya-Solutions/meetily/blob/main/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:

```swift
// 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`](https://github.com/Zackriya-Solutions/meetily/blob/main/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`](https://github.com/Zackriya-Solutions/meetily/blob/main/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`](https://github.com/Zackriya-Solutions/meetily/blob/main/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`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src/hooks/usePermissionCheck.ts) provides the UI with permission status and request methods:

```tsx
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`](https://github.com/Zackriya-Solutions/meetily/blob/main/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:

```rust
// 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

| File | Purpose | Location |
|------|---------|----------|
| [`permissions.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/permissions.rs) | Central permission orchestrator with platform abstraction | [[`frontend/src-tauri/src/audio/permissions.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/permissions.rs)](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/permissions.rs) |
| [`check_screen_permission.swift`](https://github.com/Zackriya-Solutions/meetily/blob/main/check_screen_permission.swift) | macOS screen recording prompt helper | [[`frontend/src-tauri/check_screen_permission.swift`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/check_screen_permission.swift)](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/check_screen_permission.swift) |
| [`macos.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/macos.rs) | macOS-specific device handling and permission requests | [[`frontend/src-tauri/src/audio/devices/platform/macos.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/devices/platform/macos.rs)](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/devices/platform/macos.rs) |
| [`windows.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/windows.rs) | Windows WASAPI implementation and access validation | [[`frontend/src-tauri/src/audio/devices/platform/windows.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/devices/platform/windows.rs)](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/devices/platform/windows.rs) |
| [`linux.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/linux.rs) | Linux ALSA/PulseAudio device access logic | [[`frontend/src-tauri/src/audio/devices/platform/linux.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/devices/platform/linux.rs)](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/devices/platform/linux.rs) |
| [`recording_commands.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/recording_commands.rs) | Tauri command handlers that invoke permission checks | [[`frontend/src-tauri/src/audio/recording_commands.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/recording_commands.rs)](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/recording_commands.rs) |
| [`usePermissionCheck.ts`](https://github.com/Zackriya-Solutions/meetily/blob/main/usePermissionCheck.ts) | React hook for frontend permission state management | [[`frontend/src/hooks/usePermissionCheck.ts`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src/hooks/usePermissionCheck.ts)](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src/hooks/usePermissionCheck.ts) |

## Summary

- **Centralized enforcement**: All recording operations must pass through [`permissions.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/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`](https://github.com/Zackriya-Solutions/meetily/blob/main/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`](https://github.com/Zackriya-Solutions/meetily/blob/main/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`](https://github.com/Zackriya-Solutions/meetily/blob/main/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`](https://github.com/Zackriya-Solutions/meetily/blob/main/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.