<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Michael Bullington&apos;s Weblog</title><description>I try to share things that are interesting to me. This may include technology, personal projects, living in New York City; etc.</description><link>https://mbullington.net/</link><item><title>Exploring; Leaving Figma</title><link>https://mbullington.net/weblog/leaving-figma/</link><guid isPermaLink="true">https://mbullington.net/weblog/leaving-figma/</guid><description>&lt;p&gt;As the eagle-eyed among you may have noticed, I’ve been working on a new project for the past few months.&lt;/p&gt;
&lt;p&gt;I’m incredibly thankful for my time at Figma—almost 3.5 years. It’s a great team; an...</description><pubDate>Sat, 02 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As the eagle-eyed among you may have noticed, I’ve been working on a new project for the past few months.&lt;/p&gt;
&lt;p&gt;I’m incredibly thankful for my time at Figma—almost 3.5 years. It’s a great team; and while the largest company I’ve ever worked at, it still feels like a startup with the benefit of a massive and caring community. This is what I will miss most.&lt;/p&gt;
&lt;p&gt;On the other side: I’ve been using the community space at &lt;a href=&quot;https://www.southparkcommons.com/&quot;&gt;South Park Commons&lt;/a&gt; in NYC, which I’d highly recommend. I love the positive entropy and talent density.&lt;/p&gt;</content:encoded></item><item><title>Link Blogging</title><link>https://mbullington.net/weblog/link-blogging/</link><guid isPermaLink="true">https://mbullington.net/weblog/link-blogging/</guid><description>&lt;p&gt;Ref: &lt;a href=&quot;https://simonwillison.net/2024/Dec/22/link-blog/&quot;&gt;“My approach to running a link blog” by Simon Willison&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I wanted to start link blogging! I’ve been very inspired by Simon W...</description><pubDate>Fri, 30 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Ref: &lt;a href=&quot;https://simonwillison.net/2024/Dec/22/link-blog/&quot;&gt;“My approach to running a link blog” by Simon Willison&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I wanted to start link blogging! I’ve been very inspired by Simon Willison the past few years—and once I’ve gotten past having Something Important to say, a link blog seems like a good way to lower the stakes of making &amp;#x26; sharing something on my website.&lt;/p&gt;
&lt;p&gt;This is the main tenant:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I try to add something extra. My goal with any link blog post is that if you read both my post and the source material you’ll have an enhanced experience over if you read just the source material itself.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I’ve backfilled a few entries (and will more-so soon), and &lt;a href=&quot;/rss.xml&quot;&gt;installed RSS&lt;/a&gt; if that’s your jam. Let me know what you think!&lt;/p&gt;</content:encoded></item><item><title>Gamejam, SUB-SURFACE!</title><link>https://mbullington.net/weblog/subsurface/</link><guid isPermaLink="true">https://mbullington.net/weblog/subsurface/</guid><description>&lt;p&gt;&lt;img src=&quot;https://img.itch.zone/aW1hZ2UvMzQ2NjM5My8yMDY4MDg3My5wbmc=/original/yTfvqH.png&quot; alt=&quot;SUB-SURFACE&quot;&gt;&lt;/p&gt;
&lt;p&gt;I helped make a game—&lt;a href=&quot;https://trashmoon.itch.io/subsurface&quot;&gt;SUB-SURFACE&lt;/...</description><pubDate>Fri, 11 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://img.itch.zone/aW1hZ2UvMzQ2NjM5My8yMDY4MDg3My5wbmc=/original/yTfvqH.png&quot; alt=&quot;SUB-SURFACE&quot;&gt;&lt;/p&gt;
&lt;p&gt;I helped make a game—&lt;a href=&quot;https://trashmoon.itch.io/subsurface&quot;&gt;SUB-SURFACE&lt;/a&gt;! A gamejam one, anyway—every year or so I end up doing a gamejam with a few friends.&lt;/p&gt;
&lt;p&gt;Who worked on it:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://austinbreed.com/&quot;&gt;Austin Breed&lt;/a&gt; (art &amp;#x26; animation), &lt;a href=&quot;https://jeffomatic.com/&quot;&gt;Jeff Lee&lt;/a&gt; (programming &amp;#x26; audio), me (programming), &lt;a href=&quot;https://trashmoon.com/&quot;&gt;Saman Bemel-Benrud&lt;/a&gt; (a bit of everything), &lt;a href=&quot;https://itch.io/profile/rubacava&quot;&gt;Tom Lubanovic&lt;/a&gt; (design)&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title>Deno&apos;s sandbox is insufficient</title><link>https://mbullington.net/weblog/please-let-me-sandbox-npm/</link><guid isPermaLink="true">https://mbullington.net/weblog/please-let-me-sandbox-npm/</guid><description>&lt;p&gt;Node.js packages, NPM post-install scripts horrify me.&lt;/p&gt;
&lt;p&gt;So much of “traditional” security relies on if an application can get root, change your system etc… to &lt;em&gt;say absolutely nothing&lt;/em&gt; ...</description><pubDate>Wed, 17 May 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Node.js packages, NPM post-install scripts horrify me.&lt;/p&gt;
&lt;p&gt;So much of “traditional” security relies on if an application can get root, change your system etc… to &lt;em&gt;say absolutely nothing&lt;/em&gt; about what’s sitting in your &lt;code&gt;$HOME&lt;/code&gt; directory.&lt;/p&gt;
&lt;p&gt;My SSH keys? My downloads? My private notes?&lt;/p&gt;
&lt;p&gt;At any time—any of the bazillion packages NPM install could be malicious, and secretly exfiltrate your data. &lt;code&gt;DYLD_INSERT_LIBRARIES&lt;/code&gt; something, put something in your &lt;code&gt;.bashrc&lt;/code&gt;, whatever.&lt;/p&gt;
&lt;p&gt;Another JavaScript runtime—Deno &lt;a href=&quot;https://docs.deno.com/runtime/fundamentals/security/#permissions&quot;&gt;tries to solve this problem&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; deno run --allow-run runner.ts&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;error:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; Uncaught&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; PermissionDenied:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; Requires&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; env&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; access&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; to&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;HOME&quot;,&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; run&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; again&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; with&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; the&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --allow-env&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; flag&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; privateKey&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; Deno.readFile&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Deno.env.get(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;&quot;HOME&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;/.ssh/id_ed25519&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;By default, access to most system I/O is denied. There are some I/O operations that are allowed in a limited capacity, even by default. These are described below.&lt;/p&gt;
&lt;p&gt;To enable these operations, the user must explicitly grant permission to the Deno runtime. This is done by passing the &lt;code&gt;--allow-read&lt;/code&gt;, &lt;code&gt;--allow-write&lt;/code&gt;, &lt;code&gt;--allow-net&lt;/code&gt;, &lt;code&gt;--allow-env&lt;/code&gt;, and &lt;code&gt;--allow-run&lt;/code&gt; flags to the deno command.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;digging-deeper&quot;&gt;Digging deeper&lt;/h4&gt;
&lt;p&gt;As far as I could tell—Deno’s approach is only gated by an &lt;em&gt;application-specific sandbox.&lt;/em&gt; The files to be read/denied are checked against an allowlist in their Rust code, if it’s there it’s allowed, otherwise it’s denied.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Deno makes the assumption its JavaScript engine, V8, and it’s application code is perfect—free of memory bugs.&lt;/strong&gt; If this assumption is violated, then you can break the sandbox. Furthermore, if you allow calling a subcommand like ESBuild, you also break the sandbox.&lt;/p&gt;
&lt;p&gt;This is inconsistent with other projects where V8 is used—Chromium’s &lt;a href=&quot;https://chromium.googlesource.com/chromium/src/+/HEAD/docs/design/sandbox.md&quot;&gt;“Sandbox”&lt;/a&gt; takes the assumption their application sandbox has &lt;em&gt;already been escaped.&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Assume sandboxed code is malicious code: For threat-modeling purposes, we consider the sandbox compromised (that is, running malicious code) once the execution path reaches past a few early calls in the &lt;code&gt;main()&lt;/code&gt; function. In practice, it could happen as soon as the first external input is accepted, or right before the main loop is entered.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;How they accomplish this is a command in macOS named &lt;code&gt;sandbox-exec&lt;/code&gt;, a command that allows us &lt;em&gt;at the OS level&lt;/em&gt; to restrict what a process can read, write, and access through the network.&lt;/p&gt;
&lt;p&gt;The mechanism is not documented outside of Apple, is &lt;em&gt;technically&lt;/em&gt; deprecated (&lt;code&gt;man sandbox-exec&lt;/code&gt;), but even so is used by Chromium, Firefox, and Bazel. Profiles are defined using &lt;em&gt;some sort of Scheme variant.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;How these have been documented, then, is by analyzing ones internal to macOS—try picking an example in &lt;code&gt;/System/Library/Sandbox/Profiles&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;scheme&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;;; cat /System/Library/Sandbox/Profiles/bsd.sb&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(version &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(debug deny)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(import &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;system.sb&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;;; allow processes to traverse symlinks&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(allow file-read-metadata)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(allow file-read-data file-write-data&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  (regex&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    ; Allow files accessed by system dylibs and frameworks&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    #&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;/&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\.&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;CFUserTextEncoding$&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    #&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;^/usr/share/nls/&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    #&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;^/usr/share/zoneinfo /var/db/timezone/zoneinfo/&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  ))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(allow ipc-posix-shm (ipc-posix-name &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;apple.shm.notification_center&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)) &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;; Libnotify&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(allow signal (target self))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Neat! Then run it with &lt;code&gt;sandbox-exec -f /System/Library/Sandbox/Profiles/bsd.sb node index.js&lt;/code&gt;, although don’t expect it to do much without modification.&lt;/p&gt;
&lt;h4 id=&quot;tying-this-together&quot;&gt;Tying this together&lt;/h4&gt;
&lt;p&gt;Please let me sandbox Node.js. Please let me sandbox NPM. While Deno is a great start, their sandbox is &lt;em&gt;insufficient&lt;/em&gt; relying only on application-level policy—true sandboxing needs &lt;strong&gt;OS-level sandboxing.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Deno needs OS-level sandboxing because they &lt;strong&gt;cannot guarantee the correctness of their system,&lt;/strong&gt; something even Google admits for V8:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The key to security is understanding: we can only truly secure a system if we fully understand its behaviors with respect to the combination of all possible inputs in all possible states. For a codebase as large and diverse as Chromium, reasoning about the combined behavior of all its parts is &lt;strong&gt;nearly impossible&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;On macOS, this can be accomplished using &lt;code&gt;sandbox-exec&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I’d really love to see Deno ship with &lt;code&gt;sandbox-exec&lt;/code&gt; support, and for the permissions Deno has developed to permeate Node.js/NPM writ large.&lt;/p&gt;</content:encoded></item><item><title>Serial side projects</title><link>https://mbullington.net/weblog/side-projects/</link><guid isPermaLink="true">https://mbullington.net/weblog/side-projects/</guid><description>&lt;p&gt;It started small, about a year ago, in-between me trying to finish my undergrad degree.&lt;/p&gt;
&lt;p&gt;I kept having an idea for a spatial desktop manager—not totally unlike a project called &lt;a href=&quot;https...</description><pubDate>Tue, 22 Feb 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It started small, about a year ago, in-between me trying to finish my undergrad degree.&lt;/p&gt;
&lt;p&gt;I kept having an idea for a spatial desktop manager—not totally unlike a project called &lt;a href=&quot;https://itsfoss.com/paperwm/&quot;&gt;PaperWM&lt;/a&gt;, although I didn’t know it at the time. You can think of like when you search for titles in Netflix how the different rows retain their relative position to the cursor. Except, of course, with windows.&lt;/p&gt;
&lt;p&gt;Cut to a few months later, I ended up combing through &lt;em&gt;stacks&lt;/em&gt; of Linux documentation trying to find the best way to &lt;em&gt;build this thing&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;OK. I need to learn about Wayland and build my window manager with that. Surely C isn’t good enough (in fairness, it isn’t), which compiled language has the best &lt;code&gt;wlroots&lt;/code&gt; bindings? &lt;a href=&quot;https://developer.apple.com/swift/&quot;&gt;Swift&lt;/a&gt;, cool.&lt;/p&gt;
&lt;p&gt;Maybe it needs to be a distro?&lt;/p&gt;
&lt;p&gt;Cut later—I now have a fully immutable Linux system decently far removed from my Ubuntu base. This little immutability stunt, based on &lt;a href=&quot;https://ostreedev.github.io/ostree/introduction/&quot;&gt;OSTree&lt;/a&gt;, is pretty stable actually. There’s a lot of externalities that come with it, and &lt;strong&gt;of course&lt;/strong&gt; I had to figure those out as well from the jump. I took &lt;a href=&quot;https://github.com/bloomos/os/wiki&quot;&gt;optimistic notes&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;On and on it went, me finding the ends of the Linux earth for prior art and inspiration, but my excitement for the original idea was waning.&lt;/p&gt;
&lt;h4 id=&quot;the-goal-of-a-side-project&quot;&gt;The goal of a side-project&lt;/h4&gt;
&lt;p&gt;If it’s not clear speaking of it in the past-tense, I’m no longer working on this project.&lt;/p&gt;
&lt;p&gt;Was it a failure? I don’t know. I’m not sure. All of these tasks, some I’m actively invested in and others zombies, all carry a guilt that they’re not &lt;em&gt;shipped&lt;/em&gt;. &lt;strong&gt;“Always be shipping.”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Other than declaring side-project bankruptcy, what am I suppose to do? Make a GAANT chart months out for my free time?&lt;/p&gt;</content:encoded></item></channel></rss>