Homefront

Product & architecture review

Design proposal 15 min read

Contents12 sections

This review recommends the idea and constraints for a single new codebase that unifies and subsumes Homefront and Hyades. The existing repositories are reference material, not interfaces to preserve or systems to bolt together.

Conclusion

The strongest product is not “a secure place to run arbitrary applications.” It is a platform where replacing an application does not implicitly replace the security policy protecting its data.

That distinction should define the new codebase.

Isocore already articulates the capability-secure distributed-runtime idea. Internet2 develops much of the surrounding vision: shared state, typed interfaces, replaceable presentations, and applications that humans and agents can drive through the same actions. Those are substantial foundations.

What is missing is a sufficiently strong answer to:

Suppose the application itself is malicious. What can it still not do?

A useful Homefront should answer that question concretely, without requiring the application author to implement the protections correctly.

The product recommendation is:

A private application workspace with platform-enforced data policies, sandboxed computation, and narrowly authorized external actions.

The distributed runtime is its foundation—not its whole value proposition.

1. Start with malicious applications, not merely buggy ones

“Any vulnerability may be exploited” suggests a stronger design discipline than trying to make every application correct:

Treat application code as an adversarial implementation of a constrained interface.

An expense tool should remain unable to:

Its UI might still be wrong. It might calculate an incorrect subtotal. It might corrupt data it was explicitly authorized to modify. Those are separate correctness obligations.

This is where the formal-verification background can create real differentiation: make a small set of important properties hold for every application, including hostile applications.

The alternative—“applications can be secure if their authors use these excellent primitives correctly”—is valuable infrastructure, but falls short of secure by default.

Isolation is necessary but insufficient

A microVM containing a compromised expense application can successfully protect neighboring VMs while the application leaks its entire database through its legitimate network connection.

Likewise, a Wasm component with an unrestricted database handle and HTTP client can do enormous damage without escaping Wasm.

The important boundary is not simply where code runs. It is which decisions the code is allowed to make.

2. Resolve the confidentiality contract before designing orchestration

The disk-only threat model is coherent, but much narrower than “the server is compromised.”

Adversary What must protect the data?
Reads a storage snapshot Encryption, strong key protection, no plaintext spill
Controls an application Isolation and constrained authority
Controls a relay End-to-end encryption and authenticated protocol state
Controls the machine executing plaintext computation A separately justified protection mechanism—or trust in that machine

A normal microVM does not protect guest plaintext from a malicious host administrator. Neither does Wasm.

There is a fundamental constraint:

Ordinary arbitrary computation over private plaintext must happen somewhere trusted with that plaintext.

Keeping the user’s root key off a server is insufficient if the server receives decrypted records instead.

For the new design, adopt an explicit distinction:

An execution endpoint might be a laptop, an organization-controlled machine, or explicitly trusted hosted compute.

Calling a hosted execution server a “node” does not remove this trust. If the requirement literally prohibits sending decryption authority or plaintext to any server, private computation must remain on user devices, absent specialized cryptographic computation or additional hardware assumptions.

Private computation runs on authorized devices or organization-controlled execution endpoints. Hosted infrastructure stores and relays ciphertext.

Delegating computation elsewhere is an explicit security-relevant action, not an invisible load-balancing optimization.

Confidential computing could eventually supply another execution profile, but it introduces attestation, hardware, firmware, rollback, and side-channel assumptions. It should not be the unexplained mechanism making the initial promise work.

Also, “nothing sensitive on disk” must cover logs, temporary files, crash dumps, swap, backups, and VM snapshots containing memory—not just the application database.

3. The foundational primitive should be a protected stateful object

The VM is too low-level. A whole application is too coarse.

A better conceptual primitive is:

A durable object with an identity, a policy, and capabilities for specific observations and state transitions.

This need not mean one process per database row. It is the authority model; execution can be batched and pooled.

For example, an expense object might expose:

read_receipt
submit
request_changes
approve
export_for_payment

These are not equivalent to unrestricted read and write.

The distinction matters:

The application supplies the workflow and presentation. A separately authorized policy defines the permitted transitions.

An illustrative policy:

Receipt visibility:
  requester and finance reviewers

Submission:
  requester must be the authenticated caller

Approval:
  finance reviewer
  reviewer must differ from requester
  amount must fit the approval grant

External export:
  disabled unless separately authorized

The policy must not be editable by ordinary application code. A generated application may propose a policy change; it cannot approve its own proposal.

This is not a demand to build every business rule into the runtime. The runtime needs a small policy/transition enforcement mechanism, with reusable policies and independently approved validators above it.

An interface describes how to invoke an operation. A security contract also describes when the operation is permitted and what it may change. WIT alone does not supply the latter.

Why this is a product rather than just infrastructure

For an internal tool, the platform can eliminate entire recurring tasks:

The developer writes the tool’s particular behavior, rather than reconstructing the security foundation.

