

{"id":12940,"date":"2021-02-07T13:15:44","date_gmt":"2021-02-07T18:15:44","guid":{"rendered":"https:\/\/rud.is\/b\/?p=12940"},"modified":"2021-02-07T13:15:44","modified_gmt":"2021-02-07T18:15:44","slug":"getting-a-handle-on-macos-app-entitlements-with-r","status":"publish","type":"post","link":"https:\/\/rud.is\/b\/2021\/02\/07\/getting-a-handle-on-macos-app-entitlements-with-r\/","title":{"rendered":"Getting a Handle on macOS App Entitlements with R"},"content":{"rendered":"<p>If you&#8217;ve been following me around the internets for a while you&#8217;ve likely heard me pontificate about the need to be aware of and reduce \u2014 when possible \u2014 your personal &#8220;cyber&#8221; attack surface. One of the ways you can do that is to install as few applications as possible onto your devices and make sure you have a decent handle on those you&#8217;ve kept around are doing or capable of doing.<\/p>\n<p>On macOS, one application attribute you can look at is the set of &#8220;entitlements&#8221; apps have asked for and that you have actioned on (i.e. either granted or denied the entitlement request). If you have Developer Tools or Xcode installed you can use the <code>codesign<\/code> utility (it may be usable w\/o the developer tools, but I never run without them so drop a note in the comments if you can confirm this) to see them:<\/p>\n<pre><code class=\"language-shell\">$ codesign -d --entitlements :- \/Applications\/RStudio.app\nExecutable=\/Applications\/RStudio.app\/Contents\/MacOS\/RStudio\n&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\n&lt;!DOCTYPE plist PUBLIC \"-\/\/Apple Computer\/\/DTD PLIST 1.0\/\/EN\" \"http:\/\/www.apple.com\/DTDs\/PropertyList-1.0.dtd\"&gt;\n&lt;plist version=\"1.0\"&gt;\n&lt;dict&gt;\n\n  &lt;!-- Required by R packages which want to access the camera. --&gt;\n  &lt;key&gt;com.apple.security.device.camera&lt;\/key&gt;\n  &lt;true\/&gt;\n\n  &lt;!-- Required by R packages which want to access the microphone. --&gt;\n  &lt;key&gt;com.apple.security.device.audio-input&lt;\/key&gt;\n  &lt;true\/&gt;\n\n  &lt;!-- Required by Qt \/ Chromium. --&gt;\n  &lt;key&gt;com.apple.security.cs.disable-library-validation&lt;\/key&gt;\n  &lt;true\/&gt;\n  &lt;key&gt;com.apple.security.cs.disable-executable-page-protection&lt;\/key&gt;\n  &lt;true\/&gt;\n\n  &lt;!-- We use DYLD_INSERT_LIBRARIES to load the libR.dylib dynamically. --&gt;\n  &lt;key&gt;com.apple.security.cs.allow-dyld-environment-variables&lt;\/key&gt;\n  &lt;true\/&gt;\n\n  &lt;!-- Required to knit to Word --&gt;\n  &lt;key&gt;com.apple.security.automation.apple-events&lt;\/key&gt;\n  &lt;true\/&gt;\n\n&lt;\/dict&gt;\n&lt;\/plist&gt;\n<\/code><\/pre>\n<p>The output is (ugh) XML, and don&#8217;t think that all app developers are as awesome as RStudio ones since those comments are pseudo-optional (i.e. you can put junk in them). I&#8217;ll continue to use RStudio throughout this example just for consistency.<\/p>\n<p>Since you likely have better things to do than execute a command line tool multiple times and do significant damage to your eyes with all those pointy tags we can use R to turn the apps on our filesystem into data and examine the entitlements in a much more dignified manner.<\/p>\n<p>First, we&#8217;ll write a function to wrap the <code>codesign<\/code> tool execution (and, I&#8217;ve leaked how were going to eventually look at them by putting all the library calls up front):<\/p>\n<pre><code class=\"language-r\">library(XML)\nlibrary(tidyverse)\nlibrary(igraph)\nlibrary(tidygraph)\nlibrary(ggraph)\n\n# rewriting this to also grab the text from the comments is an exercise left to the reader\n\nread_entitlements &lt;- function(app) { \n\n  system2(\n    command = \"codesign\",\n    args = c(\n      \"-d\",\n      \"--entitlements\",\n      \":-\",\n      gsub(\" \", \"\\\\\\\\ \", app)\n    ),\n    stdout = TRUE\n  ) -&gt; x\n\n  x &lt;- paste0(x, collapse = \"\\n\")\n\n  if (nchar(x) == 0) return(tibble())\n\n  x &lt;- XML::xmlParse(x, asText=TRUE)\n  x &lt;- try(XML::readKeyValueDB(x), silent = TRUE)\n\n  if (inherits(x, \"try-error\")) return(tibble())\n\n  x &lt;- sapply(x, function(.x) paste0(.x, collapse=\";\"))\n\n  if (length(x) == 0) return(tibble())\n\n  data.frame(\n    app = basename(app),\n    entitlement = make.unique(names(x)),\n    value = I(x)\n  ) -&gt; x\n\n  x &lt;- tibble::as_tibble(x)\n\n  x\n\n} \n<\/code><\/pre>\n<p>Now, we can slurp up all the entitlements with just a few lines of code:<\/p>\n<pre><code class=\"language-r\">my_apps &lt;- list.files(\"\/Applications\", pattern = \"\\\\.app$\", full.names = TRUE)\n\nmy_apps_entitlements &lt;- map_df(my_apps, read_entitlements)\n\nmy_apps_entitlements %&gt;% \n  filter(grepl(\"RStudio\", app))\n## # A tibble: 6 x 3\n##   app         entitlement                                              value   \n##   &lt;chr&gt;       &lt;chr&gt;                                                    &lt;I&lt;chr&gt;&gt;\n## 1 RStudio.app com.apple.security.device.camera                         TRUE    \n## 2 RStudio.app com.apple.security.device.audio-input                    TRUE    \n## 3 RStudio.app com.apple.security.cs.disable-library-validation         TRUE    \n## 4 RStudio.app com.apple.security.cs.disable-executable-page-protection TRUE    \n## 5 RStudio.app com.apple.security.cs.allow-dyld-environment-variables   TRUE    \n## 6 RStudio.app com.apple.security.automation.apple-events               TRUE \n<\/code><\/pre>\n<p>Having these entitlement strings is great, but what do they mean? Unfortunately, Apple, frankly, <em>sucks<\/em> at developer documentation, and this suckage shines especially bright when it comes to documenting <em>all<\/em> the possible entitlements. We <em>can<\/em> retrieve some of them from the online documentation, so let&#8217;s do that and re-look at RStudio:<\/p>\n<pre><code class=\"language-r\"># a handful of fairly ok json URLs that back the online dev docs; they have ok, but scant entitlement definitions\nc(\n  \"https:\/\/developer.apple.com\/tutorials\/data\/documentation\/bundleresources\/entitlements.json\",\n  \"https:\/\/developer.apple.com\/tutorials\/data\/documentation\/security\/app_sandbox.json\",\n  \"https:\/\/developer.apple.com\/tutorials\/data\/documentation\/security\/hardened_runtime.json\",\n  \"https:\/\/developer.apple.com\/tutorials\/data\/documentation\/bundleresources\/entitlements\/system_extensions.json\"\n) -&gt; entitlements_info_urls\n\nextract_entitlements_info &lt;- function(x) {\n\n  apple_ents_pg &lt;- jsonlite::fromJSON(x)\n\n  apple_ents_pg$references %&gt;% \n    map_df(~{\n\n      if (!hasName(.x, \"role\")) return(tibble())\n      if (.x$role != \"symbol\") return(tibble())\n\n      tibble(\n        title = .x$title,\n        entitlement = .x$name,\n        description = .x$abstract$text %||% NA_character_\n      )\n\n    })\n\n}\n\nentitlements_info_urls %&gt;% \n  map(extract_ents_info) %&gt;% \n  bind_rows() %&gt;% \n  distinct() -&gt; apple_entitlements_definitions\n\n# look at rstudio again ---------------------------------------------------\n\nmy_apps_entitlements %&gt;% \n  left_join(apple_entitlements_definitions) %&gt;% \n  filter(grepl(\"RStudio\", app)) %&gt;% \n  select(title, description)\n## Joining, by = \"entitlement\"\n## # A tibble: 6 x 2\n##   title                            description                                                       \n##   &lt;chr&gt;                            &lt;chr&gt;                                                             \n## 1 Camera Entitlement               A Boolean value that indicates whether the app may capture movies\u2026\n## 2 Audio Input Entitlement          A Boolean value that indicates whether the app may record audio u\u2026\n## 3 Disable Library Validation Enti\u2026 A Boolean value that indicates whether the app may load arbitrary\u2026\n## 4 Disable Executable Memory Prote\u2026 A Boolean value that indicates whether to disable all code signin\u2026\n## 5 Allow DYLD Environment Variable\u2026 A Boolean value that indicates whether the app may be affected by\u2026\n## 6 Apple Events Entitlement         A Boolean value that indicates whether the app may prompt the use\u2026\n<\/code><\/pre>\n<p>It might be interesting to see what the most requested entitlements are:<\/p>\n<pre><code class=\"language-r\"><br \/>my_apps_entitlements %&gt;% \n  filter(\n    grepl(\"security\", entitlement)\n  ) %&gt;% \n  count(entitlement, sort = TRUE)\n## # A tibble: 60 x 2\n##    entitlement                                           n\n##    &lt;chr&gt;                                             &lt;int&gt;\n##  1 com.apple.security.app-sandbox                       51\n##  2 com.apple.security.network.client                    44\n##  3 com.apple.security.files.user-selected.read-write    35\n##  4 com.apple.security.application-groups                29\n##  5 com.apple.security.automation.apple-events           26\n##  6 com.apple.security.device.audio-input                19\n##  7 com.apple.security.device.camera                     17\n##  8 com.apple.security.files.bookmarks.app-scope         16\n##  9 com.apple.security.network.server                    16\n## 10 com.apple.security.cs.disable-library-validation     15\n## # \u2026 with 50 more rows\n<\/code><\/pre>\n<p>Playing in an app sandbox, talking to the internet, and handling files are unsurprising in the top three slots since that&#8217;s how most apps get stuff done for you.<\/p>\n<p>There are a few entitlements which increase your attack surface, one of which is apps that use untrusted third-party libraries:<\/p>\n<pre><code class=\"language-r\">my_apps_entitlements %&gt;% \n  filter(\n    entitlement == \"com.apple.security.cs.disable-library-validation\"\n  ) %&gt;% \n  select(app)\n## # A tibble: 15 x 1\n##    app                      \n##    &lt;chr&gt;                    \n##  1 Epic Games Launcher.app  \n##  2 GarageBand.app           \n##  3 HandBrake.app            \n##  4 IINA.app                 \n##  5 iStat Menus.app          \n##  6 krisp.app                \n##  7 Microsoft Excel.app      \n##  8 Microsoft PowerPoint.app \n##  9 Microsoft Word.app       \n## 10 Mirror for Chromecast.app\n## 11 Overflow.app             \n## 12 R.app                    \n## 13 RStudio.app              \n## 14 RSwitch.app              \n## 15 Wireshark.app \n<\/code><\/pre>\n<p>(&#8216;Tis ironic that one of Apple&#8217;s own apps is in that list.)<\/p>\n<p>What about apps that listen on the network (i.e. are also servers)?<\/p>\n<pre><code class=\"language-r\">## # A tibble: 16 x 1\n##    app                          \n##    &lt;chr&gt;                        \n##  1 1Blocker.app                 \n##  2 1Password 7.app              \n##  3 Adblock Plus.app             \n##  4 Divinity - Original Sin 2.app\n##  5 Fantastical.app              \n##  6 feedly.app                   \n##  7 GarageBand.app               \n##  8 iMovie.app                   \n##  9 Keynote.app                  \n## 10 Kindle.app                   \n## 11 Microsoft Remote Desktop.app \n## 12 Mirror for Chromecast.app    \n## 13 Slack.app                    \n## 14 Tailscale.app                \n## 15 Telegram.app                 \n## 16 xScope.app \n<\/code><\/pre>\n<p>You should read through the retrieved definitions to see what else you may want to observe to be an informed macOS app user.<\/p>\n<h3>The Big Picture<\/h3>\n<p>Looking at individual apps is great, but why not look at <em>them all<\/em>? We can build a large, but searchable network graph hierarchy if we output it as PDf, so let&#8217;s do that:<\/p>\n<pre><code class=\"language-r\"># this is just some brutish force code to build a hierarchical edge list\n\nmy_apps_entitlements %&gt;% \n  distinct(entitlement) %&gt;% \n  pull(entitlement) %&gt;% \n  stri_count_fixed(\".\") %&gt;% \n  max() -&gt; max_dots\n\nmy_apps_entitlements %&gt;% \n  distinct(entitlement, app) %&gt;% \n  separate(\n    entitlement,\n    into = sprintf(\"level_%02d\", 1:(max_dots+1)),\n    fill = \"right\",\n    sep = \"\\\\.\"\n  ) %&gt;% \n  select(\n    starts_with(\"level\"), app\n  ) -&gt; wide_hierarchy\n\nbind_rows(\n\n  distinct(wide_hierarchy, level_01) %&gt;%\n    rename(to = level_01) %&gt;%\n    mutate(from = \".\") %&gt;%\n    select(from, to) %&gt;% \n    mutate(to = sprintf(\"%s_1\", to)),\n\n  map_df(1:nrow(wide_hierarchy), ~{\n\n    wide_hierarchy[.x,] %&gt;% \n      unlist(use.names = FALSE) %&gt;% \n      na.exclude() -&gt; tmp\n\n    tibble(\n      from = tail(lag(tmp), -1),\n      to = head(lead(tmp), -1),\n      lvl = 1:length(from)\n    ) %&gt;% \n      mutate(\n        from = sprintf(\"%s_%d\", from, lvl),\n        to = sprintf(\"%s_%d\", to, lvl+1)\n      )\n\n  }) %&gt;% \n    distinct()\n\n) -&gt; long_hierarchy\n\n# all that so we can make a pretty graph! ---------------------------------\n\ng &lt;- graph_from_data_frame(long_hierarchy, directed = TRUE)\n\nggraph(g, 'partition', circular = FALSE) + \n  geom_edge_diagonal2(\n    width = 0.125, color = \"gray70\"\n  ) + \n  geom_node_text(\n    aes(\n      label = stri_replace_last_regex(name, \"_[[:digit:]]+$\", \"\")\n    ),\n    hjust = 0, size = 3, family = font_gs\n  ) +\n  coord_flip() -&gt; gg\n\n# saving as PDF b\/c it is ginormous, but very searchable\n\nquartz(\n  file = \"~\/output-tmp\/.pdf\", # put it where you want\n  width = 21,\n  height = 88,\n  type = \"pdf\",\n  family = font_gs\n)\nprint(gg)\ndev.off()\n<\/code><\/pre>\n<p>The above generates a <em>large<\/em> (dimension-wise; it&#8217;s ~&lt;5MB on disk for me) PDF graph that is barely viewable in thumnail mode:<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-01.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"12943\" data-permalink=\"https:\/\/rud.is\/b\/2021\/02\/07\/getting-a-handle-on-macos-app-entitlements-with-r\/ent-grph-01\/\" data-orig-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-01.png?fit=268%2C1036&amp;ssl=1\" data-orig-size=\"268,1036\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"ent-grph-01\" data-image-description=\"&lt;p&gt;entitlements thumbnail&lt;\/p&gt;\n\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-01.png?fit=265%2C1024&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-01.png?resize=268%2C1036&#038;ssl=1\" alt=\"\" width=\"268\" height=\"1036\" class=\"aligncenter size-full wp-image-12943\" srcset=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-01.png?w=268&amp;ssl=1 268w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-01.png?resize=265%2C1024&amp;ssl=1 265w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-01.png?resize=39%2C150&amp;ssl=1 39w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-01.png?resize=150%2C580&amp;ssl=1 150w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-01.png?resize=200%2C773&amp;ssl=1 200w\" sizes=\"auto, (max-width: 268px) 100vw, 268px\" \/><\/a><\/p>\n<p>Here are some screen captures of portions of it. First are all network servers and clients:<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"12942\" data-permalink=\"https:\/\/rud.is\/b\/2021\/02\/07\/getting-a-handle-on-macos-app-entitlements-with-r\/ent-grph-02\/\" data-orig-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?fit=1269%2C1338&amp;ssl=1\" data-orig-size=\"1269,1338\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"ent-grph-02\" data-image-description=\"&lt;p&gt;network entitlements&lt;\/p&gt;\n\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?fit=510%2C538&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?resize=510%2C538&#038;ssl=1\" alt=\"\" width=\"510\" height=\"538\" class=\"aligncenter size-full wp-image-12942\" srcset=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?w=1269&amp;ssl=1 1269w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?resize=285%2C300&amp;ssl=1 285w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?resize=530%2C559&amp;ssl=1 530w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?resize=142%2C150&amp;ssl=1 142w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?resize=768%2C810&amp;ssl=1 768w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?resize=500%2C527&amp;ssl=1 500w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?resize=150%2C158&amp;ssl=1 150w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?resize=1200%2C1265&amp;ssl=1 1200w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?resize=400%2C422&amp;ssl=1 400w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?resize=800%2C843&amp;ssl=1 800w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?resize=200%2C211&amp;ssl=1 200w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?w=1020&amp;ssl=1 1020w\" sizes=\"auto, (max-width: 510px) 100vw, 510px\" \/><\/a><\/p>\n<p>Last are seekrit entitlements only for Apple:<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-03.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"12941\" data-permalink=\"https:\/\/rud.is\/b\/2021\/02\/07\/getting-a-handle-on-macos-app-entitlements-with-r\/ent-grph-03\/\" data-orig-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-03.png?fit=1928%2C1628&amp;ssl=1\" data-orig-size=\"1928,1628\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"ent-grph-03\" data-image-description=\"&lt;p&gt;apple-only entitlements&lt;\/p&gt;\n\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-03.png?fit=510%2C431&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-03.png?resize=510%2C431&#038;ssl=1\" alt=\"\" width=\"510\" height=\"431\" class=\"aligncenter size-full wp-image-12941\" srcset=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-03.png?w=1928&amp;ssl=1 1928w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-03.png?resize=300%2C253&amp;ssl=1 300w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-03.png?resize=530%2C448&amp;ssl=1 530w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-03.png?resize=150%2C127&amp;ssl=1 150w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-03.png?resize=768%2C648&amp;ssl=1 768w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-03.png?resize=1536%2C1297&amp;ssl=1 1536w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-03.png?resize=500%2C422&amp;ssl=1 500w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-03.png?resize=1200%2C1013&amp;ssl=1 1200w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-03.png?resize=400%2C338&amp;ssl=1 400w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-03.png?resize=800%2C676&amp;ssl=1 800w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-03.png?resize=200%2C169&amp;ssl=1 200w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-03.png?w=1020&amp;ssl=1 1020w\" sizes=\"auto, (max-width: 510px) 100vw, 510px\" \/><\/a><\/p>\n<h3>FIN<\/h3>\n<p>I&#8217;ll likely put a few of these functions into {mactheknife} for easier usage.<\/p>\n<p>After going through this exercise I deleted 11 apps, some for their entitlements and others that I just never use anymore. Hopefully this will help you do some early Spring cleaning as well.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you&#8217;ve been following me around the internets for a while you&#8217;ve likely heard me pontificate about the need to be aware of and reduce \u2014 when possible \u2014 your personal &#8220;cyber&#8221; attack surface. One of the ways you can do that is to install as few applications as possible onto your devices and make [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":12942,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":3,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":""},"categories":[3,780,91],"tags":[],"class_list":["post-12940","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-information-security","category-macos","category-r"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Getting a Handle on macOS App Entitlements with R - rud.is<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/rud.is\/b\/2021\/02\/07\/getting-a-handle-on-macos-app-entitlements-with-r\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Getting a Handle on macOS App Entitlements with R - rud.is\" \/>\n<meta property=\"og:description\" content=\"If you&#8217;ve been following me around the internets for a while you&#8217;ve likely heard me pontificate about the need to be aware of and reduce \u2014 when possible \u2014 your personal &#8220;cyber&#8221; attack surface. One of the ways you can do that is to install as few applications as possible onto your devices and make [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/rud.is\/b\/2021\/02\/07\/getting-a-handle-on-macos-app-entitlements-with-r\/\" \/>\n<meta property=\"og:site_name\" content=\"rud.is\" \/>\n<meta property=\"article:published_time\" content=\"2021-02-07T18:15:44+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?fit=1269%2C1338&ssl=1\" \/>\n\t<meta property=\"og:image:width\" content=\"1269\" \/>\n\t<meta property=\"og:image:height\" content=\"1338\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"hrbrmstr\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"hrbrmstr\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2021\\\/02\\\/07\\\/getting-a-handle-on-macos-app-entitlements-with-r\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2021\\\/02\\\/07\\\/getting-a-handle-on-macos-app-entitlements-with-r\\\/\"},\"author\":{\"name\":\"hrbrmstr\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\"},\"headline\":\"Getting a Handle on macOS App Entitlements with R\",\"datePublished\":\"2021-02-07T18:15:44+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2021\\\/02\\\/07\\\/getting-a-handle-on-macos-app-entitlements-with-r\\\/\"},\"wordCount\":592,\"commentCount\":3,\"publisher\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\"},\"image\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2021\\\/02\\\/07\\\/getting-a-handle-on-macos-app-entitlements-with-r\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2021\\\/02\\\/ent-grph-02.png?fit=1269%2C1338&ssl=1\",\"articleSection\":[\"Information Security\",\"macOS\",\"R\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/rud.is\\\/b\\\/2021\\\/02\\\/07\\\/getting-a-handle-on-macos-app-entitlements-with-r\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2021\\\/02\\\/07\\\/getting-a-handle-on-macos-app-entitlements-with-r\\\/\",\"url\":\"https:\\\/\\\/rud.is\\\/b\\\/2021\\\/02\\\/07\\\/getting-a-handle-on-macos-app-entitlements-with-r\\\/\",\"name\":\"Getting a Handle on macOS App Entitlements with R - rud.is\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2021\\\/02\\\/07\\\/getting-a-handle-on-macos-app-entitlements-with-r\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2021\\\/02\\\/07\\\/getting-a-handle-on-macos-app-entitlements-with-r\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2021\\\/02\\\/ent-grph-02.png?fit=1269%2C1338&ssl=1\",\"datePublished\":\"2021-02-07T18:15:44+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2021\\\/02\\\/07\\\/getting-a-handle-on-macos-app-entitlements-with-r\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/rud.is\\\/b\\\/2021\\\/02\\\/07\\\/getting-a-handle-on-macos-app-entitlements-with-r\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2021\\\/02\\\/07\\\/getting-a-handle-on-macos-app-entitlements-with-r\\\/#primaryimage\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2021\\\/02\\\/ent-grph-02.png?fit=1269%2C1338&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2021\\\/02\\\/ent-grph-02.png?fit=1269%2C1338&ssl=1\",\"width\":1269,\"height\":1338,\"caption\":\"macos app entitlements\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2021\\\/02\\\/07\\\/getting-a-handle-on-macos-app-entitlements-with-r\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/rud.is\\\/b\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Getting a Handle on macOS App Entitlements with R\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#website\",\"url\":\"https:\\\/\\\/rud.is\\\/b\\\/\",\"name\":\"rud.is\",\"description\":\"&quot;In God we trust. All others must bring data&quot;\",\"publisher\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/rud.is\\\/b\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\",\"name\":\"hrbrmstr\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\",\"width\":460,\"height\":460,\"caption\":\"hrbrmstr\"},\"logo\":{\"@id\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\"},\"description\":\"Don't look at me\u2026I do what he does \u2014 just slower. #rstats avuncular \u2022 ?Resistance Fighter \u2022 Cook \u2022 Christian \u2022 [Master] Chef des Donn\u00e9es de S\u00e9curit\u00e9 @ @rapid7\",\"sameAs\":[\"http:\\\/\\\/rud.is\"],\"url\":\"https:\\\/\\\/rud.is\\\/b\\\/author\\\/hrbrmstr\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Getting a Handle on macOS App Entitlements with R - rud.is","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/rud.is\/b\/2021\/02\/07\/getting-a-handle-on-macos-app-entitlements-with-r\/","og_locale":"en_US","og_type":"article","og_title":"Getting a Handle on macOS App Entitlements with R - rud.is","og_description":"If you&#8217;ve been following me around the internets for a while you&#8217;ve likely heard me pontificate about the need to be aware of and reduce \u2014 when possible \u2014 your personal &#8220;cyber&#8221; attack surface. One of the ways you can do that is to install as few applications as possible onto your devices and make [&hellip;]","og_url":"https:\/\/rud.is\/b\/2021\/02\/07\/getting-a-handle-on-macos-app-entitlements-with-r\/","og_site_name":"rud.is","article_published_time":"2021-02-07T18:15:44+00:00","og_image":[{"width":1269,"height":1338,"url":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?fit=1269%2C1338&ssl=1","type":"image\/png"}],"author":"hrbrmstr","twitter_card":"summary_large_image","twitter_misc":{"Written by":"hrbrmstr","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/rud.is\/b\/2021\/02\/07\/getting-a-handle-on-macos-app-entitlements-with-r\/#article","isPartOf":{"@id":"https:\/\/rud.is\/b\/2021\/02\/07\/getting-a-handle-on-macos-app-entitlements-with-r\/"},"author":{"name":"hrbrmstr","@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"headline":"Getting a Handle on macOS App Entitlements with R","datePublished":"2021-02-07T18:15:44+00:00","mainEntityOfPage":{"@id":"https:\/\/rud.is\/b\/2021\/02\/07\/getting-a-handle-on-macos-app-entitlements-with-r\/"},"wordCount":592,"commentCount":3,"publisher":{"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"image":{"@id":"https:\/\/rud.is\/b\/2021\/02\/07\/getting-a-handle-on-macos-app-entitlements-with-r\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?fit=1269%2C1338&ssl=1","articleSection":["Information Security","macOS","R"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/rud.is\/b\/2021\/02\/07\/getting-a-handle-on-macos-app-entitlements-with-r\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/rud.is\/b\/2021\/02\/07\/getting-a-handle-on-macos-app-entitlements-with-r\/","url":"https:\/\/rud.is\/b\/2021\/02\/07\/getting-a-handle-on-macos-app-entitlements-with-r\/","name":"Getting a Handle on macOS App Entitlements with R - rud.is","isPartOf":{"@id":"https:\/\/rud.is\/b\/#website"},"primaryImageOfPage":{"@id":"https:\/\/rud.is\/b\/2021\/02\/07\/getting-a-handle-on-macos-app-entitlements-with-r\/#primaryimage"},"image":{"@id":"https:\/\/rud.is\/b\/2021\/02\/07\/getting-a-handle-on-macos-app-entitlements-with-r\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?fit=1269%2C1338&ssl=1","datePublished":"2021-02-07T18:15:44+00:00","breadcrumb":{"@id":"https:\/\/rud.is\/b\/2021\/02\/07\/getting-a-handle-on-macos-app-entitlements-with-r\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/rud.is\/b\/2021\/02\/07\/getting-a-handle-on-macos-app-entitlements-with-r\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/rud.is\/b\/2021\/02\/07\/getting-a-handle-on-macos-app-entitlements-with-r\/#primaryimage","url":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?fit=1269%2C1338&ssl=1","contentUrl":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?fit=1269%2C1338&ssl=1","width":1269,"height":1338,"caption":"macos app entitlements"},{"@type":"BreadcrumbList","@id":"https:\/\/rud.is\/b\/2021\/02\/07\/getting-a-handle-on-macos-app-entitlements-with-r\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/rud.is\/b\/"},{"@type":"ListItem","position":2,"name":"Getting a Handle on macOS App Entitlements with R"}]},{"@type":"WebSite","@id":"https:\/\/rud.is\/b\/#website","url":"https:\/\/rud.is\/b\/","name":"rud.is","description":"&quot;In God we trust. All others must bring data&quot;","publisher":{"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/rud.is\/b\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886","name":"hrbrmstr","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","url":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","contentUrl":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","width":460,"height":460,"caption":"hrbrmstr"},"logo":{"@id":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1"},"description":"Don't look at me\u2026I do what he does \u2014 just slower. #rstats avuncular \u2022 ?Resistance Fighter \u2022 Cook \u2022 Christian \u2022 [Master] Chef des Donn\u00e9es de S\u00e9curit\u00e9 @ @rapid7","sameAs":["http:\/\/rud.is"],"url":"https:\/\/rud.is\/b\/author\/hrbrmstr\/"}]}},"jetpack_featured_media_url":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2021\/02\/ent-grph-02.png?fit=1269%2C1338&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/p23idr-3mI","jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":12645,"url":"https:\/\/rud.is\/b\/2020\/02\/06\/prying-r-script-files-away-from-xcode-et-al-on-macos\/","url_meta":{"origin":12940,"position":0},"title":"Prying &#8220;.R&#8221; Script Files Away from Xcode (et al) on macOS","author":"hrbrmstr","date":"2020-02-06","format":false,"excerpt":"As the maintainer of RSwitch --- and developer of my own (for personal use) macOS, iOS, watchOS, iPadOS and tvOS apps --- I need the full Apple Xcode install around (more R-focused macOS folk can get away with just the command-line tools being installed). As an Apple Developer who insanely\u2026","rel":"","context":"In &quot;macOS&quot;","block_context":{"text":"macOS","link":"https:\/\/rud.is\/b\/category\/macos\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":12185,"url":"https:\/\/rud.is\/b\/2019\/05\/12\/quick-hit-updates-to-quicklookr-and-rdatainfo\/","url_meta":{"origin":12940,"position":1},"title":"Quick Hit: Updates to QuickLookR and {rdatainfo}","author":"hrbrmstr","date":"2019-05-12","format":false,"excerpt":"I'm using GitUgh links here b\/c the issue was submitted there. Those not wishing to be surveilled by Microsoft can find the macOS QuickLook plugin project and {rdatainfo} project in SourceHut and GitLab (~hrbrmstr and hrbrmstr accounts respectively). I hadn't touched QuickLookR? or {rdatainfo}? at all since 2016 since it\u2026","rel":"","context":"In &quot;macOS&quot;","block_context":{"text":"macOS","link":"https:\/\/rud.is\/b\/category\/macos\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":13026,"url":"https:\/\/rud.is\/b\/2021\/04\/14\/avoiding-the-mdls-command-line-round-trip-with-swiftrswift_function\/","url_meta":{"origin":12940,"position":2},"title":"Avoiding The mdls Command Line Round Trip With swiftr::swift_function()","author":"hrbrmstr","date":"2021-04-14","format":false,"excerpt":"The last post showed how to work with the macOS mdls command line XML output, but with {swiftr} we can avoid the command line round trip by bridging the low-level Spotlight API (which mdls uses) directly in R via Swift. If you've already played with {swiftr} before but were somewhat\u2026","rel":"","context":"In &quot;macOS&quot;","block_context":{"text":"macOS","link":"https:\/\/rud.is\/b\/category\/macos\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":12841,"url":"https:\/\/rud.is\/b\/2020\/11\/18\/apple-silicon-big-sur-rstudio-r-field-report\/","url_meta":{"origin":12940,"position":3},"title":"Apple Silicon + Big Sur + RStudio + R Field Report","author":"hrbrmstr","date":"2020-11-18","format":false,"excerpt":"It's been a while since I've posted anything R-related and, while this one will be brief, it may be of use to some R folks who have taken the leap into Big Sur and\/or Apple Silicon. Stay to the end for an early Christmas ?! Big Sur Report As #rstats\u2026","rel":"","context":"In &quot;macOS&quot;","block_context":{"text":"macOS","link":"https:\/\/rud.is\/b\/category\/macos\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":13498,"url":"https:\/\/rud.is\/b\/2022\/07\/10\/rust-cli-for-apples-weatherkit-rest-api\/","url_meta":{"origin":12940,"position":4},"title":"Rust CLI For Apple&#8217;s WeatherKit REST API","author":"hrbrmstr","date":"2022-07-10","format":false,"excerpt":"Apple is in the final stages of shuttering the DarkSky service\/API. They've replaced it with WeatherKit, which has both an xOS framework version as well as a REST API. To use either, you need to be a member of the Apple Developer Program (ADP) \u2014 $99.00\/USD per-year \u2014 and calls\u2026","rel":"","context":"In &quot;Apple&quot;","block_context":{"text":"Apple","link":"https:\/\/rud.is\/b\/category\/apple\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":12763,"url":"https:\/\/rud.is\/b\/2020\/05\/25\/rswitch-1-7-0-has-been-released\/","url_meta":{"origin":12940,"position":5},"title":"RSwitch 1.7.0 Has Been Released","author":"hrbrmstr","date":"2020-05-25","format":false,"excerpt":"I (and, apparently, Gandalf O_o) are pleased to announce that RSwitch version 1.7.0 has been released. (Direct Download) RSwitch is a macOS menubar utility that: makes it dead simple to manage multiple macOS R versions use the latest RStudio daily builds access remote RStudio Server sessions using in a purpose-built\u2026","rel":"","context":"In &quot;Apple&quot;","block_context":{"text":"Apple","link":"https:\/\/rud.is\/b\/category\/apple\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2020\/05\/gandalf-rswitch.png?fit=480%2C280&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts\/12940","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/comments?post=12940"}],"version-history":[{"count":0,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts\/12940\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/media\/12942"}],"wp:attachment":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/media?parent=12940"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/categories?post=12940"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/tags?post=12940"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}