A lightweight, cryptography-powered, open-source toolkit built to enforce Zero Trust security for infrastructure, applications, and data in the AI-driven world.
# AGENTS.md
This file provides guidance to Codex (Codex.ai/code) when working with code in this repository.
## Project Overview
OpenNHP is a Go-based Zero Trust security toolkit implementing two core protocols:
- **NHP (Network-infrastructure Hiding Protocol)**: Conceals server ports, IPs, and domains from unauthorized access
- **DHP (Data-content Hiding Protocol)**: Ensures data security via encryption and confidential computing
The system follows NIST Zero Trust Architecture with three core components that communicate via encrypted UDP packets using the Noise Protocol Framework.
## Git Commit Requirements
All commits must be signed with a verified GPG or SSH key. Unsigned commits will fail CI checks.
```bash
# Sign commits (if not configured globally)
git commit -S -m "your message"
# Amend to sign an existing commit
git commit --amend --no-edit -S
```
## Build Commands
```bash
# Full build (all components + SDKs + plugins + archive)
make
# Build individual components
make agentd # Build nhp-agent daemon
make serverd # Build nhp-server daemon
make acd # Build nhp-ac (access controller) daemon
make db # Build nhp-db daemon
make kgc # Build nhp-kgc (key generation center)
# Build with eBPF support (requires clang)
make ebpf
# Build plugins
make plugins
# Initialize/tidy modules
make init
```
## Running Tests
```bash
# Run tests in the nhp module
cd nhp && go test ./...
# Run tests in the endpoints module
cd endpoints && go test ./...
# Run specific test file
cd nhp && go test -v ./test/packet_test.go
# Run benchmark tests
cd nhp && go test -bench=. ./core/benchmark/
```
## Code Formatting
**IMPORTANT**: All Go code must be properly formatted before committing. CI will fail if formatting is incorrect.
### Before Committing
Always run these commands on modified Go files:
```bash
# Format code with gofmt
gofmt -w <file.go>
# Fix import grouping with goimports
goimports -w <file.go>
# Or format all files in a directory
gofmt -w ./path/to/package/
goimports -w ./path/to/package/
```
### Import Grouping Style
Imports must be organized into three groups separated by blank lines:
1. Standard library imports
2. External third-party imports
3. Internal project imports
```go
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
"github.com/pelletier/go-toml/v2"
"github.com/OpenNHP/opennhp/nhp/common"
"github.com/OpenNHP/opennhp/nhp/log"
)
```
### Verify Formatting
Check if files need formatting (no output means properly formatted):
```bash
gofmt -l <file.go>
goimports -l <file.go>
```
### Install goimports
If `goimports` is not installed:
```bash
go install golang.org/x/tools/cmd/goimports@latest
```
## Docker Development
```bash
# Build and run the full stack
cd docker && docker-compose up --build
# Individual service testing
docker-compose up nhp-server
docker-compose up nhp-ac
docker-compose up nhp-agent
```
## Architecture
### Module Structure
The codebase uses two separate Go modules with a local replace directive:
- **`nhp/`**: Core protocol library
- `core/`: Packet handling, cryptography, device management, Noise Protocol implementation
- `common/`: Shared types and message definitions (AgentKnockMsg, ServerKnockAckMsg, etc.)
- `utils/`: Utility functions
- `plugins/`: Plugin handler interfaces (PluginHandler interface)
- `log/`: Logging infrastructure
- `etcd/`: Distributed configuration support
- **`endpoints/`**: Daemon implementations (depends on nhp module)
- `agent/`: NHP-Agent - client that sends knock requests
- `server/`: NHP-Server - authenticates and authorizes requests
- `ac/`: NHP-AC - access controller that manages firewall rules
- `db/`: NHP-DB - Data Broker for DHP
- `kgc/`: Key Generation Center for IBC (Identity-Based Cryptography)
- `relay/`: TCP relay functionality
### Core Concepts
**Device Types** (defined in `nhp/core/device.go`):
- `NHP_AGENT`: Client initiating access requests
- `NHP_SERVER`: Central authentication/authorization server
- `NHP_AC`: Access controller managing network rules
- `NHP_DB`: Data Broker for DHP
- `NHP_RELAY`: Packet relay
**Packet Types** (defined in `nhp/core/packet.go`):
- `NHP_KNK`: Agent knock request
- `NHP_ACK`: Server knock acknowledgment
- `NHP_AOP`: Server-to-AC operation request
- `NHP_ART`: AC operation result
- `NHP_REG`/`NHP_RAK`: Agent registration flow
- `DHP_*`: Data Hiding Protocol messages
**Cipher Schemes** (in `nhp/core/crypto.go`):
- `CIPHER_SCHEME_CURVE`: Curve25519 + AES-256-GCM + BLAKE2s
- `CIPHER_SCHEME_GMSM`: SM2 + SM4-GCM + SM3 (Chinese national standards)
### Configuration
All daemons use TOML configuration files in their respective `etc/` directories:
- `config.toml`: Base configuration (private key, listen address, log level)
- `server.toml`: Remote server/peer definitions
- `resource.toml`: Protected resources and auth service providers
- `http.toml`: HTTP server settings (for nhp-server)
### Plugin System
Server plugins implement the `PluginHandler` interface (`nhp/plugins/serverpluginhandler.go`) and are built as Go plugins (`.so` files). See `examples/server_plugin/` for reference implementation.
Key plugin methods:
- `AuthWithNHP()`: Handle NHP protocol authentication
- `AuthWithHttp()`: Handle HTTP-based authentication
- `RegisterAgent()`: Agent registration
- `ListService()`: Service discovery
### Key Generation
All daemons support the `keygen` command:
```bash
./nhp-serverd keygen --curve # Generate Curve25519 keys
./nhp-serverd keygen --sm2 # Generate SM2 keys (default)
```
## Demo Deployment (AWS)
The `terraform/demo/` stack provisions the public demo (nhp-server, nhp-ac,
nhp-relay + nginx + Let's Encrypt) in `us-east-2` on the OpenNHP demo AWS
account. The state bucket is configured at `terraform init` time via
`-backend-config="bucket=$TF_STATE_BUCKET"` (workflows read the
`TF_STATE_BUCKET` repo variable) so the account ID is not committed in source.
All secrets live in a single AWS Secrets Manager secret: **`opennhp/demo`**.
### `opennhp/demo` schema
The secret is JSON; fields are added idempotently by scripts and workflows.
Missing fields are auto-generated on the next `scripts/generate-nhp-keys.sh`
run (triggered by the `deploy-demo-v2` workflow).
| Field | Populated by | Used by |
| --- | --- | --- |
| `nhp_server_private_key` / `_public_key` | `scripts/generate-nhp-keys.sh` | server `config.toml`; peer tables on ac/relay |
| `nhp_ac_private_key` / `_public_key` | same | ac `config.toml`; peer table on server |
| `nhp_relay_private_key` / `_public_key` | same | relay `config.toml`; peer table on server |
| `nhp_agent_private_key` / `_public_key` | same | native nhp-agent clients; `agent.toml` on server |
| `nhp_jsagent_private_key` / `_public_key` | same | cluster 1 `endpoints/js-agent/` demo identity (rendered into `config.json` `clusters[0]` at deploy time); trusted by server cluster 1 only |
| `nhp_jsagent2_private_key` / `_public_key` | same | cluster 2 js-agent demo identity (rendered into `config.json` `clusters[1]`); trusted by server cluster 2 only, so the two clusters use independent agent keys |
| `nhp_server2_private_key` / `_public_key` | same | cluster 2 server `config.toml`; peer tables on ac2/relay |
| `nhp_ac2_private_key` / `_public_key` | same | cluster 2 ac `config.toml`; peer table on server2 |
| `cloudflare_api_token` | manually provisioned once | Terraform + certbot DNS-01 (`Zone:DNS:Edit` + `Zone:Zone:Read`) |
| `cloudflare_zone_id` | same | Terraform DNS records for `opennhp.org` |
| `stealth_ca_cert` | `infra-demo` workflow (from GitHub Secrets `STEALTH_CA_CERT`) | `tls_locally_signed_cert.demo_nhp` |
| `stealth_ca_key` | `infra-demo` workflow (from GitHub Secrets `STEALTH_CA_KEY`) | `tls_locally_signed_cert.demo_nhp` |
| `ssh_deploy_private_key` | manually bootstrapped (see `terraform/demo/RUNBOOK.md`); never enters Terraform state | CI SSH into EC2 hosts |
| `ssh_deploy_public_key` | derived in CI via `ssh-keygen -y` and passed as `TF_VAR_deploy_public_key` | `aws_key_pair.deploy` → `ec2-user` authorized keys |
| `ssh_host_keys` | `infra-demo` workflow on `apply` | CI `known_hosts` for strict host key checking |
### Key-generation flow
`scripts/generate-nhp-keys.sh`:
1. Reads existing values from `opennhp/demo`.
2. Uses each daemon's `keygen --curve --json` to fill any missing pair.
3. Writes the merged object back to `opennhp/demo` (preserving unrelated fields).
4. Renders `deploy/config-templates/` via `envsubst` into `deploy/configs/` for
scp to the hosts.
Pass `--regenerate` to the script (or `regenerate_keys=yes` on the workflow) to
force a full rotation. This breaks every registered agent/ac/relay until their
peer tables are redeployed in lockstep, so use sparingly.
## Protocol Flow
1. Agent sends encrypted knock (`NHP_KNK`) to Server
2. Server validates, sends operation request (`NHP_AOP`) to AC
3. AC opens firewall, responds (`NHP_ART`) to Server
4. Server sends acknowledgment (`NHP_ACK`) with access info to Agent
5. Agent can now access the protected resource through AC