Skip to main content
Alex GriffithsDotNetGeek
← Back to experiments

SafeNet

Prototype

2019 – Present

I wondered if...

we redesigned the web today using everything we've learned since it began, What would the web look like?

A long-running thought experiment exploring what a modern web could look like if identity, trust, provenance and user ownership were designed into the network from the beginning.

The Question

The web we have today is the web that happened, not the web anyone sat down and designed.

Over the last thirty years we've continuously adapted it to solve new problems. Security was added. Identity evolved separately. Privacy became an application concern. Trust was pushed out to individual websites and platforms.

Considering how all of that evolved, the web has done remarkably well.

It did leave me wondering though...

If we could start again today, with everything we've learned over the last thirty years, what would we build differently?

SafeNet isn't an attempt to replace the Internet.

It's a long-running engineering thought experiment.


The Problem

I grew up alongside the web.

I remember how exciting it was when suddenly anyone could publish ideas, learn almost anything and communicate with people on the other side of the world. It genuinely felt like one of humanity's greatest inventions.

I still think it is.

But somewhere along the way the incentives changed.

Many services no longer exist simply because they're useful. Attention became the product. Personal information became something to collect and monetise. Advertising became the business model that shaped almost everything else.

The result is a web full of tracking, duplicated identity, fake traffic, questionable information and websites that all solve the same problems independently.

Every service wants me to create another account.

Every service stores another copy of my personal information.

Every service decides its own approach to identity, permissions and trust.

AI has only made some of those problems more obvious.

We're rapidly reaching a point where understanding where information came from is becoming just as important as the information itself.

That left me wondering whether many of these problems actually belong much lower down the stack.

Maybe they're not website problems.

Maybe they're network problems.


The Hypothesis

The more I thought about it, the more I realised I wasn't really questioning websites.

I was questioning the assumptions we've built the web on.

One of those assumptions is that every website should be able to send executable code to my computer.

That made perfect sense in the 1990s.

Today it also creates one of the biggest attack surfaces on the Internet.

SafeNet explores a different model.

Instead of downloading HTML, JavaScript and whatever other code a website decides to send me, a SafeNet site would simply describe itself.

Pages would be delivered as structured JSON describing content, layout, styling, interactions and data requirements. The SafeNet client would then render that description using its own built-in rendering engine.

The experience could still include animations, responsive layouts, forms, 3D environments and everything people expect from modern applications.

The difference is that websites wouldn't be able to execute arbitrary code on the client.

That removes an enormous attack surface and gives the platform complete control over the capabilities available to every site.

The browser also becomes something quite different.

It's no longer just a window onto the Internet.

It's a trusted application that understands identity, permissions, rendering and communication as part of the platform itself.

Identity follows the same philosophy.

Instead of every website collecting and storing my personal information, sites would request access to specific pieces of information when they genuinely needed them.

Need my delivery address?

Ask for it.

Need proof that I'm over eighteen?

Ask for that instead.

Need my date of birth?

Probably not.

The information remains mine.

The website is simply granted permission to use it.

Changing my address becomes a single update instead of visiting dozens of different websites.

Permissions become visible, auditable and revocable.

Another idea I've been exploring is provenance.

Every SafeNet site would publish a manifest describing where its information comes from, who owns it, whether AI was involved in creating it and how it has changed over time.

The platform could then make that information visible before the user decides whether to trust what they're reading.

I'm deliberately not trying to build a censorship system.

The goal isn't deciding what's true.

The goal is making provenance visible enough that people can make better informed decisions.

The same thinking extends to the platform itself.

SafeNet would define a set of platform rules that every published site agrees to.

Not because I want to control the web, but because every platform already encodes a set of values.

SafeNet simply makes those values explicit.

Things like user privacy, transparency, provenance, identity and security become part of the platform rather than something every individual website has to reinvent.

The funding model follows the same principle.

I don't want the platform's incentives tied to advertising or engagement.

A modest subscription feels like a much healthier relationship. If users pay for the network, the network works for its users.

Finally, I've been exploring whether distributed ledger technologies have a role in supporting identity, permissions, ownership and digital rights.

I don't know whether blockchain is the right answer.

SafeNet exists so I can explore questions like that without pretending I already know the answer.

