Why Ownly does not Work on the ndn6 Network? A Decade of #2856

New Year's Eve 2024, Sydney. A user opened Ownly (then called NDN Workspace), the flagship NDN application developed and published by UCLA Internet Research Laboratory. Her laptop could reach the network, but it couldn't publish. Every attempt to register a prefix was met with a blunt "403 prefix-disallowed" error.

This article looks back on operations of two NDN networks under different philosophies, analyzes why the Ownly application is incompatible with one of the networks. Then I present the lessons learned and identify the practical gaps on why NDN is not ready for transitioning from a "UCLA experiment" to a "global Internet".

ndn6 Network and NDN-FCH 2021

Since 2021, I (re)started operating the ndn6 network, my own global scale NDN network. The ndn6 network is connected to the global NDN testbed but not a part of it. It's an independent network that conforms to the NDN protocol, but has its own routing protocol and prefix registration policies.

The same year, I participated in the NDN-FCH: The Big Rewrite™ project at the 11th NDN Hackathon, during which I led a team to build a new version of "Find Closest Hub" service:

NDN-FCH 2021 is an online service for finding available Named Data Networking routers near the client on the global NDN testbed and other connected networks.

This "big rewrite", compared to the original FCH service from 2016, is designed to have better robustness and more precise geolocation data. It includes automated health probes toward each router, so that most routers returned from the API are confirmed to be reachable on the data plane. More importantly, it could dole out links to "other connected networks", i.e. NDN routers on the ndn6 network.

After the hackathon, I continued building the ecosystem around ndn6 Network and NDN-FCH 2021 service. I updated NDNts @ndn/autoconfig package to call my own NDN-FCH 2021 API. My experimental video streaming service, NDN push-ups, could invoke NDN-FCH 2021 API to discover both WebSocket gateways on global NDN testbed routers and HTTP/3 WebTransport gateways on the ndn6 network, and connect to whichever router that responds the fastest. The video player, regardless of which router it connects to and which transport protocol it chooses, would send Interests under /yoursunny/pushups prefix that are forwarded to a file server that hosts the video segments, while the network provides Interest aggregation and Data caching benefits to reduce workload of the file server.

The Deep connectToNetwork API

Since 2023, UCLA Internet Research Laboratory (IRL) started developing NDN Workspace. Workspace is a decentralized collaborative editor, where users can create shared workspaces and collaborate on group files. Each participant maintains a local copy of the workspace, and propagates the encrypted and signed updates using State Vector Sync (SVS) protocol over the NDN network.

Their initial version was built with my NDNts library, which, at the time, was the only NDN development library that could operate in a browser environment. Naturally, they imported @ndn/autoconfig package to establish "testbed connectivity". Here's the function call:

import { connectToNetwork } from "@ndn/autoconfig";

const faces = await connectToNetwork();

This function call looks deceptively simple, but it is one of the "deep" APIs in the NDNts library. It implements the following procedure:

  1. Determine the supported transport protocol, which would be WebSocket in the browser environment when the WebTransport library isn't imported.
  2. Query the NDN-FCH 2021 API to discover four nearest NDN routers that support the desired transport protocol.
  3. Attempt to connect to each of these routers, send a probe Interest /localhop/nfd/rib/list that could be answered by every NFD instance configured as a router, and measure the round trip time.
  4. Keep the connection to the fastest router, and close the other connections.

If the function executes successfully, the browser would have a connection to a nearby NDN router. For the Workspace developers sitting in a UCLA lab, it is certainly the suns.cs.ucla.edu machine in their building. For visitors elsewhere in the world, this could be either a global NDN testbed router or a router in the ndn6 network.

The two networks, despite having different routing protocols, are interconnected. Some of my ndn6 routers have UDP tunnels to a nearby testbed router. Across each of these tunnels, I configure a /ndn route pointing to the testbed router, and register a /yoursunny prefix on the testbed router pointing back to the ndn6 router. With these manual routes, an Interest with /ndn prefix hitting an ndn6 router would be forwarded to the testbed, while Interests starting with /yoursunny in the testbed are forwarded to the ndn6 network.

This works perfectly for a consumer application such as my video streaming service: regardless of which network the client connected to, an Interest for /yoursunny/pushups is always coming to my file server. Moreover, routers in both networks could perform Interest aggregation and Data caching, for more efficient content retrieval by the clients.

