# OpenNHP: a zero trust toolkit that hides ports, IPs and domains until a signed knock arrives

> OpenNHP is the CSA NHP reference implementation in Go: an agent, a server and an access controller that keep services invisible by default. Here is how the knock flow works, how to build it, and where the README stops short.

**OpenNHP/opennhp** — A lightweight, cryptography-powered, open-source toolkit built to enforce Zero Trust security for infrastructure, applications, and data in the AI-driven world.

- Repository: https://github.com/OpenNHP/opennhp
- Website: http://opennhp.org/
- Stars: 13,938 · Forks: 2,484
- Language: Go
- License: Apache-2.0
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/opennhp-opennhp

## What OpenNHP hides, and who needs that

Most access control starts after the connection. A user authenticates, then the policy engine decides what they may touch. The port was already reachable, the hostname already resolved, and the service already answered a probe. OpenNHP attacks the earlier step: the README states that every port, IP and hostname sits behind a default-deny gate, and access is granted only after a cryptographically signed knock is authenticated and authorized out of band. The project frames the problem as visibility itself, summarised in the README line that in the AI era visibility equals vulnerability.

The intended audience is infrastructure and platform teams who already run IAM, DNS, FIDO and a Zero Trust policy engine. OpenNHP is explicit that it slots in alongside those rather than replacing them. If your problem is deciding which employee may read which record, this is not that tool. If your problem is that a database port answers SYN packets from anywhere, it is.

OpenNHP is the reference implementation of the Cloud Security Alliance Network-infrastructure Hiding Protocol specification. That matters for adoption: the protocol has a written specification outside the repository, so you are not adopting a single vendor's private knock format.

## The four-message knock flow and the three daemons behind it

The architecture is three core components plus addons. NHP-Agent is the client that sends encrypted knock requests. NHP-Server authenticates and authorizes those requests and, per the README, runs separately and is architecturally decoupled from the protected host. NHP-AC is the access controller that manages firewall rules on the protected server. Two addons extend reach: NHP-Relay is an HTTP-to-UDP bridge that lets browser-based agents send knocks over HTTPS, and NHP-KGC is a Key Generation Center for Identity-Based Cryptography.

The protocol flow has four named messages. The agent sends an encrypted knock, NHP_KNK, to the server. The server validates it and sends an operation request, NHP_AOP, to the AC. The AC opens the firewall and replies, NHP_ART, to the server. The server returns an acknowledgment, NHP_ACK, with access information to the agent, which then reaches the protected resource through the AC.

Two design choices stand out. First, the server never touches the firewall itself, which keeps the authorization decision away from the enforcement point and means the protected host does not need to run the authentication logic. Second, the README describes NHP as bi-directional with status, unlike Single Packet Authorization, which it characterises as one-way. That status channel is what lets an agent learn whether the door opened instead of firing and hoping.

The comparison table in the README positions NHP as third generation: generation one is port knocking, described as plaintext and replay-prone; generation two is Single Packet Authorization, described as using shared secrets, one-way, typically hiding only ports and typically written in C or C++. NHP is claimed to hide domain, IP and ports, be stateless and horizontally scalable, and be written in memory-safe Go.

## Building OpenNHP from source with make

The README lists prerequisites as Go 1.26 or newer, make, and Docker with Docker Compose for the full-stack demo. Note the Go version: 1.26 is ahead of what many build images ship, so check your toolchain before anything else.

The Makefile at the repository root derives a version string from nhp/version/VERSION plus a timestamp, and injects it into the binaries through ldflags along with the commit id, commit time and build time. When .git is absent, for instance in a Docker build whose context excludes it via .dockerignore, the Makefile falls back to the literal string unknown for the commit id rather than an empty value, so a daemon built that way reports unknown instead of blank.

```bash
make
```

That single target builds everything. Individual daemons have their own targets:

```bash
make agentd    # NHP-Agent
make serverd   # NHP-Server
make acd       # NHP-AC
make db        # NHP-DB (Data Broker for DHP)
```

The Makefile also defines plugin paths, NHP_SERVER_PLUGINS pointing at ./examples/server_plugin/basic and NHP_AUTHENTICATOR_PLUGINS pointing at ./examples/server_plugin/authenticator. Those example directories are the place to look for how a server-side plugin is wired, and examples/client_sdk/ is the matching client example. The README does not show a full end-to-end run of agent, server and AC with concrete flags, so the honest first step after building is to read the examples and the deploy and docker directories rather than guessing at daemon arguments.

## Cipher suites, IBC and the choice you have to make early

OpenNHP ships two interchangeable cipher suites. CIPHER_SCHEME_CURVE is Curve25519 with AES-256-GCM and BLAKE2s. CIPHER_SCHEME_GMSM is SM2 with SM4-GCM and SM3. Both are driven by the Noise Protocol Framework, and an Identity-Based Cryptography mode is available through the Key Generation Center.

This is a real fork in the road, not a cosmetic setting. The two suites do not share primitives, and the SM series exists to satisfy Chinese cryptographic requirements, so the choice is usually made for you by regulation or by the peers you must interoperate with. Pick before you generate keys. Swapping later means reissuing material on both sides.

The IBC path is the more interesting one architecturally. With a Key Generation Center, identities map to keys without the certificate exchange you would normally manage. That reduces operational load, but it also concentrates trust: the KGC becomes a component whose availability and integrity the whole knock path depends on. The README lists NHP-KGC as an addon and points to the documentation for cryptographic design, and that documentation is where you should look before committing to IBC rather than certificate-based identities.

