
Din Mac-app får adgang til mikrofonen — og glemmer det så hver gang du åbner den
GeekBye bad om mikrofontilladelse, du gav den, og det virkede. Næste gang du åbnede appen: væk. Og appen dukkede aldrig op i Systemindstillinger → Mikrofon overhovedet. Skurken var en macOS-sikkerhedsfunktion, der stille og roligt kørte appen fra en sti, som forsvinder — her er diagnosen og den ét-klik-løsning.
Her er en fejl, der får dig til at tvivle på dine egne øjne. Du installerer GeekBye, den beder om adgang til mikrofonen, du klikker Allow, og transskriptionen virker. Fint. Du lukker den, åbner den igen næste morgen — og den beder om mikrofonadgang igen. Du går ind for at tjekke Systemindstillinger → Anonymitet og sikkerhed → Mikrofon for at rette det manuelt, og GeekBye er ikke engang på listen. Ikke nægtet. Ikke tilladt. Bare fraværende, som om den aldrig havde spurgt.
Hver enkelt brik så korrekt ud. Prompten var ægte. Tilladelsen virkede i øjeblikket. Appen var korrekt signeret og notariseret med de rigtige brugsstrenge. Og alligevel fordampede tilladelsen ved hver opstart. GeekBye v2.0.6 rettede den — og den underliggende årsag er en af de mest snigende ting, macOS gør for at beskytte dig.
Funktionen, der skjulte appen for sig selv
Skurken er macOS App Translocation, en Gatekeeper-sikkerhedsfunktion. Når du henter en app og kører den direkte fra DMG'en eller fra din ~/Downloads-mappe — et hvilket som helst sted, hvor den stadig er i "karantæne" — kører macOS den faktisk ikke fra det sted, du ser den. Den kopierer den gennemsigtigt til en tilfældig, skrivebeskyttet sti dybt under /private/var/folders/.../AppTranslocation/… og kører den kopi. Det er et godt forsvar: det forhindrer en ondsindet download i at manipulere med filer ved siden af sig selv.
Men her er konflikten. macOS' tilladelsessystem (TCC — det, der holder styr på, hvem der må bruge din mikrofon, dit kamera og din skærm) identificerer en app ud fra dens sti og kodeidentitet. Når appen er translokeret, er den sti tilfældig og midlertidig. Så når du giver mikrofonadgang, registrerer macOS pligtskyldigt tilladelsen — mod en sti, der ikke findes næste gang appen åbnes. Åbn appen igen, macOS translokerer den til en anden tilfældig sti, ser en app, den ikke har nogen oplysninger om, og spørger igen. Og fordi den spøgelsessti aldrig er en stabil placering, får appen aldrig en permanent række i Systemindstillinger → Mikrofon.
Appen gav tilladelse til et spøgelse.
Det er også derfor, kun nogle folk ramte den. Hvis din kopi af GeekBye allerede lå i /Applications — fordi du trak den derhen, eller fordi den kom derhen via automatisk opdatering — er der ingen karantæne, ingen translokation, en stabil sti, og alt bevares perfekt. Fejlen var usynlig for os og for alle, der var forbi deres første installation, hvilket er præcis den slags fejl, der overlever længst.
Løsningen: giv appen et rigtigt hjem
Da hele problemet er en ustabil sti, er løsningen at få appen over på en stabil en. v2.0.6 registrerer, når GeekBye kører translokeret (eller bare kører uden for /Applications) og tilbyder et ét-klik "Move to Applications" (flyt til Programmer) — ved hjælp af det macOS-relokeringskald, der kopierer bundtet ind i /Applications og genstarter det derfra. Fra det tidspunkt har appen en fast identitet: mikrofontilladelsen bliver hængende, skærmoptagelse bliver hængende, og GeekBye dukker endelig op i Systemindstillinger, hvor du ville forvente det.
Prompten er høflig omkring det. Den tilbyder Move to Applications (flyt til Programmer), Not Now (ikke nu) og Don't Ask Again (spørg ikke igen) — og den husker det sidste valg, så appen aldrig plager nogen, der har en bevidst grund til at køre den fra et andet sted. Beslutningen om, hvorvidt prompten overhovedet skal vises, er isoleret i små, rene funktioner (er dette build translokeret? er det uden for /Applications? har brugeren undertrykt det?), så logikken kan enhedstestes uden at skulle starte et rigtigt notariseret build på et rigtigt karantæne-volumen.
Den samme udgivelse forenklede også selve tilladelsesoplevelsen. GeekBye plejede at åbne et brugerdefineret, specialbygget tilladelsesvindue inde i appen — nogle få hundrede linjer UI, der forsøgte at gengive noget, operativsystemet allerede gør godt. v2.0.6 slettede det og lænede sig op ad den native macOS-tilladelsesprompt, understøttet af en stille, ikke-blokerende banner, der kun vises, når en påkrævet tilladelse faktisk mangler. Mindre kode, og en adfærd brugerne allerede genkender, fordi alle andre Mac-apps fungerer på samme måde.
Den del, jeg er mest stolt af: vi beviste det, før vi troede på det
Det havde været nemt at gætte translokation og sende en rettelse. I stedet sendte udgivelsen en opstartsdiagnostik først: ved opstart rapporterer GeekBye nu sin egen sti til den eksekverbare fil og hvorvidt den er translokeret, hvorvidt den er inde i /Applications, samt den aktuelle status for mikrofon- og skærmtilladelser. Den telemetri gjorde en plausibel teori til en bekræftet: produktionsdata viste, at de berørte sessioner faktisk kørte fra translokerede stier uden for /Applications, præcis som forudsagt.
Den rækkefølge betyder noget. "Prompten dukker op, men tilladelsen bliver ikke hængende" har flere mulige forklaringer — et signeringsproblem, en manglende brugsstreng, et entitlement-problem, en finurlighed i TCC-databasen. Vi udelukkede årsagerne på API-niveau (anmodningsstien var påviseligt korrekt) og lod så virkelige data pege på identitets-/stilaget i stedet for at sende en håbefuld rettelse og håbe, at supporthenvendelserne stoppede.
Tre ting denne fejl lærer
- En tilladelse, der prompter, men ikke bliver hængende, er et identitets_problem, ikke et _API-problem. Hvis anmodningskoden er korrekt, og tilladelsen alligevel forsvinder, så hold op med at omskrive anmodningen. Spørg, hvilken sti og kodeidentitet operativsystemet binder tilladelsen til — og hvorvidt den identitet er stabil på tværs af opstarter.
- Send diagnostikken med (eller før) rettelsen. Nogle få felter — hvor kører jeg fra, hvad er min tilladelsesstatus — forvandlede et kvalificeret gæt til en verificeret rodårsag og fortalte os præcis, hvilke brugere der var berørt. Instrumentér den grænse, du har mistanke om, før du lapper den.
- De fejl, der skjuler sig for udviklerne, er dem, der kører i det "forkerte" miljø. Vores boede i
/Applicationspå hver eneste udviklermaskine, så fejlen var strukturelt usynlig for os, mens den ramte førstegangsbrugere. Når en fejlrapport ikke kan reproduceres, er det første spørgsmål hvad er anderledes ved det sted, den kører, ikke tager brugeren fejl.
GeekBye v2.0.6 sendte relokeringsprompten og diagnostikken sammen. For den bredere pålidelighedsbue, som dette indgår i, se hvad en version 2 faktisk kræver (v2.0.0) og hvorfor skærmoptagelse fanger den forkerte skærm (v2.0.10) — endnu en fejl, der kun dukkede op i et specifikt miljø. For den detaljeorienterede udgivelse ved siden af, rolig software: flimmer-rettelsen og svar-tilstands-chippen (v2.0.3 + v2.0.5).