178 lines
4.7 KiB
Markdown
178 lines
4.7 KiB
Markdown
# FIPS_DEPLOYMENT.md
|
|
|
|
## 1. Scope
|
|
|
|
This runbook covers a practical Tier-1 deployment of `nsigner` over a TCP listener, with connectivity provided by FIPS as the network substrate.
|
|
|
|
Tier-1 objective:
|
|
|
|
- Keep `nsigner` transport simple (`--listen tcp:IPv4:PORT` or `--listen tcp:[IPv6]:PORT`).
|
|
- Use FIPS to carry traffic between peers.
|
|
- Do not add FIPS runtime dependencies into `nsigner`.
|
|
|
|
Out of scope in this document:
|
|
|
|
- Mandatory transport-level TLS/authentication hardening (still planned for a later phase).
|
|
- Automatic caller->npub enrichment from FIPS session metadata.
|
|
|
|
---
|
|
|
|
## 2. Architecture
|
|
|
|
Two cooperating layers:
|
|
|
|
1. **Signer process layer** (`nsigner`)
|
|
- Listens on operator-selected TCP endpoint (IPv4 or IPv6).
|
|
- Uses existing 4-byte big-endian framed JSON-RPC protocol.
|
|
- Keeps existing policy/prompt behavior.
|
|
|
|
2. **Network substrate layer** (FIPS)
|
|
- Establishes peer connectivity between nodes/qubes.
|
|
- Carries application traffic to the configured signer TCP endpoint.
|
|
|
|
Conceptually:
|
|
|
|
`client app -> local FIPS endpoint -> FIPS mesh -> remote FIPS endpoint -> signer TCP endpoint -> nsigner`
|
|
|
|
---
|
|
|
|
## 3. Prerequisites
|
|
|
|
On signer host/qube:
|
|
|
|
- Built `nsigner` binary.
|
|
- FIPS installed and running.
|
|
- Local firewall policy that keeps signer listener local-only.
|
|
|
|
On caller host/qube:
|
|
|
|
- FIPS installed and peered with signer host/qube.
|
|
- A client implementation that speaks `nsigner` framed JSON-RPC (see `documents/CLIENT_IMPLEMENTATION.md`).
|
|
|
|
Operational assumptions:
|
|
|
|
- Operator controls both endpoints.
|
|
- Manual verification of peer identity is performed in FIPS tooling before enabling signer traffic.
|
|
|
|
---
|
|
|
|
## 4. Start signer in Tier-1 TCP mode
|
|
|
|
Run `nsigner` in TCP listen mode:
|
|
|
|
```bash
|
|
./build/nsigner --listen tcp:[::]:8080
|
|
```
|
|
|
|
Or bind to a specific FIPS ULA address:
|
|
|
|
```bash
|
|
./build/nsigner --listen tcp:[fd00::1234]:8080
|
|
```
|
|
|
|
Behavior notes:
|
|
|
|
- Bind target is operator-controlled; pick the narrowest reachable address that satisfies your topology.
|
|
- No TUI hotkey loop is required in TCP mode; process serves requests until terminated.
|
|
- Caller identity is shown as a TCP endpoint descriptor in activity/prompt context.
|
|
|
|
---
|
|
|
|
## 5. FIPS substrate wiring pattern
|
|
|
|
Because FIPS deployment topologies vary, use this generic pattern:
|
|
|
|
1. Bind `nsigner` on a deliberate signer endpoint (`[::]:PORT` for broad reach, or specific `fd..` for tighter scope).
|
|
2. Configure FIPS service/forwarding so remote authenticated peer traffic is delivered to that signer endpoint.
|
|
3. On caller side, direct client traffic to the local FIPS ingress endpoint for that remote service.
|
|
|
|
Validation checklist:
|
|
|
|
- FIPS session is established between caller and signer nodes.
|
|
- Transport path from caller -> configured signer endpoint succeeds.
|
|
- `nsigner` receives framed request and returns framed response.
|
|
|
|
---
|
|
|
|
## 6. Minimal validation flow
|
|
|
|
### 6.1 Liveness check
|
|
|
|
From caller side, send a framed `get_public_key` request through the FIPS-backed endpoint.
|
|
|
|
Request JSON:
|
|
|
|
```json
|
|
{"id":"1","method":"get_public_key","params":[]}
|
|
```
|
|
|
|
Expected response:
|
|
|
|
```json
|
|
{"id":"1","result":"<hex_pubkey>"}
|
|
```
|
|
|
|
### 6.2 Signing check
|
|
|
|
Send `sign_event` with explicit role selector:
|
|
|
|
```json
|
|
{
|
|
"id": "2",
|
|
"method": "sign_event",
|
|
"params": ["<event_json>", {"role":"main"}]
|
|
}
|
|
```
|
|
|
|
Expected result: signed event JSON in `result`.
|
|
|
|
### 6.3 Negative check (policy)
|
|
|
|
Trigger a request path that requires prompt/denial and confirm client handles policy denial as a normal result path.
|
|
|
|
---
|
|
|
|
## 7. Security guardrails
|
|
|
|
- Prefer binding to a specific FIPS IPv6 ULA (`fd..`) rather than wildcard (`[::]`) when possible.
|
|
- Do not expose signer port directly on LAN/WAN.
|
|
- Keep FIPS peer allowlist tight; avoid broad trust domains.
|
|
- Treat FIPS connectivity as transport, not authorization bypass.
|
|
- Preserve interactive approval where required by policy.
|
|
|
|
---
|
|
|
|
## 8. Troubleshooting
|
|
|
|
### 8.1 `invalid tcp listen target`
|
|
|
|
Cause:
|
|
- `--listen` argument does not match `tcp:HOST:PORT` or `tcp:[IPv6]:PORT`.
|
|
|
|
Fix:
|
|
- Use valid numeric port and valid IPv4/IPv6 literal host.
|
|
|
|
### 8.2 Framing parse failures (`parse_error`)
|
|
|
|
Cause:
|
|
- Client sent line-delimited/raw JSON instead of framed JSON.
|
|
|
|
Fix:
|
|
- Send 4-byte big-endian length prefix followed by exact UTF-8 JSON payload bytes.
|
|
|
|
### 8.3 FIPS path up, signer path down
|
|
|
|
Cause:
|
|
- FIPS session exists but forwarding/service mapping to signer loopback endpoint is missing.
|
|
|
|
Fix:
|
|
- Verify substrate service routing config and local endpoint mapping.
|
|
|
|
---
|
|
|
|
## 9. Next hardening steps (post Tier-1)
|
|
|
|
- Add automated two-node validation script for operator smoke checks.
|
|
- Add optional identity enrichment from FIPS session metadata (`peer_npub`).
|
|
- Introduce remote TCP mode only with mandatory TLS + authenticated caller key flow.
|