Concepts
This page explains the core abstractions in aegis and how they relate to each other.
Node
A Node is a participant in the mesh. It has:
- ID — Unique identifier, used in certificates and topology
- Name — Human-readable label
- Type — Classification (e.g.,
NodeTypeGeneric) - Address — Host and port for connections
- Services — List of services this node provides
node, _ := aegis.NewNodeBuilder().
WithID("api-1").
WithName("API Server").
WithAddress("localhost:8443").
WithServices(aegis.ServiceInfo{Name: "identity", Version: "v1"}).
Build()
A node manages its own:
- MeshServer — gRPC server for incoming connections
- PeerManager — Outgoing connections to other nodes
- Topology — View of all nodes in the mesh
- TLSConfig — Certificates for mTLS
Think of a node as a process's identity in the mesh.
Peer
A Peer is a connection to another node. The PeerManager maintains these connections.
// Add a peer
node.AddPeer(aegis.PeerInfo{
ID: "other-node",
Type: aegis.NodeTypeGeneric,
Address: "other-host:8443",
})
// Get all peers
peers := node.GetAllPeers()
// Communicate with a peer
resp, _ := node.PingPeer(ctx, "other-node")
Peers are directional: if node A adds node B as a peer, A initiates the connection. For bidirectional communication, both nodes should add each other.
All peer connections use mTLS. The certificates verify node identity.
Topology
The Topology is a shared view of mesh membership. Each node maintains its own copy, synchronized via gossip.
// Add a node to local topology
node.Topology.AddNode(aegis.NodeInfo{
ID: "new-node",
Name: "New Node",
Address: "new-host:8443",
})
// Query topology
allNodes := node.Topology.GetAllNodes()
serviceProviders := node.Topology.GetServiceProviders("identity", "v1")
Topology has a version number. When nodes sync, the higher version wins. This provides eventual consistency—all nodes converge to the same view.
Service
A Service is a capability that a node provides. Services have a name and version:
aegis.ServiceInfo{Name: "identity", Version: "v1"}
Services are declared when building a node:
node, _ := aegis.NewNodeBuilder().
WithServices(
aegis.ServiceInfo{Name: "identity", Version: "v1"},
aegis.ServiceInfo{Name: "audit", Version: "v1"},
).
Build()
The service registry answers: "Which nodes provide service X?"
providers := node.Topology.GetServiceProviders("identity", "v1")
This enables location-transparent service calls. Consumers don't need to know specific addresses.
ServiceClientPool
The ServiceClientPool manages connections to service providers:
pool := aegis.NewServiceClientPool(node)
defer pool.Close()
It provides:
- Connection pooling — Reuses connections to the same address
- Round-robin — Distributes calls across providers
- mTLS — All connections are authenticated
Create typed clients for specific services:
client := aegis.NewServiceClient(pool, "identity", "v1", identity.NewIdentityServiceClient)
// Get a client (may connect to different provider each time)
identityClient, _ := client.Get(ctx)
Caller
A Caller represents the identity of a node making a request. Extract it from the gRPC context:
func (s *MyServer) HandleRequest(ctx context.Context, req *pb.Request) (*pb.Response, error) {
caller, err := aegis.CallerFromContext(ctx)
if err != nil {
return nil, err
}
log.Printf("Request from node: %s", caller.NodeID)
// caller.Certificate contains the full X.509 certificate
}
This enables authorization decisions based on caller identity.
How They Relate
┌─────────────────────────────────────────────────────────────┐
│ Node │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ MeshServer │ │ PeerManager │ │ Topology │ │
│ │ (inbound) │ │ (outbound) │ │ (mesh membership) │ │
│ └──────┬──────┘ └──────┬──────┘ └──────────┬──────────┘ │
│ │ │ │ │
│ │ mTLS │ mTLS │ sync │
│ ▼ ▼ ▼ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ TLSConfig │ │
│ │ (certificates, CA, verification) │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
│ Services declared
▼
┌───────────────────┐
│ ServiceRegistry │
│ (in Topology) │
└─────────┬─────────┘
│
│ GetServiceProviders()
▼
┌───────────────────┐
│ ServiceClientPool │
│ (connections) │
└───────────────────┘
Next Steps
- Architecture — How mTLS and topology sync work internally
- Types Reference — Full type definitions