Go SDK Reference Go

Embed an nfltr tunnel agent directly in your Go application — no separate binary, no shell exec, no child process management.


Overview

The pkg/agent SDK wraps the same gRPC transport used by the nfltr CLI into a clean Go API. Your application calls agent.New(), Connect(ctx), and the tunnel is up.

Install

go get github.com/onpremlink/onpremlink/pkg/agent

Basic usage

import "github.com/onpremlink/onpremlink/pkg/agent"

a := agent.New(agent.Config{
    ServerAddr: "grpc.nfltr.xyz:443",
    AgentID:      "my-service-01",
    APIKey:     os.Getenv("NFLTR_API_KEY"),
    TLS:        true,
    Routes: []agent.Route{
        {Backend: "http://localhost:8080"}, // default
    },
})

if err := a.Connect(ctx); err != nil {
    log.Fatal(err)
}
log.Println("tunnel active, agent-id:", a.AgentID())

// Block until the context is cancelled or Close() is called.
<-a.Done()

Config

All parameters for the agent connection. Zero values are safe; only AgentID and one of (APIKey / TLSConfig) are required.

ServerAddrstring required
gRPC server address, e.g. "grpc.nfltr.xyz:443". Port must be included. Default: "rpc-server:9090".
AgentIDstring required
Agent identifier (on-premise host ID). Must be unique per server. This is the name that appears in the /browse/<agent_id>/ URL path.
APIKeystring optional
API key for authentication. Can be combined with TLSConfig for mTLS + API key. Set NFLTR_API_KEY environment variable or load from a secrets manager.
TLSConfig*tls.Config optional
Client TLS certificate for mTLS authentication. Can be combined with APIKey. When set, the agent authenticates via certificate CN.
TLSbool optional
Enable TLS for the gRPC connection. Defaults to false. Set to true when connecting to a TLS-enabled server (e.g. port 443). Ignored when TLSConfig is provided.
Routes[]Route optional
Backend routing table. The first entry without a Prefix acts as the default/fallback route. See Route below.
RequestTimeoutint optional
Per-request proxy timeout in seconds. Defaults to 60.
Logger*slog.Logger optional
Structured logger. Defaults to slog.Default().

Route

Describes a single backend target for incoming HTTP requests.

Backendstring required
Target URL for this route, e.g. "http://localhost:8080".
Prefixstring optional
URL path prefix (without leading slash) that activates this route. Empty prefix means default/fallback. The prefix is stripped before forwarding.

Examples

// Single backend (default)
Routes: []agent.Route{
    {Backend: "http://localhost:8080"},
}

// Multi-backend: /api → :8080, /ws → :4000, default → :3000
Routes: []agent.Route{
    {Prefix: "api", Backend: "http://localhost:8080"},
    {Prefix: "ws",  Backend: "http://localhost:4000"},
    {Backend: "http://localhost:3000"}, // fallback
}

Agent interface

The value returned by agent.New() implements this interface:

type Agent interface {
    // Connect dials the server and starts tunneling.
    // Blocks until the first heartbeat succeeds (agent is live).
    Connect(ctx context.Context) error

    // AgentID returns the agent identifier.
    AgentID() string

    // Done returns a channel closed when the agent shuts down.
    Done() <-chan struct{}

    // Close gracefully disconnects the agent.
    Close()
}

Options

WithShareURL

Request a word-pair share URL from the server and receive it via callback after connecting:

a := agent.New(cfg, agent.WithShareURL(
    "https://nfltr.xyz",
    func(shareURL string) {
        log.Println("share URL:", shareURL)
        // e.g. https://swift-bay.nfltr.xyz/
    },
))

The share URL is valid for the lifetime of the tunnel connection. It is automatically revoked when the agent disconnects.

WithLabels

Attach key-value metadata to the agent connection. Labels are used for fleet token matching and endpoint pooling:

a := agent.New(cfg, agent.WithLabels(map[string]string{
    "env":     "production",
    "region":  "us-east",
    "version": "v2.1.0",
}))

Complete example

package main

import (
    "context"
    "log"
    "os"
    "os/signal"
    "syscall"

    "github.com/onpremlink/onpremlink/pkg/agent"
)

func main() {
    ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
    defer stop()

    a := agent.New(
        agent.Config{
            ServerAddr: "grpc.nfltr.xyz:443",
            AgentID:      "payment-service",
            APIKey:     os.Getenv("NFLTR_API_KEY"),
            TLS:        true,
            Routes: []agent.Route{
                {Prefix: "api",    Backend: "http://localhost:8080"},
                {Prefix: "health", Backend: "http://localhost:9090"},
                {Backend:          "http://localhost:8080"},
            },
        },
        agent.WithShareURL("https://nfltr.xyz", func(u string) {
            log.Printf("share URL: %s", u)
        }),
        agent.WithLabels(map[string]string{"env": "prod"}),
    )

    if err := a.Connect(ctx); err != nil {
        log.Fatalf("connect: %v", err)
    }
    log.Printf("tunnel active: https://nfltr.xyz/browse/%s/", a.AgentID())

    <-ctx.Done()
    a.Close()
    <-a.Done()
    log.Println("shutdown complete")
}

Authentication

MethodConfig fieldWhen to use
API keyAPIKeySaaS deployments, CI environments
mTLS certificateTLSConfigSelf-hosted, zero-trust, IoT

API key (SaaS)

cfg := agent.Config{
    APIKey: os.Getenv("NFLTR_API_KEY"),
    // ...
}

Generate an API key from the dashboard or the admin API.

mTLS certificate (self-hosted)

cert, err := tls.LoadX509KeyPair("agent.crt", "agent.key")
if err != nil {
    log.Fatal(err)
}
cfg := agent.Config{
    TLSConfig: &tls.Config{Certificates: []tls.Certificate{cert}},
    // ...
}

Error handling

Connect returns an error if the initial dial fails. Once connected, the agent reconnects automatically on transient failures. Monitor the Done() channel for permanent shutdown:

if err := a.Connect(ctx); err != nil {
    // Fatal: bad credentials, server unreachable, etc.
    log.Fatalf("connect: %v", err)
}

// Agent is now running. Done() closes when:
//   - ctx is cancelled
//   - Close() is called
//   - A non-recoverable gRPC error occurs
go func() {
    <-a.Done()
    log.Println("agent disconnected")
}()

Kubernetes operator

The pkg/agent SDK is designed to be embedded in Kubernetes controllers. Each AgentTunnel custom resource maps to one agent.Agent instance started by the controller's reconcile loop.

// In your controller's Reconcile() method:
func (r *AgentTunnelReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
    // ... fetch the AgentTunnel CR ...

    a := agent.New(agent.Config{
        ServerAddr: cr.Spec.ServerAddr,
        AgentID:      cr.Spec.AgentID,
        APIKey:     apiKey,
        Routes:     routesFromSpec(cr.Spec.Routes),
    })
    if err := a.Connect(ctx); err != nil {
        return ctrl.Result{}, err
    }
    r.agents.Store(req.NamespacedName, a)
    return ctrl.Result{}, nil
}