4. Capabilities need an information-flow policy

This is the largest missing piece in a capability-only story.

Consider an application with:

  1. Read access to confidential HR records.
  2. Write access to an organization-wide wiki.

Both capabilities are individually legitimate. Together, they permit disclosure.

Removing unrestricted networking does not solve this. A replicated feed is an output channel. So are logs, notifications, shared files, clipboard writes, rendered links, and model-provider requests.

Internet2’s idea that apps communicate through granted interfaces is the right starting point. But “no network import” cannot mean “no exfiltration” when a granted interface publishes data.

A tractable initial policy

Avoid starting with a universal fine-grained information-flow language.

Instead:

If a job combines two datasets, its output ordinarily inherits the intersection of their permitted reader sets.

This can initially operate at job or component granularity rather than tracking every value.

It will reject some useful operations. That is the real cost of confidentiality—not an implementation inconvenience to silently bypass.

A controlled export can cross the boundary. But “send arbitrary text to Slack” is not a safe export merely because the Slack token stays inside a broker.

A safer operation might be:

notify_approver(expense_reference)

The trusted connector chooses the destination and a fixed notification format. It does not accept arbitrary secret-bearing text from the app.

Hails is a particularly relevant precedent: untrusted application functionality with data policy enforced independently of ordinary application logic. Sandstorm is also a closer product/security precedent than BEAM alone.

Neither should be treated as proof that the proposed system will work. They demonstrate that the design space extends beyond choosing a sandbox.

5. One codebase, several deliberately separate trust boundaries

The new system can unify the ideas without making every subsystem equally privileged.

A. Authority and key management

Responsible for:

Applications receive handles, not root keys or general-purpose signing authority.

Effective authority combines the caller’s authorization, the application’s grant, the object’s policy, and current constraints. Background jobs receive their own bounded delegation rather than impersonating an unrestricted user.

B. Durable data

Provides:

Homefront’s separation between local persistence and remote confirmation is important to preserve.

However, signed history is not automatically authorized history, complete history, or semantically valid history. Each requires its own validation.

C. Execution

Two useful execution backends:

Both connect through the same authority system.

But compatibility has a cost: an unchanged legacy application may own its database and implement its own authorization. In that case, it remains trusted for those internal decisions. The platform can contain it, but cannot retroactively enforce business rules hidden inside it.

Support arbitrary code; do not promise arbitrary existing applications the strongest guarantees without adaptation.

Wasm and microVMs are also complementary defense layers. A Wasm worker can run inside an OS-isolated process or VM. Neither requires placing the key manager, network parser, package builder, and untrusted workload in one address space.

D. Placement and scheduling

The scheduler decides where an authorized workload runs—not what it may access.

Placement must preserve:

An overloaded trusted machine should not cause a private job to migrate silently onto an unapproved machine.

Scheduling permission is not decryption permission.

E. User interface and software loading

The trusted shell owns:

Application UI code does not get to impersonate those surfaces.

A semantic UI interface, as explored in Internet2, is useful here. It need not require a new graphics engine: a trusted renderer can use ordinary browser technology while sandboxed components submit constrained presentation data.

Do not put rebuilding text layout, a GPU material system, or a replacement browser on the critical path to secure internal tools.

F. Connectors

External services are explicit trust boundaries.

A connector should retain the external credential and expose narrow operations over selected resources. Incoming documents, webhook payloads, and model outputs remain untrusted data.

For agents, this is crucial:

A document may suggest an action. It cannot grant permission to perform it.

Prompt injection can still persuade an agent to misuse its allowed authority. The platform’s job is to make that authority small enough, and consequential actions constrained enough, that persuasion does not become unrestricted access.

One executable can launch these roles as separate processes. One repository does not require one security domain.

6. Several earlier design choices should not survive unchanged

These are disagreements with architectural choices, not criticisms of unfinished implementations.

“Check at mint; possession is proof”

This is excellent for preventing forged handles and avoiding repeated namespace-based authorization mistakes.

It does not eliminate changing conditions.

A valid handle can outlive:

The solution is not scattered authorization checks. It is a handle whose implementation centrally enforces its current validity and state-dependent constraints.

There is another subtlety: attenuation is not conservation. A parent grant allowing ten uses cannot safely produce ten independently redeemable children each allowing ten uses.

Global usage limits require shared accounting, allocated spending rights, or another explicit conservation mechanism. Signatures and subset checks alone do not provide it.

“A content hash is the capability”

A hash of predictable plaintext is not a secret. An attacker can compute candidate hashes.

Use content hashes for identity and integrity. Use separately justified authority for access. Where encrypted content addresses function as bearer references, state the secrecy and leakage assumptions explicitly.

“Only fire-and-forget calls should cross the network”

An asynchronous message primitive is reasonable. Making every app author reconstruct delivery tracking, timeout handling, and reconciliation is not a secure-by-default developer experience.