The Sydney Incident

By 2024, the ndn6 network has grown to 12 nodes around the world, after my acquisition of cheap LowEndTalk VPS dealz around Black Friday. I have nodes in "usual" locations such as Chicago and Amsterdam, and less common locations such as Sydney and Mumbai. In contrast, the global NDN testbed is limited to hardware donated by participating universities. They have many nodes in the United States and Western Europe, but have no presence in Australia.

New Year's Even 2024, I was contacted by a Workspace developer:

I am speaking on behalf of workspace. we had a workspace client in Australia and got directed to your network (the closed Testbed router is in Singapore but you have one in Sydney) then got 403. Looks like workspace, by the current design, violates your "localhop" policy. Not your problem but ours of course.

Apparently, their user traveled out of the UCLA bubble and entered my territory. A prefix registration command sent by the Workspace application was trying to register /ndn/irl-workspace/20240525 with the signing identity /ndn/edu/ucla/cs/lixia. It has violated the strict prefix registration policy enforced by the ndn6 network, which includes this rule:

Each prefix must start with either the identity name of your certificate or one of these multicast prefixes: /ndn/broadcast, /ndn/multicast, /yoursunny/M.

NFD Automatic Prefix Propagation

NDN Forwarding Daemon (NFD) introduced Automatic Prefix Propagation feature in 2015. With this feature, when the user starts a producer application on an end host, the NFD instance running on the end host, upon seeing the prefix registration command from the producer application, would automatically generate a new prefix registration command and send it to the NDN testbed router. The second prefix registration command is sent under the prefix /localhop/nfd/rib/register, which has an implicit HopLimit of 1, allowing it to reach the testbed router.

The policy is described in NDN Automatic Prefix Propagation technical report and hard-coded in NFD HostToGatewayReadvertisePolicy class:

  1. The end host NFD must have a /localhop/rib route to signify a connection to the testbed router.
  2. The application prefix must not start with /localhost, because those are intended for local use only.
  3. The end host NFD's keychain must have a key whose identity name is a prefix of the application prefix.
  4. Shortest prefix match is used to choose a propagated prefix when there are multiple matching keys.

Following the rules, we can expand from an example given in the technical report:

application prefix keychain identity propagated prefix
/ndn/ucla/alice/app1 /ndn/ucla/alice /ndn/ucla/alice
/ndn/ucla/alice/app2
/ndn/ucla/bob/app3 /ndn/ucla/bob /ndn/ucla/bob
/ndn/ucla/bob/app3 (none)
/ndn/ucla/carol/app4 (no match) (none)

This was tricky to setup, but with some effort I can get it to work between my end host and the testbed.

NFD Feature #2856: Confine registered prefix within identity

Yanbiao Li, the developer responsible for this feature, implemented the "client side" policy accurately in the end host NFD. However, the "server side" for these prefix registration commands, running on the NDN testbed routers, is less precise.

The NDN Automatic Prefix Propagation technical report states:

While on the remote gateway, the NFD is configured with at least one trust anchor. Later, only those propagations whose signing keys are directly or recursively signed by trust anchors can be authenticated.

However, in the actual implementation, trust schema, coded in "validator config" syntax, effectively says:

  1. A prefix registration command under /localhop/nfd/rib/register must be signed by an ECDSA key.
  2. The certificate associated with the ECDSA key must be traceable to the testbed root anchor CA certificate, following the hierarchical trust model.

It is missing a critical link:

  • It allows any ECDSA key holder authorized by the testbed root to sign a prefix registration command of any prefix.
  • It does not check whether the identity name of the ECDSA key is same as or a prefix of the prefix being registered.

For example, if a user has a key with identity name /ndn/ucla/alice issued by the testbed CA, she could hand craft a prefix registration command for the prefix /ndn/ucla/carol, and the testbed router would have no hesitation in accepting this command. In other words, the application prefix is not confined within the identity name of the user's key.

I alerted the NDN testbed operator, Dr John DeHart, about this situation on 2015-05-28. His reply was:

I think it makes sense for the prefix a user or user app can remotely register be confined. And I think the natural confinement is to the identity of the user.