SafeNet is an experiment in what the web might look like if trust, provenance and user ownership were designed into the platform from the very beginning.

Approach

SafeNet spent years as a folder of notes before it became code. The danger with a project this size is that it stays a notes folder forever, so I forced it into the shape of a proof of concept.

I wrote a project specification and broke the work into phases. The mini network and identity layer first, then the personal data vault and capability grants, then recipe capsules, policy and a transparency log, then manifest enforcement, and finally a demo that ties everything together.

For each phase I keep an open-questions document alongside the design. Before I write any code I try to write down every question I can't answer, then force myself to answer it in writing. Some of those documents ended up longer than the code they describe. I've made peace with that.

I also gave the project a grounding scenario to stop it drifting into pure philosophy. A shop asks for my delivery address so it can ship me something. It's allowed to keep the address for thirty days and share it onward with one named carrier. When I revoke the grant, both the shop and the carrier lose access. If SafeNet can't express that scenario cleanly, none of the grander ideas matter.

I hadn't used Rust before this project, but SafeNet needed a small, predictable systems layer with explicit control over memory and concurrency. The project became the reason to learn it.

The rendering engine could wait. The ideas I was least sure about all lived in the identity and data layers, so that's where the prototype started.


Architecture

The prototype is a Rust workspace of deliberately small services, with a couple of Node components around the edges.

safenetd is the gateway daemon. It refuses to serve a site unless the site provides a signed manifest, verified with an Ed25519 public key before anything is served. It also hosts the endpoints for the transparency log and can replicate log entries from peers.

The personal data vault encrypts records with XChaCha20-Poly1305 and stores them in PostgreSQL. Alongside the storage sits a grant store that models capability grants with delegation. A shop can delegate a subset of its access to a carrier, and revoking the shop's grant cascades down and invalidates the carrier's too.

The policy engine evaluates rules written in YAML. A rule has a condition, a set of allow and redact patterns over vault URIs like pdv://address/*#phone, and a retention duration. The shipping demo's policy allows a carrier to see the address fields it needs and redacts the phone number unless the delivery is flagged as needing a call.

The symbolic recipe VM is a tiny interpreter with five opcodes — substring, match, dictionary mapping, hash and range check — each running under a safety budget that caps literal sizes, dictionary entries and regex pattern length. Its job is to answer questions about my data without handing the data over.

The federated log is a Merkle tree using RFC 6962-style hashing, with append, head and consistency-proof endpoints and simple peer replication.

Around the Rust core sit a Node wallet that handles consent requests and grant lifecycle, a Node runtime service that validates site manifests, SDKs in Rust, TypeScript and Python, a small CLI, and a docker-compose file that brings the whole thing up with PostgreSQL.


Interesting Challenges

Answering questions without revealing data. The over-eighteen check from the hypothesis sounds trivial until you try to build it. If a site can run arbitrary code against my date of birth, I've already lost. The recipe VM came out of this: the site sends a small, bounded computation to the data, and only the answer comes back. A range check proves I'm over eighteen. A hash proves two records match. A substring returns the part of the postcode a courier actually needs. The safety budgets exist because a VM like this is also a lovely exfiltration tool if you let a recipe build arbitrarily large outputs or pathological regexes.

Delegation without losing control. Sharing my address with a shop is one problem. The shop sharing it with a carrier is a different one. Grants ended up forming a tree, where a delegated grant can only carry a subset of its parent's onward-share rights, and revoking a parent invalidates every child beneath it. Getting the cascade right was fiddly, and it convinced me that delegation has to be modelled from the start. Bolting it onto a flat permission list later would be miserable.

Hand-drawn notebook sketch of the grant delegation tree: my address in the vault at the top, a grant to a shop beneath it carrying a thirty-day retention and permission to share onward with one named carrier, a delegated grant to that carrier below which is a subset only and cannot be re-shared, a policy card allowing the address lines and redacting the phone number, and a red strike through the top grant with a dashed arrow showing the revocation cascading down and killing the child grant too

The shipping scenario is deliberately small, and it still took a tree to express. Revoking the shop's grant has to take the carrier's with it, or the guarantee means nothing.

