Full ASP.NET Core. Zero files.
Standard published .NET apps — Razor Pages, MVC, Blazor Server, minimal APIs — pulled from encrypted storage, decrypted in volatile memory, and loaded from memory streams. Your assemblies never exist as files on the server: not your DLLs, not your NuGet dependencies, not the runtime machinery that executes them.
Publish normally. Push the folder.
No SDK, no base classes, no LockFlare code in your app. You publish the way you always do; Cipher encrypts the output, stores it as ciphertext, and your server loads it from RAM.
Your side: a standard publish
Build a framework-dependent publish — dotnet publish -c Release -o publish — and push the contents of the folder, with the entry DLL and your wwwroot/ at the root of what you upload. Set the entry DLL, and you are deployed.
Our side: loaded from memory
On the server your assemblies are decrypted in RAM and loaded from memory streams into an AssemblyLoadContext; the entry point is invoked from the assembly's own metadata. No compilation step and no source shipping: what you push is compiled IL, and it goes from ciphertext to executing code without ever becoming a file.
NuGet: bring your packages
Anything on NuGet works. Your dependencies ship inside the publish output as regular assemblies and load from RAM with the rest of the app — Entity Framework Core, Dapper, Serilog, MediatR, payment SDKs, all of it, unmodified.
The whole ASP.NET Core surface
Most apps run unmodified. Precompiled Razor views execute from the in-memory assembly; pages and controllers are discovered automatically.
Razor Pages and MVC
Server-rendered HTML, layouts, tag helpers, model binding — precompiled views executing straight from your in-memory assembly. No application-part registration, no changes.
Blazor Server
The SignalR circuit's websocket is proxied to your app over its socket. Interactive server rendering, with circuit state living in your app's process — standard Blazor behaviour.
Minimal APIs and SignalR
MapGet, MapPost, hubs, websockets — the modern surface works as is. Your app binds a unix socket that Cipher reverse-proxies; you never choose a port.
Static assets
Your wwwroot is staged into a RAM-backed filesystem private to your app — served by UseStaticFiles, invisible to the host, wiped when the process exits.
Forms and Data Protection
Antiforgery, auth cookies and TempData just work: Cipher supplies a stable per-application key held only in memory, so tokens survive restarts and redeploys. Nothing to configure.
Configuration and secrets
App configuration is injected as process environment variables — held in memory, never written to a file. Read them with IConfiguration, exactly as you do today.
Each app in its own cell
Every application runs in a hardened process the kernel itself confines — a boundary, not a convention.
- Private network namespace. No outbound connectivity from the app's namespace by default — application code cannot phone home or exfiltrate. Inbound traffic arrives only through the Cipher proxy, over a per-app unix socket.
- Private mount and PID namespaces. The app sees only its own filesystem view and its own processes. ps and /proc show nothing belonging to the host or to any other application.
- Unprivileged, capped, contained. A dedicated non-root user per app, no privilege escalation, and enforced memory and process-count caps — a runaway app exhausts its own cell, not the server.
From exec to serving, in ten steps
Environment check
The engine refuses to start if debugging or tracing tools are present. Debugger-attach detection and shared-library injection protection guard the process from the first instruction.
License validation
The engine reads its license and presents it to the control plane, which checks it against the account and the source address. Licenses are IP-bound.
Runtime and manifest fetch
The encrypted runtime arrives with a manifest enumerating its dependencies and their SHA-256 digests, both under a per-request symmetric key.
Dependency fetch and verify
Each runtime dependency is fetched independently under its own per-request key and SHA-256 verified against the manifest before acceptance. A mismatch means a full retry.
In-memory handoff
The engine spawns the runtime process and streams the decrypted assemblies over a pipe as length-prefixed binary frames — loaded from memory, entry point invoked by reflection.
RAM scrub
The engine zeroes its in-memory copy of every decrypted assembly, scrubs the decryption keys, and enters a heartbeat loop.
App list fetch
The live runtime authenticates with its license and fetches your deployed applications: each one's published DLLs and static assets, decrypted from encrypted storage into RAM.
Per-app confinement
Each application gets its own hardened process: private network, mount and PID namespaces, a dedicated unprivileged user, enforced memory and process caps.
Stream and load
Your app's assemblies stream into its confined process over standard input and load from memory streams — Kestrel starts inside the cell and binds a per-app unix socket.
Proxy and serve
The Cipher proxy routes your domains to the app's socket. Health is confirmed and traffic flows, with nothing of yours on the filesystem.
Push a build, swap the app
New builds reach running engines over an authenticated, timestamp-fresh reload channel — stale signals are rejected as replay defence. On verification your new assemblies are decrypted into RAM and a fresh confined process comes up beside the old one. Traffic swaps to the new socket; in-flight requests drain against the old process before it exits and its memory is reclaimed. Data Protection keys are stable across the swap, so sessions and antiforgery tokens survive the redeploy.
TLS can be terminated in front — a CDN or a reverse proxy, with only port 80 on the server — or by the server itself; the .NET engine has that built in.
Installing the .NET engine, in the docsWhat it defends against — and what it does not
Defends against
- Filesystem search for customer source or assemblies — nothing persisted
- Disassembly of the engine — no customer or runtime code inside it
- Man-in-the-middle on delivery — TLS plus SHA-256 manifest verification per dependency
- Replay of old delivery responses — per-request key material
- Replay of reload signals — timestamp freshness window
- Debugger attach for memory inspection — refused at startup, shut down on sight
- Cross-app access — private mount, PID and network namespaces per application
- Data exfiltration by app code — no outbound network from the app namespace
- Post-seal compromise — a sealed server has no interactive credentials
Explicitly out of scope
- A compromised customer license — the root of trust for Enclave, in your custody
- A compromised control plane — protected under its own security model
- Memory scraping by a privileged local attacker on a running, unsealed machine — the honest limit; Enclave is the answer
- Side-channel attacks — cache timing, Spectre-class, power analysis
- Vulnerabilities in your own application code
The exact app you run locally
Bring a published app and a test server, and we will load it from memory with you. What the runtime cannot do is written down first — the .NET limitations.