A library can expose:

await operation.result()

without pretending the network cannot fail.

The required distinction is between:

For external effects, a timeout must not imply “nothing happened.” Durable operation identities, idempotency where supported, and explicit reconciliation belong in the platform’s supported programming model.

Moving complexity out of the kernel is useful. Moving it into every application is often not.

“There is no server”

“No compulsory vendor-controlled server” is an excellent property.

“No server roles” is not a useful universal constraint. Some actions require an available authority to order them. An always-on organization node can supply that without owning everyone’s identity or plaintext storage.

Likewise, a native implementation does not leave the trusted computing base merely because it could have been implemented as an isolated component. Trust follows actual failure consequences, not architectural vocabulary.

7. Global invariants require choosing consistency, not just isolation

A sandbox cannot establish:

Nor does a CRDT establish those properties merely by converging.

The new platform should distinguish:

Collaborative state: notes, comments, drafts, annotations. Offline changes and merging are often appropriate.

Authoritative transitions: approvals, spending, membership, irreversible actions. These need an explicit acceptance order, or a specialized coordination-free construction with a proved invariant.

Initially, use one logical authority per workspace for those transitions. Replication can improve availability later.

If that authority is unreachable, preserve drafts and pending requests—but do not claim an approval has completed.

This also clarifies revocation:

The UI must display these distinctions honestly. Security includes not telling someone that an operation succeeded when its outcome is unknown.

8. Formal verification should target the policy-enforcement core

The mission should not depend on proving every generated tool correct.

The highest-leverage proof targets are the components that let untrusted tools operate safely:

  1. Authority cannot amplify through delegation, invocation, restart, or migration.
  2. Resource handles cannot designate resources outside their grants.
  3. Policy changes require separate authority.
  4. Accepted transitions preserve specified state invariants.
  5. Confidentiality restrictions propagate through supported output channels.
  6. Revocation and budget accounting obey their stated acceptance semantics.
  7. Recovery cannot silently restore obsolete authority or reuse cryptographic state unsafely.

State the assumptions: runtime, compiler, OS, hardware, cryptographic primitives, trusted endpoints, and excluded channels. An abstract proof is not automatically a proof about deployed binaries.

Affetto’s ideas are useful here: owned authority, constrained effects, explicit resource lifetimes, and simulated handlers. But Homefront should not wait for a complete new language, nor require application developers to adopt one.

Use stable interfaces that Affetto can eventually target. Initial SDKs should meet developers and coding agents where they already work.

The decisive adversarial test is:

Replace a legitimate component with one deliberately trying to violate the contract. Do the protections still hold?

Then test the same thing across crashes, retries, partitions, stale backups, updates, and permission changes—not only isolated function calls.

9. The first product should be much narrower than the eventual runtime

A good initial customer is a small engineering organization or research lab building private operational tools:

These exercise meaningful permissions without requiring an entire replacement computing environment.

The initial product should provide:

The developer experience should resemble:

Create tool
→ define data and actions
→ choose/review policy
→ build UI
→ test with synthetic users
→ publish privately

Not:

Design a distributed protocol
→ implement authorization
→ invent an effect discipline
→ wire component resources manually
→ debug cryptographic synchronization

A coding agent should get a complete SDK, working examples, policy tests, and a local simulator. It should be able to generate the ordinary parts without being trusted to invent the security architecture.

What not to build first

An anonymous, zero-authority preview can be useful. Anonymous arbitrary compute is principally an abuse-management product.

Company value

The commercial offering can sell deployment, availability, encrypted backup, managed organization compute, connector maintenance, fleet administration, and independently assessed assurance.

The security contract itself should not disappear in the self-hosted edition. Basic confinement, usable authorization, and encryption cannot be premium exceptions to “secure by default.”

The differentiator is not simply cheaper hosting or more built-in services. It is:

Teams can change their tools quickly without repeatedly entrusting new application code with organization-wide credentials and security decisions.

The constraint to put at the top of the new specification

Application code may compute and propose actions within granted authority. It may not redefine the authority, confidentiality, or acceptance rules governing those actions.

That is the synthesis worth pursuing:

But with a sharper product boundary: data and policy belong to the workspace; applications are replaceable participants.

That is the tool worth reaching for by default when asked to build an internal application—not because its programs are guaranteed to contain no bugs, but because many important security properties no longer depend on those programs being correct.

Sources and review scope

The repositories consulted for this review are listed below; repository access may be required:

Affetto was reviewed separately; it was not copied, moved, or modified. Other architectural context includes the browser essay and the Hails and Sandstorm references linked above.

This was an architectural review of specifications and selected implementation/security paths, not an exhaustive code audit or test run. Existing implementations, proposals, and formal guarantees should not be conflated; the recommendations above describe a new system, not properties already established by the reference projects.