However, during a group discussion on 2015-06-05 NFD call, we concluded that it is impossible to implement the prefix confinement feature in the existing "validator config" trust schema syntax. The prefix registration command is encoded as nested TLV object, where the application prefix, cost, and other optional properties are encoded in one TLV and embedded into a name component. On the other hand, the "validator config" syntax is only able to match the entire name component, but cannot drill into the sub-TLVs inside the parameters structure.

This technical limitation left NFD "blind" to its own security requirements. I posted NFD Feature #2856: Confine registered prefix within identity on 2015-06-06:

In prefix registration, confine registered prefix to the signer's identity.

  • Add a prefix_confinement boolean option to RIB configuration. The following rules apply only if this option is set to true.
  • A prefix registration/unregistration command is rejected if the signer's identity is not a prefix of the registered prefix.

Despite this issue being posted in 2015, it remained "New" because, in a "testbed", everyone is a friend and can be trusted.

In 2015, we realized the front door of the NDN testbed was unlocked. For a decade, despite this issue being resurfaced multiple times during discussions, the community's response has been to hope no one notices. In Sydney, someone finally walked through the wrong door.

Prefix Registration Policy in the Two Networks

Global NDN testbed replaced their Ansible setup with Docker Compose, but the same "validator config" trust schema is still in use as of 2026. On the global NDN testbed, anyone could register any prefix, as long as you have a testbed authorized certificate.

In ndn6 network, I built the "enforcer" that NFD refused to be: ndn6-prefix-proxy.

  1. The ndn6-prefix-proxy tool listens on /localhop/nfd/rib/register to receive prefix registration commands from end hosts.
  2. Since the tool isn't restricted to "validator config" syntax, it could decode the prefix registration command and extract the application prefix, and then compare it with the signing key's identity name.
  3. If the policy check and crypto validation are both successful, the tool sends an equivalent prefix registration command to NFD under /localhost/nfd/rib/register, and relays the outcome to the end host.

The specific command line I used on ndn6 routers is:

ndn6-prefix-proxy \
  --anchor /etc/ndn/certs/root.ndncert \
  --anchor /etc/ndn/anchor/testbed-2204.ndncert \
  --open-prefix /ndn/broadcast \
  --open-prefix /ndn/multicast \
  --open-prefix /yoursunny/M

With this command line, the ndn6 network would accept certificates issued by either the testbed CA or ndn6's private CA. It allows arbitrary registrations under three "open" prefixes for multicast, while all other registrations have #2856 confinement. I also intentionally "broke" localhop_security schema so that the /localhop/nfd/rib/register command handler in NFD itself would reject all commands, in case ndn6-prefix-proxy isn't running, while the /localhop/nfd/rib/list dataset remains operational to satisfy the probe Interest sent by NDNts connectToNetwork() API.

A "polite" end host running NFD and having a testbed certificate would be able to register prefixes on both the global NDN testbed and the ndn6 network, because Yanbiao's implementation ensures the propagated prefix matches the certificate's identity name. On the other hand, applications developed with NDNts could be less "polite".

NDNts's @ndn/nfdmgmt package provides the mechanism of generating and sending a prefix registration command to NFD, but does not enforce the "voluntary" policy as in NFD's HostToGatewayReadvertisePolicy class. The API accepts a Signer interface that abstracts the procedure of choosing a key and producing the signature. In the basic examples, I typically pass a single ECDSA key pair as the Signer, because the simplest producer application only needs one prefix. If the application needs to register multiple prefixes that require distinct signing keys, it is possible to construct a custom Signer that chooses the appropriate signing key for each command.

Workspace, following my examples, reuses the same key pair for everything. When a client tries to register a prefix not covered by this key pair, a 403 error is the ensured outcome.

From Workspace to Ownly

UCLA is obviously unhappy with my "high bar of entry" for new features in NDNts, as I demand written specifications for every protocol and feature before implementing, which does not match their desired velocity. They used to maintain a NDNts auxiliary repository to monkey-patch my library, but it isn't feasible to support every feature they wanted. In 2025, they decided to abandon the NDN Workspace codebase and start from scratch in a new codebase: Ownly.

