The Magic of .sock: Why Modern Infrastructure Relies on Unix Domain Sockets

Published: (January 15, 2026 at 09:05 AM EST)
5 min read
Source: Dev.to

Source: Dev.to

/var/run/docker.sock – used for controlling Docker.
agent.sock – used by SPIRE to authenticate workloads.

It isn’t just “because it’s fast.” There is a decisive security reason: absolute identity assurance provided by the OS kernel.

In this article we will:

  1. Explain the true nature of sockets and the critical differences from TCP.
  2. Conduct an experiment in Go that extracts the identity of the connection peer (PID/UID) directly from the kernel.

Sockets vs. Files

Many people are taught that “sockets are handled as files.” When you list them with ls -l they indeed appear as files:

srw-rw---- 1 root docker 0 Jan 1 12:00 /var/run/docker.sock

The file size is always 0 because the “data” isn’t stored on disk; it is merely an address‑book entry for a communication endpoint (a window) in kernel memory.

Data‑flow Comparison

FeatureTCP (INET)UNIX Domain Socket (UDS)
AddressingIP:Port (e.g., 127.0.0.1:8080)File path (e.g., /tmp/app.sock)
ScopeOver network (remote)Same host only (local)
OverheadHigh – protocol headers, checksum, routing table look‑upsMinimal – memory copy only
Access controlFirewall (iptables), TLSFile permissions (chmod/chown)
IdentitySource IP (spoofable)PID/UID/GID (guaranteed by kernel)
  • TCP – Even for local communication the data traverses the full network stack (packet encapsulation, checksum calculation, routing).
  • UDS – Bypasses the network stack entirely; communication is performed by copying buffers inside the kernel, giving overwhelmingly low latency.

In TCP you can see the source IP address, but there is no reliable way to know which process initiated the connection (IP can be spoofed).

With UDS the server can ask the kernel to reveal the credentials of the peer using the SO_PEERCRED socket option. Because this information comes straight from the kernel’s internal tables, the client cannot spoof it. This is why Zero‑Trust systems such as SPIRE adopt UDS.

⚠️ Note: SO_PEERCRED is a Linux‑specific feature. It does not work on macOS or Windows.

Demo: Extracting PID/UID with Go

Below is a minimal server that prints the peer’s PID, UID, and GID.

// main.go
package main

import (
	"fmt"
	"net"
	"os"
	"syscall"
)

func main() {
	const socketPath = "/tmp/test.sock"

	// Remove any stale socket file.
	_ = os.Remove(socketPath)

	// Start a UDS listener.
	l, err := net.Listen("unix", socketPath)
	if err != nil {
		panic(err)
	}
	defer l.Close()

	// Make the socket world‑writable for the experiment.
	_ = os.Chmod(socketPath, 0o777)

	fmt.Println("🕵️  Server is listening on", socketPath)
	fmt.Println("waiting for connection...")

	for {
		conn, err := l.Accept()
		if err != nil {
			fmt.Println("accept error:", err)
			continue
		}
		go handleConnection(conn)
	}
}

func handleConnection(c net.Conn) {
	defer c.Close()

	// Convert net.Conn to *net.UnixConn to obtain the underlying file descriptor.
	unixConn, ok := c.(*net.UnixConn)
	if !ok {
		fmt.Println("Not a unix connection")
		return
	}
	file, err := unixConn.File()
	if err != nil {
		fmt.Println("Failed to get file descriptor:", err)
		return
	}
	defer file.Close()
	fd := int(file.Fd())

	// Query the kernel for peer credentials.
	ucred, err := syscall.GetsockoptUcred(fd, syscall.SOL_SOCKET, syscall.SO_PEERCRED)
	if err != nil {
		fmt.Println("Failed to get credentials:", err)
		return
	}

	// Display the results.
	fmt.Printf("\n[🚨 DETECTED]\n")
	fmt.Printf(" - Connected by PID : %d\n", ucred.Pid)
	fmt.Printf(" - User ID (UID)    : %d\n", ucred.Uid)
	fmt.Printf(" - Group ID (GID)   : %d\n", ucred.Gid)

	_, _ = c.Write([]byte("Identity Verified. closing.\n"))
}

Running the Demo (Linux / Docker)

# 1️⃣ Save the code above as main.go

# 2️⃣ Start a Linux container with Go installed.
docker run -it --rm -v "$PWD":/app -w /app golang:1.25 bash

# Inside the container:
# ── Start the server in the background
go run main.go &

# ── Connect with netcat (nc)
echo | sh -c 'echo "Client PID: $$"; exec nc -U /tmp/test.sock'

Expected output (server side)

🕵️  Server is listening on /tmp/test.sock
waiting for connection...

[🚨 DETECTED]
 - Connected by PID : 757
 - User ID (UID)    : 0
 - Group ID (GID)   : 0

The PID shown (757 in the example) matches the nc process that performed the connection – proof that the kernel guarantees the identity.

Real‑World Use: SPIRE & Docker

  • Access to docker.sock is effectively root‑level because the Docker daemon runs as root.
  • SPIRE’s agent uses SO_PEERCRED on its Unix socket to verify that a request truly originates from the expected workload (e.g., a Pod).

SPIRE does more than just read the PID:

  1. Calls watcher.IsAlive() to guard against PID‑reuse attacks (a process dies, its PID is reassigned, and the attacker tries to masquerade).
  2. Passes the PID to Workload Attestor plugins (Docker, Kubernetes, etc.). Those plugins translate the PID into richer attributes such as container IDs, pod labels, etc.

On Windows, SPIRE uses named pipes with an analogous mechanism: the kernel still guarantees the client’s identity, even though the underlying OS differs.

Take‑aways

  • .sock (Unix Domain Socket) is not an “old technology” – it provides high performance and kernel‑verified identity.
  • SO_PEERCRED gives you a trustworthy PID/UID/GID pair that cannot be forged by the client.
  • This capability is the cornerstone of many Zero‑Trust designs in cloud‑native environments (Docker, SPIRE, etc.).

Feel free to experiment with the code above, and remember that the security guarantees only hold on Linux where SO_PEERCRED is available. Happy hacking!

Performance

Bypassing the network stack.

Strongest Security

ID assurance at the kernel level (Peer Cred).

Simple Access Control

Utilization of file system permissions.

Combining these features, UDS continues to be a critical component supporting the “last one mile of host communication” in modern container infrastructure where Zero Trust security is required.

Back to Blog

Related posts

Read more »

Rapg: TUI-based Secret Manager

We've all been there. You join a new project, and the first thing you hear is: > 'Check the pinned message in Slack for the .env file.' Or you have several .env...

Technology is an Enabler, not a Saviour

Why clarity of thinking matters more than the tools you use Technology is often treated as a magic switch—flip it on, and everything improves. New software, pl...