← Developers
Level 1: code Framework

Go

Go exposes the dialer. Resolve, compare the answer, and refuse the connection before a socket opens.

Configuration and reference code for Go

Dialer

securd.go
package securd

import (
	"context"
	"errors"
	"net"
	"os"
	"strings"
)

var ErrHeld = errors.New("securd: destination held or blocked for this agent role")

func blockAddrs() map[string]bool {
	m := map[string]bool{}
	for _, a := range strings.Split(os.Getenv("SECURD_BLOCK_ADDRS"), ",") {
		if a != "" {
			m[a] = true
		}
	}
	return m
}

// DialContext resolves first and refuses answers that point at the block page.
func DialContext(ctx context.Context, network, addr string) (net.Conn, error) {
	host, port, err := net.SplitHostPort(addr)
	if err != nil {
		return nil, err
	}
	ips, err := net.DefaultResolver.LookupIPAddr(ctx, host)
	if err != nil {
		return nil, ErrHeld
	}
	blocked := blockAddrs()
	for _, ip := range ips {
		if blocked[ip.String()] {
			return nil, ErrHeld
		}
	}
	var d net.Dialer
	return d.DialContext(ctx, network, net.JoinHostPort(ips[0].String(), port))
}

Use it

main.go
client := &http.Client{Transport: &http.Transport{DialContext: securd.DialContext}}
resp, err := client.Get("https://api.example.com/v1/items")
if errors.Is(err, securd.ErrHeld) {
	log.Printf("held: ask an operator to approve the host for this agent role")
	return
}

Evaluate Agent DNS with your own agent traffic

Deploy on a single policy in learning mode and review the recorded destinations with your team.