Ownly shares the same "decentralized workspace" design concept but switches to a different programming language: Go. It is based on their NDNd protocol stack, which encompasses the YaNFD forwarder, a distance vector routing protocol, State Vector Sync (SVS), and Light VecSec trust schema syntax. The Ownly application revised the SVS sync prefix, introduced content encryption, and switched the UI library from Solid to Vue. The web application is now a massive 14 MiB WebAssembly binary that includes all the batteries, including a basic NDN-FCH 2021 client that I helped them porting to NDNd during 17th NDN hackathon.

Despite the facelift, Ownly still uses a skeleton key for every door: all prefix registration commands are signed by the same testbed key, which inherits the same behavior as Workspace. During the initial launch, users in Washington DC reported intermittent errors because they are halfway between the Chicago node of ndn6 network and the Boston node of global NDN testbed. If the FCH client connects them to Chicago, their prefix registration commands would be rejected.

Following my advice, Ownly developers have chosen the shortcut: deyoursunnyify the connection. They specified ?network=ndn parameter in the NDN-FCH 2021 request, so that the NDN-FCH API would filter the results by network operator and only return routers on the global NDN testbed, rejecting nodes operated by @yoursunny i.e. myself. Effectively, they have chosen to dodge the incompatibility issue by stop driving on the roads that check IDs.

In 2026-05-11, I briefly checked the prefix registration commands sent by the Ownly web application, and I can determine that they still do not conform to the #2856 confinement policy. One of the prefix registration command seen on the wire is:

05fd014407a008086c6f63616c686f7008036e6664080372696208087265676973746572085e685c075408036e646e08146f776e6c792e6e616d65642d646174612e6e6574080c7765656b6c792d63616c6c730804726f6f7408036e646e080365647508076172697a6f6e61080a7368696a756e7869616f380469fe849d6f01416a010002204d9dc12a41e7989a08dba466621d890fac60ee3f8d3b2178c97edec68251d3c512000a044233d77f0c0203e824002c491b01031c30072e08036e646e080365647508076172697a6f6e61080a7368696a756e7869616f08034b45590808ea59348d08f9ddad2608cb36250dd4dd999d28080000019e189accd52e473045022000c98dd6fb73e4b8f119de7e0d23a257b54509d7977df699dd3a5c10bb92c5d4022100e5c961aea453091b60dc016eeb40e6b0cf1383cdb78b28fb0acb164382722187

Decoding with NDN-Play reveals what's inside:

prefix registration command

We can see that the signing identity /ndn/edu/arizona/shijunxiao is not a prefix of the registered prefix /ndn/ownly.named-data.net/weekly-calls/root/ndn/edu/arizona/shijunxiao/t= 1778287773. Although the global NDN testbed operated by a UCLA-led team is accepting this prefix, it would not be accepted by a router in the ndn6 network or any other router that enforces the #2856 confinement policy.

Should #2856 be Rejected?

Shortly after the Sydney incident, I asked the Ownly developer:

The counter question: how does SVS plan to support NFD when #2856 confinement is implemented?

Their answer was:

I think the network should adapt to app requirement, not the opposite

I replied:

Go ahead and set #2856 as Rejected. For many years, in my nightmares, I see #2856 gets implemented and deployed, breaking my /yoursunny registration.

I got a 🤌 emoji but there was no further action.

It is ironic that the /yoursunny prefix registration that I injected into the global NDN testbed to bring traffic to the ndn6 network is itself an exploitation of the testbed's lack of #2856 confinement. The testbed CA can only issue certificates that match a client's email address or DNS name, such as /ndn/contoso.com or /ndn/someone%40contoso.com; it isn't possible to obtain a certificate for /yoursunny signing identity following normal NDNCERT procedures.

To me, #2856 is a double edge sword.

  • As an application developer, I want the feature Rejected. If the global NDN testbed starts to enforce prefix confinement, I would have to stop squatting on the "illegal" /yoursunny name. I would have to either renumber rename all my producers, or require every consumer to attach a forwarding hint of my "legal name" to reach my producers.
  • As network operator, I want this feature. Without it, anyone can announce /yoursunny/pushups/20231031 in the network and hijack one of my push-up videos.

The global NDN testbed remains a "UCLA experiment" where trust is assumed. The ndn6 network tries to be an "NDN Internet" where trust is a cryptographic proof. Until we decide which one NDN wants to be, NFD Feature #2856 would likely remain where it has been for the last decade: open, unresolved, and haunting the architecture.