## Where OpenNHP is the wrong tool, and where the README goes quiet

Hiding reachability does nothing for an attacker who is already inside the network or already holds valid credentials. If your threat model is a compromised laptop on the corporate VLAN, the knock gate is behind them. The README's own framing, invisible until trusted, assumes the attacker is outside and probing.

The operational cost is the second limit. Every protected service now depends on a working AC that can edit firewall rules, a server that can authorize, and agents that hold valid key material. That is three new failure domains between a user and a database. The README does not document what happens when the server is unreachable but the agent has a valid knock, nor whether the AC fails open or closed. Those are the questions to ask before this sits in front of production.

The documentation gaps are worth naming plainly. The README does not document rollback, does not publish an upgrade procedure, and does not describe a compatibility guarantee between agent and server versions. Given that releases moved from v0.7.3 in May 2026 to v1.0.1 and v1.0.2 in September 2026, a mixed-version fleet is a realistic scenario and the repository is silent on it. The README also states that NHP-Server is decoupled from the protected host but does not spell out the deployment topology that implies in practice; for that, the docs site and the deploy and terraform directories in the repository are the sources to read.

## How this differs from Single Packet Authorization tools

The obvious alternative is an SPA implementation such as fwknop. Both approaches require a client to prove itself before a firewall rule opens, and both keep the service invisible to a port scan. The differences are in the protocol generation.

The README characterises SPA as using shared secrets, one-way, typically hiding ports only, and typically implemented in C or C++. OpenNHP's NHP is described as using modern cryptography, bi-directional with status, hiding domain plus IP plus ports, stateless and horizontally scalable, and implemented in Go. Each of those is a concrete change. Bi-directional with status means the agent receives an NHP_ACK carrying access information rather than assuming success. Hiding the domain as well as the port means DNS records stop being a discovery surface. Statelessness matters at scale because the server holds no per-client session state to replicate.

Go versus C or C++ is a memory-safety argument, and for a component that parses unauthenticated packets from the internet it is a reasonable one. It is not a performance argument, and the README makes no throughput claim. If you already run fwknop and it covers ports only, the migration case rests on whether you need the domain hiding and the status channel.

## Licence, maintenance and what upgrading costs you

OpenNHP is Apache-2.0, which permits commercial use, modification and redistribution with the usual notice and patent-grant terms. The repository ships a SECURITY.md and a CODE_OF_CONDUCT.md, and the README links a Discord server for questions. None of that is legal advice; read the LICENSE file itself before shipping it inside a product.

Maintenance looks current. The last push to main was on 2026-09-20, one day before this was written, and the repository is not archived. Releases v1.0.1 and v1.0.2 both landed in September 2026, with v0.7.3 in May 2026. That is a fast-moving 1.x line, and it is the main upgrade cost: the jump from 0.7.x to 1.0.x happened in four months, and the README documents no migration notes, no deprecation policy and no version-compatibility matrix. A CHANGELOG.md exists at the root, and that file, not the README, is where you should look for what changed between releases.

The build system adds a smaller recurring cost. Because the Makefile derives the version from nhp/version/VERSION plus a timestamp and stamps commit metadata via ldflags, reproducible builds require either a pinned source tree with .git present or an explicit CUSTOM_LD_FLAGS override. Builds from a context without .git will report unknown for the commit id by design.

## Conclusion

Adopt OpenNHP if you already run firewall or policy infrastructure you can drive from an access controller and you want reachability itself to be the control, not just authentication after connection. Do not adopt it if you need a documented rollback path, a published upgrade procedure, or a stable release line, because the README documents none of those and the version numbers moved from v0.7.3 in May 2026 to v1.0.1 and v1.0.2 in September 2026. Before deploying, verify three things against the repository itself: that Go 1.26 or newer is available on your build hosts, that your firewall backend is one the NHP-AC daemon supports, and that the cipher scheme you pick (CIPHER_SCHEME_CURVE or CIPHER_SCHEME_GMSM) matches what your peers already run.

## FAQ

### What is zero trust networking, and how does OpenNHP fit it?

Zero trust networking treats every request as untrusted until it is verified, rather than trusting anything inside a network perimeter. OpenNHP implements that at the reachability layer: the README states that ports, IPs and hostnames sit behind a default-deny gate and open only after a cryptographically signed knock is authenticated and authorized out of band.

### Why does zero trust fail?

OpenNHP's answer is that traditional defenses authenticate users after the network has already let them in, so exposed ports, IPs and domains remain a permanent attack surface. The README's response is to hide the service first and grant access only after a signed knock, so an attacker who cannot discover the service cannot exploit it.

### What are the 5 basic tenets of zero trust?

The README does not list the tenets. It states only that OpenNHP follows a modular design inspired by the NIST Zero Trust Architecture, and that NHP slots in alongside existing IAM, DNS, FIDO and Zero Trust policy engines rather than replacing them.

### What are the 7 pillars of zero trust?

The README does not enumerate the pillars. Its own decomposition is by component instead: NHP-Agent, NHP-Server and NHP-AC as the core, with NHP-Relay and NHP-KGC as addons.

## Sources

- [License: Apache-2.0](https://github.com/OpenNHP/opennhp/blob/main/LICENSE)
- [OpenNHP/opennhp on GitHub](https://github.com/OpenNHP/opennhp)
- [Project website](http://opennhp.org/)
- [README](https://github.com/OpenNHP/opennhp/blob/main/README.md)
- [Releases](https://github.com/OpenNHP/opennhp/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/opennhp-opennhp
