LockFlare

.NET runtime

The .NET runtime carries fewer application-level constraints than Node — dependencies travel inside the artifact — but two things differ from a conventional host: nothing compiles on the server, and outbound network is closed by default.

No compilation on the host

A published application is decrypted in RAM and its assemblies load through in-memory assembly loading inside a collectible load context. No compiler runs on the server — there is no compilation surface at all, which is deliberate: a compiler is a code-execution primitive, and removing it removes a class of attack.

The consequence is that anything expecting to be compiled at runtime must be precompiled at publish time instead.

PatternWhat to do
Razor views compiled at runtime Precompile them. Razor compilation at publish is the default for ASP.NET Core — confirm it is not disabled.
Runtime code generation via Roslyn Not available on the host. Move it to build time, or restructure around it.
Plugin assemblies loaded from a directory at runtime There is no directory to load from. Ship plugins inside the artifact.

Assemblies have no physical location

Assemblies load from memory streams, so they have no path on disk. Code that reads Assembly.Location, AppContext.BaseDirectory or builds a path relative to the executing assembly will not find what it expects — Location is empty for an assembly loaded this way.

This usually shows up in code locating a config file, a template, or an embedded resource by path. Embedded resources loaded through Assembly.GetManifestResourceStream work normally, because they travel inside the assembly.

Configuration is delivered to the process environment in memory rather than as a file on disk, so read settings from environment variables rather than locating an appsettings.json on the filesystem.

Outbound network is closed by default

An application runs in an empty network namespace and cannot open outbound connections — not to a database, not to a payment provider, not to any external API. That is what removes the exfiltration path for compromised application logic, and it is the recommended posture for anything that does not need egress.

Most applications need egress, and it must be enabled deliberately. If your app talks to a database, turn it on for that environment before you push — otherwise every outbound call fails and the cause is not obvious from the application’s own error messages.

Enabling it changes only the network namespace. Private mount, PID, IPC and UTS namespaces, the dedicated unprivileged user, no_new_privs and cgroup caps all still apply — the application can reach the network but still cannot observe host processes or host files.

It is currently a per-environment switch rather than a per-destination allow-list. Narrowing that is planned.

Resource caps are enforced

Each application runs under cgroup limits on memory and process count. An application that exceeds its memory cap is killed and restarted rather than being allowed to exhaust the host — which contains the failure to the application that caused it, but does mean a genuinely memory-hungry workload needs its cap sized deliberately rather than left at a default.

What works unchanged

Worth stating, because the list above is all constraints. Your application’s own entry point is invoked, so it runs exactly as written — Razor Pages, MVC, Blazor Server, minimal APIs, Kestrel. There is no LockFlare code in your application and no SDK to adopt.

NuGet dependencies travel inside the encrypted artifact and load from memory, resolved entirely by your build. Stable ASP.NET Data Protection is provided without application changes, so antiforgery tokens and authentication cookies survive restarts despite nothing being written to disk.