"Thirty days" from when? Retention sounded like the easy part of the policy language until I asked what the clock starts counting from. When the data was collected? When it was last served? When the agreement took effect? Each answer produces genuinely different behaviour, so the policy engine supports all three retention clocks and a policy has to say which one it means. I spent a whole follow-up document arguing with myself about this.

How much proof does a transparency log need? Full RFC 6962 inclusion and consistency proofs are well understood but a meaningful amount of work. I implemented a simplified consistency proof instead and wrote the compromise down in the code comments, so future me knows exactly what the log does and doesn't guarantee. For a prototype whose job is to test whether provenance logging belongs in the platform at all, that felt like the right trade.


What Went Wrong

SafeNet has been one of those projects where every answer seems to create two new questions.

When I started it, I genuinely thought I'd be spending most of my time building a new way of serving and rendering web applications.

That idea is still there.

The funny thing is I haven't really got to it yet.

Every time I peeled back another layer, I found something else that needed understanding first. Identity became permissions. Permissions became grants. Grants became policy engines. Then came cryptography, provenance, secure storage, distributed networking and trusted communication.

Before I knew it, I'd built a collection of libraries and services exploring the foundations of the platform, while the renderer that originally inspired the whole project was still sat on the whiteboard waiting for its turn.

I'm actually fine with that.

SafeNet was always meant to be an experiment, and the journey has turned out to be far more interesting than the route I originally imagined.

Quite a few of the ideas explored here have already influenced other projects. The work around provenance, permissions and semantic relationships ended up feeding directly into Chronos, while some of the thinking around trust and AI context found its way into DeliveryIQ.

The renderer is still on the list.

It's just patiently waiting while I finish exploring all the interesting rabbit holes I found on the way there.


One example is the network itself.

The original design describes a secure overlay network built around encrypted communication and custom protocols.

Today's implementation is much simpler.

The ideas are still there, but they're deliberately being explored in isolation before I commit to building the complete stack. I'd much rather prove individual concepts than spend months building infrastructure only to discover the underlying assumptions were wrong.


Another lesson came from the developer tooling.

At one point I wrote three SDKs for services that barely existed.

It felt productive.

The APIs were documented, the client libraries compiled and everything looked like it was moving forwards.

Except the services themselves hadn't caught up.

Looking back, I should have built one complete end-to-end path before expanding the ecosystem around it.

It's a mistake I'll probably make again because I genuinely enjoy designing APIs, but it's a good reminder that a working system always teaches more than a beautifully designed interface.


SafeNet also taught me that trust rarely fails in the places you expect.

The cryptography wasn't the difficult part.

The policy engine wasn't the difficult part.

The difficult parts were things like consent flows, key management and all the unglamorous plumbing that quietly determines whether a system is actually trustworthy.

They're the sort of components nobody notices when they work.

They're also the parts everything else depends on.


The final lesson is probably the most important.

SafeNet isn't one project.

It's a collection of experiments exploring different aspects of the same question.

Some of those experiments have become libraries.

Some are prototypes.

Some exist only as notes and architecture sketches.

Others have influenced completely different projects, particularly Chronos and DeliveryIQ.

The renderer that originally inspired the project is still waiting for its turn.

I haven't abandoned that idea. I've simply found a lot of interesting questions on the way there.

What's Next

SafeNet is still very much an active project.

The difference is that I now understand the problem space far better than I did when I started.

The immediate goal is to connect the pieces that already exist into a complete end-to-end scenario. That means exposing the grant and policy engines through the vault, completing the consent flow and turning today's scripted demonstrations into a working system.

After that I want to return to the original question that started the project.

Can a structured, client-rendered web experience provide the flexibility people expect without requiring websites to execute arbitrary code?

That feels like the right point to reconnect all of the ideas explored so far.

Beyond that, there are still plenty of open questions.

  • Does the network itself need to change, or can most of these ideas sit on top of today's Internet?
  • How much of identity, trust and provenance belongs in the platform, and how much belongs in applications?
  • Can distributed ledgers genuinely add value, or are simpler transparency mechanisms enough?
  • What is the smallest useful renderer that proves the idea without becoming another browser?

SafeNet has already answered some of the questions I started with.

The interesting thing is how many new ones it's created along the way.