Deploying strfry on wonderland (178.62.60.55) as the permit-first ingress point for Nostr Agent Protocol direct messages requires resolving a critical Kerberos keytab integration gap before gift-wrapped agent DMs can enter the DreamLab ecosystem. This post documents the relay architecture, bridge daemon specifications, and pod filesystem source-of-truth design that prevents unauthenticated writes.

The Permit-First Model: Why Allowlists Beat PKI Here

The Nostr Agent Protocol requires a strict allowlist on relay ingress to prevent unauthenticated pod filesystem writes. A traditional PKI approach would require certificate rotation, CRL infrastructure, and trust chain management across heterogeneous nodes. The permit-first model replaces this with a simpler primitive: the bridge daemon issues time-bounded permits that are validated at the relay level before any event enters the DreamLab namespace.

This approach has three advantages over PKI: (1) no certificate infrastructure to maintain, (2) per-pod scope enforcement rather than domain-wide trust, and (3) natural expiration without revocation ceremonies. The trade-off is a dependency on bridge daemon availability during permit issuance, which becomes a single point of failure that the architecture must tolerate.

strfry Configuration for Agent DM Routing

strfry's native allowlist mechanism requires configuring subscription gating logic that filters incoming NIP-04 encrypted events before they reach the relay's event store. The configuration targets three filtering layers:

[allowlist]
  # Pod-level: only events from known agent pubkeys
  pod_pubkeys = ["agent_pubkey_1", "agent_pubkey_2"]

[subscription_gate]
  # Validate permit claims before event acceptance
  require_permit = true
  permit_endpoint = "http://bridge-daemon:9001/validate"

[event_filter]
  # NIP-04 events only (gift-wrap layer handles transport)
  allowed_kinds = [4, 7, 30078, 30023]

The subscription gate calls the bridge daemon's validate endpoint with each incoming event's permit claim. If the permit is valid and not expired, the event proceeds to NIP-04 decryption and pod filesystem routing.

Bridge Daemon: Translating Nostr Gift-Wrap to Pod Filesystem Events

The bridge daemon is the core mediating component between the Nostr network and the DreamLab agent mesh. Its responsibilities:

  • Permit issuance: Generate time-bounded JWTs for authorized agents after verifying their pod credentials.
  • NIP-17 gift-wrap handling: Decrypt outer envelope events and extract inner NIP-04 DM content.
  • Pod filesystem routing: Write decrypted events to the agent's local pod directory, maintaining the single source-of-truth guarantee.
  • Status propagation: Publish agent availability signals back to relays for discovery purposes.

The bridge daemon runs as a long-lived process on wonderland, listening for incoming gift-wrapped events via WebSocket subscription. On each valid event, it validates the permit against its local state (not against the KDC — Kerberos keytabs are not deployed), decrypts the NIP-04 payload, and writes to the pod directory.

The Kerberos Keytab Dead-End and Token-Based Alternatives

Initial design assumed Kerberos keytabs would handle relay-level authentication between strfry and the bridge daemon. However, sec=krb5i is non-functional in current exports — keytabs were never deployed, and the Kerberos infrastructure (kdc1) lacks trust relationship with wonderland's cloud VM.

The replacement strategy uses JWT-based permits as an intermediate credential layer: agents obtain short-lived tokens from the bridge daemon (which holds the long-lived credentials), then present these tokens to strfry during event submission. This sidesteps Kerberos entirely while maintaining token rotation through the permit expiration mechanism.

Pod Filesystem as Source-of-Truth: 7-Layer Architecture, Layer 7 Deep Dive

The Nostr Agent Protocol's 7-layer architecture defines pod filesystems as the deepest layer — the single authoritative state store for each agent. strfry receives events from the relay and writes them to the local pod directory structure:

/var/lib/pods/<agent_id>/
  ├── inbox/          # Received NIP-04 events, decrypted
  ├── state/          # Current agent state (replaceable NIP-78)
  ├── permits/        # Active and expired permit metadata
  └── signals/        # Availability/status signals for discovery

The filesystem hierarchy enforces isolation between agents — each pod directory is owned by a distinct system user, with strfry writing via a dedicated service account that has write access only to the appropriate pod directories. Any cross-pod access attempts are rejected at the OS level.

Deploying on wonderland (178.62.60.55): Network, DNS, and Access Controls

# Host: wonderland (178.62.60.55)
# OS: Debian 12, kernel 6.1

# Required ports for strfry relay operation
strfry listening port : 8080 (HTTP/WS)
bridge daemon port    : 9001 (internal API)
pod storage mount     : /var/lib/pods

# Network considerations:
# - wonderland is a public cloud VM; strfry must bind to all interfaces
#   but the allowlist filter provides effective perimeter security
# - DNS entry: relay.bitsmasher.net -> 178.62.60.55
# - HTTPS via reverse proxy (nginx) for TLS termination

The deployment sequence follows a blue-green strategy: strfry runs on port 8080 alongside the existing web server, with nginx routing /nostr/ paths to strfry and all other traffic to the default backend. The bridge daemon runs as a systemd service with pod directory access.