# Macos Permissions

> macOS permission handling for Accessibility (AXIsProcessTrusted), Screen Recording, Full Disk Access, input monitoring, camera, microphone, location, and contacts. Covers TCC (Transparency Consent and Control) database, graceful degradation when permissions are denied, permission prompting patterns, opening System Settings to the correct pane, detecting permission changes, and the privacy manifes…

- **Type:** Skill
- **Install:** `agentstack add skill-makgunay-claude-swift-skills-macos-permissions`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [makgunay](https://agentstack.voostack.com/s/makgunay)
- **Installs:** 0
- **Category:** [Databases](https://agentstack.voostack.com/c/databases)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [makgunay](https://github.com/makgunay)
- **Source:** https://github.com/makgunay/claude-swift-skills/tree/main/macos-permissions

## Install

```sh
agentstack add skill-makgunay-claude-swift-skills-macos-permissions
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# macOS Permissions

## Critical Constraints

- ❌ DO NOT assume permissions are granted → ✅ Always check before using protected APIs
- ❌ DO NOT repeatedly prompt after denial → ✅ Guide user to System Settings instead
- ❌ DO NOT block the entire app on missing permission → ✅ Gracefully degrade, offer reduced functionality
- ❌ DO NOT forget PrivacyInfo.xcprivacy → ✅ Required for App Store submission

## Permission Types

| Permission | Check API | Required For |
|------------|-----------|-------------|
| Accessibility | `AXIsProcessTrusted()` | Global hotkeys, text insertion, CGEvent |
| Screen Recording | `CGPreflightScreenCaptureAccess()` | Screen capture, window list |
| Full Disk Access | Try access + handle error | Reading other app data |
| Camera | `AVCaptureDevice.authorizationStatus(for: .video)` | Camera access |
| Microphone | `AVCaptureDevice.authorizationStatus(for: .audio)` | Audio capture |
| Location | `CLLocationManager().authorizationStatus` | Location services |
| Contacts | `CNContactStore.authorizationStatus(for: .contacts)` | Contact access |

## Accessibility Permission
```swift
import ApplicationServices

// Check without prompting
func isAccessibilityGranted() -> Bool {
    AXIsProcessTrusted()
}

// Check and prompt user (shows system dialog)
func requestAccessibilityPermission() -> Bool {
    let options = [kAXTrustedCheckOptionPrompt.takeRetainedValue() as String: true]
    return AXIsProcessTrustedWithOptions(options as CFDictionary)
}

// Open System Settings → Privacy → Accessibility
func openAccessibilitySettings() {
    NSWorkspace.shared.open(URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility")!)
}
```

## Screen Recording Permission
```swift
import CoreGraphics

// Check (macOS 15+)
func isScreenRecordingGranted() -> Bool {
    CGPreflightScreenCaptureAccess()
}

// Request (macOS 15+)
func requestScreenRecording() -> Bool {
    CGRequestScreenCaptureAccess()
}

// Open Settings
func openScreenRecordingSettings() {
    NSWorkspace.shared.open(URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture")!)
}
```

## Camera / Microphone
```swift
import AVFoundation

func checkCameraPermission() async -> Bool {
    switch AVCaptureDevice.authorizationStatus(for: .video) {
    case .authorized: return true
    case .notDetermined: return await AVCaptureDevice.requestAccess(for: .video)
    case .denied, .restricted: return false
    @unknown default: return false
    }
}
```

## Graceful Degradation Pattern
```swift
struct FeatureAvailability {
    var canInsertText: Bool { AXIsProcessTrusted() }
    var canUseGlobalHotkey: Bool { AXIsProcessTrusted() }
    var canCaptureScreen: Bool { CGPreflightScreenCaptureAccess() }

    var degradedFeatures: [String] {
        var features: [String] = []
        if !canInsertText { features.append("Text insertion into other apps") }
        if !canUseGlobalHotkey { features.append("Global keyboard shortcuts") }
        return features
    }
}

struct PermissionBanner: View {
    let availability: FeatureAvailability

    var body: some View {
        if !availability.degradedFeatures.isEmpty {
            VStack(alignment: .leading, spacing: 8) {
                Label("Some features require permissions", systemImage: "lock.shield")
                    .font(.headline)
                ForEach(availability.degradedFeatures, id: \.self) { feature in
                    Text("• \(feature)")
                        .font(.caption)
                }
                Button("Open System Settings") { openAccessibilitySettings() }
                    .buttonStyle(.borderedProminent)
            }
            .padding()
            .glassEffect(.regular.tint(.orange), in: .rect(cornerRadius: 12))
        }
    }
}
```

## Permission Onboarding Flow
```swift
struct OnboardingPermissionView: View {
    @State private var accessibilityGranted = AXIsProcessTrusted()
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

    var body: some View {
        VStack(spacing: 20) {
            Image(systemName: accessibilityGranted ? "checkmark.circle.fill" : "lock.circle")
                .font(.system(size: 48))
                .foregroundStyle(accessibilityGranted ? .green : .orange)

            Text(accessibilityGranted ? "Permission Granted!" : "Accessibility Permission Required")
                .font(.title2)

            if !accessibilityGranted {
                Text("This app needs Accessibility access to insert text into other apps and register global shortcuts.")
                    .multilineTextAlignment(.center)

                Button("Open System Settings") {
                    requestAccessibilityPermission()
                }
                .buttonStyle(.borderedProminent)
            }
        }
        .onReceive(timer) { _ in
            accessibilityGranted = AXIsProcessTrusted()
        }
    }
}
```

## Privacy Manifest (PrivacyInfo.xcprivacy)
```xml

    NSPrivacyTracking
    
    NSPrivacyTrackingDomains
    
    NSPrivacyCollectedDataTypes
    
    NSPrivacyAccessedAPITypes
    
        
            NSPrivacyAccessedAPIType
            NSPrivacyAccessedAPICategoryUserDefaults
            NSPrivacyAccessedAPITypeReasons
            CA92.1
        
    

```

## Common Mistakes & Fixes

| Mistake | Fix |
|---------|-----|
| Prompting repeatedly after denial | Check status first, guide to Settings if denied |
| App crashes without permission | Always check before calling protected API |
| User can't find permission setting | Open specific System Settings pane via URL |
| Missing privacy manifest | Add PrivacyInfo.xcprivacy to app bundle |

## References

- [Accessibility API](https://developer.apple.com/documentation/applicationservices/axuielement_h)
- [TCC and Privacy](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files)

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [makgunay](https://github.com/makgunay)
- **Source:** [makgunay/claude-swift-skills](https://github.com/makgunay/claude-swift-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** yes
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-makgunay-claude-swift-skills-macos-permissions
- Seller: https://agentstack.voostack.com/s/makgunay
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
