<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="rss.xsl"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>NDM Blog</title>
        <link>https://docs.ndm-cli.dev/blog</link>
        <description>NDM Blog</description>
        <lastBuildDate>Sat, 31 Oct 2026 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Update, the Logger]]></title>
            <link>https://docs.ndm-cli.dev/blog/update-logger</link>
            <guid>https://docs.ndm-cli.dev/blog/update-logger</guid>
            <pubDate>Sat, 31 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[{/ truncate /}]]></description>
            <content:encoded><![CDATA[
<p>One of the central parts of NDM is observing what an analyzed npm package actually does during execution.
We want to collect information about its processes, file system activity, network connections and potentially sensitive data access.</p>
<p>Sounds relatively straightforward, right?</p>
<p>Well, it turned out to be quite a bit more complicated than expected.
We have already tested several approaches, and our current solution is quite different from what we originally planned.</p>
<h2 class="anchor anchorTargetStickyNavbar_Hh9E" id="our-initial-plan">Our initial plan<a href="https://docs.ndm-cli.dev/blog/update-logger#our-initial-plan" class="hash-link" aria-label="Direct link to Our initial plan" title="Direct link to Our initial plan" translate="no">​</a></h2>
<p>Our first approach was to use <a href="https://tetragon.io/" target="_blank" rel="noopener noreferrer" class=""><strong>Tetragon</strong></a>, a security observability and runtime enforcement tool based on eBPF.</p>
<p>Getting Tetragon running inside our Docker environment was not the problem.
The container started successfully, and our policies were accepted without any configuration errors.</p>
<p>The real problems started when we began testing the actual event collection.</p>
<p>Our policies did not produce the events we expected.
In particular, filtering events to only include processes belonging to our sandbox turned out to be problematic.
The container selection mechanisms we initially tried did not work properly with our Docker-based setup, because teragon was build for Kubernetes.</p>
<p>This meant that even though Tetragon was running, we could not reliably collect the information we needed.</p>
<p>So, instead of spending even more time trying to fix an approach that was not working as intended, we decided to move on to our second option.</p>
<h2 class="anchor anchorTargetStickyNavbar_Hh9E" id="plan-b">Plan "B"<a href="https://docs.ndm-cli.dev/blog/update-logger#plan-b" class="hash-link" aria-label="Direct link to Plan &quot;B&quot;" title="Direct link to Plan &quot;B&quot;" translate="no">​</a></h2>
<p>Of course, we had a backup plan.</p>
<p>We removed the Tetragon container from our Docker Compose setup and started experimenting with <a href="https://falco.org/" target="_blank" rel="noopener noreferrer" class=""><strong>Falco</strong></a>.</p>
<p>This time, things looked considerably better.
We managed to configure container selection, and our custom rules started producing the events we were looking for.</p>
<p>We successfully tested several types of activity:</p>
<ul>
<li class=""><strong>Process activity:</strong> Detecting processes started inside the sandbox.</li>
<li class=""><strong>File system activity:</strong> Observing file access, creation and modification.</li>
<li class=""><strong>Network activity:</strong> Detecting outgoing network connections.</li>
</ul>
<p>Falco also showed lower CPU usage in our tests compared to our previous Tetragon setup.</p>
<p>For the first time, we had a working proof of concept that could collect most of the information we needed.</p>
<p>However, there was still one major problem: our sandbox runtime.</p>
<h2 class="anchor anchorTargetStickyNavbar_Hh9E" id="gvisor">gVisor<a href="https://docs.ndm-cli.dev/blog/update-logger#gvisor" class="hash-link" aria-label="Direct link to gVisor" title="Direct link to gVisor" translate="no">​</a></h2>
<p>NDM does not execute potentially untrusted packages in ordinary Docker containers.
Instead, we use <a href="https://gvisor.dev/" target="_blank" rel="noopener noreferrer" class=""><strong>gVisor</strong></a> as an additional isolation layer.</p>
<h3 class="anchor anchorTargetStickyNavbar_Hh9E" id="but-what-exactly-is-gvisor">But what exactly is gVisor?<a href="https://docs.ndm-cli.dev/blog/update-logger#but-what-exactly-is-gvisor" class="hash-link" aria-label="Direct link to But what exactly is gVisor?" title="Direct link to But what exactly is gVisor?" translate="no">​</a></h3>
<p>Unlike traditional containers, which primarily rely on Linux kernel isolation mechanisms such as namespaces and cgroups, gVisor introduces an additional user-space kernel called <em>Sentry</em>.</p>
<p>This means that system calls made by applications inside the sandbox are intercepted and handled by gVisor instead of being passed directly to the host kernel.</p>
<p>This is great from a security perspective, but it creates a problem for traditional system monitoring tools.</p>
<p>Falco normally observes system activity through events generated by the host kernel.
With gVisor, many of the operations performed inside the sandbox are handled by Sentry and are therefore not visible to Falco in the same way as ordinary container activity.</p>
<p>As a result, Falco could not provide the complete view of the package's activity that we needed.</p>
<div class="theme-admonition theme-admonition-warning admonition_RRag alert alert--warning"><div class="admonitionHeading_D_CJ"><span class="admonitionIcon_FrdB"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>problem</div><div class="admonitionContent_j_8t"><p>Our monitoring solution needs to observe what happens <em>inside</em> the sandbox, not just what happens on the host running it.
Simply monitoring the host kernel is not sufficient for our setup.</p></div></div>
<p>We could have reconsidered our sandbox architecture, but that would have meant compromising on an important part of NDM's security model.</p>
<p>Instead, we started looking for a solution that works directly with gVisor.</p>
<h2 class="anchor anchorTargetStickyNavbar_Hh9E" id="a-new-hope">A new hope<a href="https://docs.ndm-cli.dev/blog/update-logger#a-new-hope" class="hash-link" aria-label="Direct link to A new hope" title="Direct link to A new hope" translate="no">​</a></h2>
<p>This is where <strong>SecCheck</strong> comes into play.</p>
<p>SecCheck is a monitoring mechanism built into gVisor itself.
It allows gVisor to report security-relevant events from inside the sandbox through a dedicated event stream.</p>
<p>And that is exactly what we were looking for.</p>
<p>Instead of trying to observe sandbox activity from outside through the host kernel, we can use the monitoring capabilities that gVisor already provides.</p>
<p>This approach also means that we do not have to abandon our existing sandbox architecture or introduce another monitoring layer that cannot properly see what happens inside it.</p>
<div class="theme-admonition theme-admonition-tip admonition_RRag alert alert--success"><div class="admonitionHeading_D_CJ"><span class="admonitionIcon_FrdB"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>Why this looks promising</div><div class="admonitionContent_j_8t"><ul>
<li class=""><strong>Native gVisor integration:</strong> Events originate directly from the component responsible for sandbox isolation.</li>
<li class=""><strong>Better visibility:</strong> We can collect information about activity that traditional host-level monitoring might miss.</li>
<li class=""><strong>Fits our architecture:</strong> The event stream can be received by a separate service and integrated into our existing Django backend.</li>
</ul></div></div>
<p>We have already started implementing the communication between gVisor and our backend. The first tests confirmed that gVisor reaches our configured SecCheck socket.</p>
<p>There is still work to do before we can reliably collect, process and store all relevant events.
In particular, we need to handle multiple concurrent sandboxes and make sure that events are correctly assigned to their respective analyses.</p>
<p><strong>We are not quite there yet, but this time we seem to be heading in the right direction.</strong></p>
<p>More details about the implementation will follow in our documentation once everything is working as intended.</p>]]></content:encoded>
            <category>update</category>
            <category>news</category>
            <category>NDM</category>
        </item>
        <item>
            <title><![CDATA[Update]]></title>
            <link>https://docs.ndm-cli.dev/blog/first-update</link>
            <guid>https://docs.ndm-cli.dev/blog/first-update</guid>
            <pubDate>Tue, 20 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[{/ truncate /}]]></description>
            <content:encoded><![CDATA[
<div class="theme-admonition theme-admonition-tip admonition_RRag alert alert--success"><div class="admonitionHeading_D_CJ"><span class="admonitionIcon_FrdB"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>What We Are Working On</div><div class="admonitionContent_j_8t"><p>We are currently setting up a <strong>logger</strong> for the NDM Sandbox.</p><p>The Sandbox is running, and we are extracting the functions from the package. We can perform the functions.</p><p>We only need a logger to see what the package is doing.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Hh9E" id="also-worth-mentioning">Also worth mentioning:<a href="https://docs.ndm-cli.dev/blog/first-update#also-worth-mentioning" class="hash-link" aria-label="Direct link to Also worth mentioning:" title="Direct link to Also worth mentioning:" translate="no">​</a></h2>
<p>The server will be asynchronous. Currently, we are testing the limits of the server.</p>
<p>We also built a tool that stops building more Sandboxes as needed. For example, if two users start a request with the same package and version at the same time, only one sandbox will start. Only one sandbox will start for both users.</p>
<p>We also implemented a PostgreSQL database so that the sandbox doesn't run for every request. The response includes a value that indicates whether the results were cached or performed in a sandbox during your request.</p>]]></content:encoded>
            <category>update</category>
            <category>news</category>
            <category>NDM</category>
        </item>
        <item>
            <title><![CDATA[First Blog post]]></title>
            <link>https://docs.ndm-cli.dev/blog/first-blogpost</link>
            <guid>https://docs.ndm-cli.dev/blog/first-blogpost</guid>
            <pubDate>Sat, 26 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[{/ truncate /}]]></description>
            <content:encoded><![CDATA[
<p>The offical
<a href="https://ndm-cli.dev/" target="_blank" rel="noopener noreferrer" class="">NDM-webpage</a></p>
<p>This is the first post.</p>
<p>Read the documentation to understand what <strong>NDM</strong> is.</p>
<div class="theme-admonition theme-admonition-info admonition_RRag alert alert--info"><div class="admonitionHeading_D_CJ"><span class="admonitionIcon_FrdB"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_j_8t"><p>The CLI-tool hasn't dropped yet.</p></div></div>]]></content:encoded>
            <category>Docusaurus</category>
            <category>news</category>
            <category>NDM</category>
        </item>
    </channel>
</rss>