C.W.K.
Stream
Lesson 01 of 05 · published

무서운 권한 둘

~11 min · permissions, tcc, accessibility, microphone

Level 0불씨 없음
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"내가 말하는 전부를 듣고, 내가 쓰는 모든 앱에 타이핑할 수 있어라." 다시 읽어봐, 그게 받아쓰기 도구와 키로거 둘 다의 스펙이란 걸 알아채.

요청

Firekeeper 는 사려 깊은 유저를 멈칫하게 해야 하는 권한 둘이 필요해. 마이크 — 널 들을 수 있어. 접근성 — 다른 앱의 포커스된 요소를 읽고 거기 작동할 수 있어. 모든 받아쓰기 앱이 정확히 이게 필요하고, 멀웨어도 그래. 필요를 없애는 똑똑한 아키텍처는 없어; 말하는 걸 타이핑하는 도구는 듣고 타이핑할 수 있어야 해. 통제할 수 있는 건 그 너머론 아무것도 요청 안 하는 것, 그리고 허가를 정당화하는 방식으로 행동하는 거야.

권한 표면은 설계 산출물

마이크             필수        -- 널 들어야 함
접근성             필수        -- 선택, 타깃 맥락, 튼튼한 삽입
Input Monitoring   회피됨      -- 설계가 이벤트 탭 대신 flagsChanged 고름
Automation         회피됨      -- 한 앱 프로파일이 요구 안 하면 AppleScript 없음
네트워크           스코프됨    -- 네가 고른 프로바이더만, 기본값으론 절대 아님

Input Monitoring 이 사업 비용으로 받아들여진 게 아니라 회피됐다 는 걸 봐. 앞선 단축키 결정이 여기서 배당금을 내는 거야: 활성화가 이벤트 스트림을 가로채는 대신 모디파이어 플래그를 관찰하니, 앱이 '모든 키 입력을 봐도 돼?' 를 물을 일이 없어. 권한 표면은 기능 목록으로 고정된 게 아니라 — 아키텍처의 산출물이고, 줄이도록 설계할 수 있어.

솔직하게, 그리고 일찍 물어

습관 둘이 요청을 공정하게 만들어. 첫째, 받아쓰기 중간에 유저를 기습하는 대신 실행 때 마이크를 요청해 — 말하기 시작하는 순간 뜨는 권한 프롬프트는 놀랍고 첫 단어를 놓치는 걸 보장해. 둘째, 상태를 읽을 수 있게 만들어: 맞는 시스템 설정 창을 여는 버튼과 함께 실시간 권한 상태를 보여주는 Setup 패널, 그래서 유저가 뭘 줬는지 늘 알고 취소할 수 있게. 뭘 쥐고 있는지 애매하게 구는 앱은 그걸 쥘 자격이 있단 논쟁을 이미 진 거야.

권한 표면은 발견되는 게 아니라 설계돼. 기능이 무서운 허가를 요구한다고 받아들이기 전에, 다른 구현이 더 작은 요청으로 같은 인터랙션을 주는지 물어. Firekeeper 의 맨-Fn 홀드와 키로거급 이벤트 탭이 같은 UX 를 줘; 둘 중 하나만 '모든 키 입력 보기' 를 요구해. 인터랙션은 지킬 값어치가 있었고; 권한은 아니었어.
넌 멀웨어랑 같은 능력을 요청하고 있어. 과장이 아니고 방어적이 될 이유도 아냐 — 엄격해질 이유야. 이 트랙의 모든 것(무보존, 보안-필드 거부, 보이는 녹음, 전송 전 프로바이더 선택)이 존재하는 건 '이 앱이 스파이웨어일 수 있어' 에 대한 솔직한 답이 안심시키기가 아니라 유저가 검증할 수 있는 아키텍처라서야.

Code

일찍 묻고, 상태를 드러내고, 여분을 안 쥠·swift
func applicationDidFinishLaunching() {
    // 실행 때 물음 — 발화 중간에 유저를 절대 기습 안 하고,
    // 권한 시트에 첫 단어를 절대 안 잃음.
    AVCaptureDevice.requestAccess(for: .audio) { _ in }

    // 접근성은 선택 + 튼튼한 삽입에 필수.
    // 드러내; 조용히 격하돼 유저가 추측하게 두지 마.
    let trusted = AXIsProcessTrustedWithOptions(
        [kAXTrustedCheckOptionPrompt.takeUnretainedValue(): true] as CFDictionary)
    setupPanel.accessibilityGranted = trusted
}

// 없는 걸 봐: Input Monitoring 요청 없음, Automation 없음.
// 단축키 설계가 그것들을 불필요하게 만들었어.

External links

Exercise

네가 쓰는 앱이 요청하는 권한을 나열해. 각각에 대해 물어: 이게 기능이 진짜 요구하는 거야, 아니면 개발자가 고른 특정 구현이 요구하는 거야? 다른 설계가 요청을 줄였을 곳 하나와, 요청이 진짜 줄일 수 없는 곳 하나를 찾아.
Hint
줄일 수 없는 요청은 제품의 본질에서 곧장 와(받아쓰기 도구는 널 들어야 해). 줄일 수 있는 건 구현 편의에서 와 — 좁은 API 보다 넓은 게 쉬웠던 거지. 구별이 중요한 건 유저가 밖에서 둘을 구별 못 하니까, 유지하는 모든 줄일 수 있는 권한이 안 써도 됐을 신뢰를 쓰는 거야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.