nodeidentity

package
v0.11.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 18, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package nodeidentity owns the installation-level identity of a Tako node.

Installation identity is deliberately separate from takod's mutable project/environment metadata. It is created only by an explicit platform bootstrap or enrollment operation and is never writable through the takod runtime API.

Index

Constants

View Source
const (
	APIVersion  = "tako.io/v1"
	Kind        = "InstallationIdentity"
	Capability  = "node.identity-v1"
	DefaultPath = "/etc/tako/identity.json"

	RoleControlPlane = "control-plane"
	RoleWorker       = "worker"
	RoleEdge         = "edge"
	RoleBuilder      = "builder"
)
View Source
const (
	InventoryAPIVersion  = "tako.io/v1"
	InventoryKind        = "ClusterInventory"
	DefaultInventoryPath = "/etc/tako/cluster-inventory.json"
	// DeploymentDenyFile is a durable, node-local safety latch. Lifecycle
	// commands set it on the target before committing a transition away from
	// schedulable, so a controller crash cannot leave a stale worker accepting
	// workload mutations indefinitely.
	DeploymentDenyFile = "deployment-denied"

	NodeLifecycleJoining     = "joining"
	NodeLifecycleReady       = "ready"
	NodeLifecycleSchedulable = "schedulable"
	NodeLifecycleCordoned    = "cordoned"
	NodeLifecycleDraining    = "draining"

	MeshCredentialActive  = "active"
	MeshCredentialRevoked = "revoked"
)
View Source
const (
	LocalBindingKind        = "LocalNodeBinding"
	DefaultLocalBindingPath = "/etc/tako/local-node.json"
)
View Source
const OperationFenceKind = "ControllerOperationFence"
View Source
const SignedInventoryKind = "SignedClusterInventory"

Variables

This section is empty.

Functions

func AcquireInventoryMutationLock

func AcquireInventoryMutationLock(path string) (func(), error)

AcquireInventoryMutationLock serializes protected inventory publication with consumers that must validate and act on one exact inventory inode.

func Create

func Create(path string, installation Installation) error

Create atomically publishes identity at path with mode 0600. Its protected parent directory must already exist. Create refuses to overwrite any existing path, including a symlink, so enrollment cannot silently replace a node's authority.

func CreateInventory

func CreateInventory(path string, inventory ClusterInventory) error

func DeploymentDenyPath

func DeploymentDenyPath(inventoryPath string) string

func MeshCredentialID

func MeshCredentialID(publicKey string) (string, error)

func OperationHolderTokenHash

func OperationHolderTokenHash(holderToken string) (string, error)

func ReplaceInventory

func ReplaceInventory(path string, inventory ClusterInventory) error

ReplaceInventory atomically publishes a new controller snapshot in the already protected inventory directory. It validates the complete snapshot before replacing the previous inode.

func SignInventorySnapshot

func SignInventorySnapshot(snapshot *SignedInventorySnapshot, controller *Installation) error

func SignOperationFence

func SignOperationFence(fence *OperationFence, installation *Installation) error

func ValidateAllocationPublicKey

func ValidateAllocationPublicKey(publicKeyEncoded string) error

func ValidateClusterID

func ValidateClusterID(value string) error

ValidateClusterID checks the serialized cluster identity format.

func ValidateMeshPublicKey

func ValidateMeshPublicKey(value string) error

ValidateMeshPublicKey accepts the canonical WireGuard key representation: base64 of exactly 32 non-zero Curve25519 public-key bytes.

func ValidateNodeID

func ValidateNodeID(value string) error

ValidateNodeID checks the serialized node identity format.

func VerifyActiveAllocationOrigin

func VerifyActiveAllocationOrigin(allocation ActiveAllocation, publicKey string) error

VerifyActiveAllocationOrigin proves that the exact durable allocation was emitted by the enrolled worker. Controller authorization is a separate step represented by AuthorizedAt and inventory publication.

func VerifyAllocationSignature

func VerifyAllocationSignature(publicKeyEncoded string, message []byte, signatureEncoded string) error

func VerifyInventorySnapshot

func VerifyInventorySnapshot(snapshot SignedInventorySnapshot, controllerPublicKey string, now time.Time) error

func VerifyOperationFence

func VerifyOperationFence(fence OperationFence, controllerPublicKey string, now time.Time) error

func VerifyUpgradeContract

func VerifyUpgradeContract(identityPath string, inventoryPath string, contract UpgradeContract) error

VerifyUpgradeContract reopens the protected identity and inventory and proves they still match the last takod attestation. Call it from the staged candidate immediately before publishing that candidate.

func WriteLocalBinding

func WriteLocalBinding(path string, binding LocalBinding) error

Types

type ActiveAllocation

type ActiveAllocation struct {
	Kind          string    `json:"kind"`
	Project       string    `json:"project"`
	Environment   string    `json:"environment"`
	Service       string    `json:"service"`
	Revision      string    `json:"revision,omitempty"`
	Slot          int       `json:"slot"`
	HostIP        string    `json:"hostIp"`
	HostPort      int       `json:"hostPort"`
	ContainerPort int       `json:"containerPort"`
	Key           string    `json:"key"`
	ClusterID     string    `json:"clusterId"`
	NodeID        string    `json:"nodeId"`
	Generation    uint64    `json:"generation"`
	IssuedAt      time.Time `json:"issuedAt"`
	OperationID   string    `json:"operationId,omitempty"`
	FenceToken    uint64    `json:"fenceToken,omitempty"`
	Signature     string    `json:"signature"`
	AuthorizedAt  time.Time `json:"authorizedAt"`
}

ActiveAllocation is the exact node-signed allocation generation that the single controller currently authorizes for routing. Omission is revocation.

type ClusterInventory

type ClusterInventory struct {
	APIVersion           string             `json:"apiVersion"`
	Kind                 string             `json:"kind"`
	ClusterID            string             `json:"clusterId"`
	Generation           uint64             `json:"generation,omitempty"`
	AllocationGeneration uint64             `json:"allocationGeneration,omitempty"`
	ControllerNodeID     string             `json:"controllerNodeId,omitempty"`
	MeshCIDR             string             `json:"meshCidr,omitempty"`
	UpdatedAt            time.Time          `json:"updatedAt,omitempty"`
	Nodes                []InventoryNode    `json:"nodes"`
	Tombstones           []NodeTombstone    `json:"tombstones,omitempty"`
	ActiveAllocations    []ActiveAllocation `json:"activeAllocations,omitempty"`
}

ClusterInventory is a controller-published, read-only trust snapshot. Join token material and private credentials never appear here.

func ReadInventory

func ReadInventory(path string) (*ClusterInventory, error)

func ReadInventoryOptional

func ReadInventoryOptional(path string) (*ClusterInventory, error)

func (ClusterInventory) Allocation

func (i ClusterInventory) Allocation(nodeID, key string, generation uint64) (ActiveAllocation, bool)

func (ClusterInventory) IsTombstoned

func (i ClusterInventory) IsTombstoned(nodeID string) bool

func (ClusterInventory) Node

func (i ClusterInventory) Node(nodeID string) (InventoryNode, bool)

func (ClusterInventory) Validate

func (i ClusterInventory) Validate() error

type Identity

type Identity struct {
	APIVersion          string    `json:"apiVersion"`
	Kind                string    `json:"kind"`
	ClusterID           string    `json:"clusterId"`
	NodeID              string    `json:"nodeId"`
	NodeName            string    `json:"nodeName"`
	CreatedAt           time.Time `json:"createdAt"`
	AllocationPublicKey string    `json:"allocationPublicKey,omitempty"`
}

Identity is the immutable, installation-level identity of one Tako node. ClusterID and NodeID are UUIDs created during explicit enrollment. Runtime role assignments deliberately live outside this value so roles can move without changing node identity.

func (Identity) Matches

func (i Identity) Matches(clusterID string, nodeID string) bool

Matches reports whether the immutable IDs identify the expected cluster member. Node names and IP addresses are intentionally not authority.

func (Identity) MatchesReference

func (i Identity) MatchesReference(reference Reference) bool

MatchesReference reports whether identity is the enrolled cluster member.

func (Identity) Validate

func (i Identity) Validate() error

Validate checks the immutable identity fields.

type Installation

type Installation struct {
	Identity
	EnrollmentRoles      []string `json:"roles"`
	AllocationPrivateKey string   `json:"allocationPrivateKey,omitempty"`
}

Installation is the create-once identity document. EnrollmentRoles record the roles requested at bootstrap/enrollment time; they are an audit fact, not the mutable current-role assignment introduced by the control plane.

func New

func New(clusterID string, nodeID string, nodeName string, roles []string, now time.Time) (*Installation, error)

New creates a validated in-memory identity. An empty clusterID or nodeID is generated as a UUIDv4. Persist it with Create, which refuses replacement.

func Read

func Read(path string) (*Installation, error)

Read validates and returns the installation identity at path. Symlinks, non-regular files, and group/world-accessible files are rejected.

func ReadOptional

func ReadOptional(path string) (*Installation, error)

ReadOptional returns nil when no identity has been enrolled.

func (Installation) HasEnrollmentRole

func (i Installation) HasEnrollmentRole(role string) bool

HasEnrollmentRole reports whether bootstrap/enrollment declared role.

func (Installation) Matches

func (i Installation) Matches(clusterID string, nodeID string) bool

Matches reports whether the installation contains the expected identity.

func (Installation) SignAllocation

func (i Installation) SignAllocation(message []byte) (string, error)

func (Installation) Validate

func (i Installation) Validate() error

Validate checks the complete persisted installation contract.

type InventoryNode

type InventoryNode struct {
	NodeID                string    `json:"nodeId"`
	NodeName              string    `json:"nodeName,omitempty"`
	Lifecycle             string    `json:"lifecycle,omitempty"`
	Roles                 []string  `json:"roles,omitempty"`
	Schedulable           bool      `json:"schedulable"`
	MeshIP                string    `json:"meshIp,omitempty"`
	MeshEndpoint          string    `json:"meshEndpoint,omitempty"`
	MeshCredentialID      string    `json:"meshCredentialId,omitempty"`
	MeshPublicKey         string    `json:"meshPublicKey,omitempty"`
	MeshCredentialStatus  string    `json:"meshCredentialStatus,omitempty"`
	SSHHost               string    `json:"sshHost,omitempty"`
	SSHPort               int       `json:"sshPort,omitempty"`
	SSHUser               string    `json:"sshUser,omitempty"`
	SSHHostKeyType        string    `json:"sshHostKeyType,omitempty"`
	SSHHostKey            string    `json:"sshHostKey,omitempty"`
	SSHHostKeyFingerprint string    `json:"sshHostKeyFingerprint,omitempty"`
	AllocationPublicKey   string    `json:"allocationPublicKey"`
	JoinedAt              time.Time `json:"joinedAt,omitempty"`
	UpdatedAt             time.Time `json:"updatedAt,omitempty"`
}

type LocalBinding

type LocalBinding struct {
	APIVersion string `json:"apiVersion"`
	Kind       string `json:"kind"`
	ClusterID  string `json:"clusterId"`
	NodeID     string `json:"nodeId"`
	NodeName   string `json:"nodeName"`
	WorkerUID  int    `json:"workerUid,omitempty"`
}

LocalBinding is the public, integrity-protected subset of installation identity needed by an unprivileged local operator. It contains no private keys or bearer credentials.

func ReadLocalBinding

func ReadLocalBinding(path string) (*LocalBinding, error)

func (LocalBinding) Validate

func (b LocalBinding) Validate() error

type NodeTombstone

type NodeTombstone struct {
	NodeID                   string    `json:"nodeId"`
	NodeName                 string    `json:"nodeName,omitempty"`
	RemovedAt                time.Time `json:"removedAt"`
	RemovedGeneration        uint64    `json:"removedGeneration"`
	RevokedMeshCredentialID  string    `json:"revokedMeshCredentialId,omitempty"`
	RevokedMeshPublicKey     string    `json:"revokedMeshPublicKey,omitempty"`
	AllocationKeyFingerprint string    `json:"allocationKeyFingerprint,omitempty"`
}

type OperationFence

type OperationFence struct {
	Kind                 string    `json:"kind"`
	ClusterID            string    `json:"clusterId"`
	ControllerNodeID     string    `json:"controllerNodeId"`
	MembershipGeneration uint64    `json:"membershipGeneration"`
	Project              string    `json:"project"`
	Environment          string    `json:"environment"`
	OperationID          string    `json:"operationId"`
	Operation            string    `json:"operation"`
	Token                uint64    `json:"token"`
	HolderTokenHash      string    `json:"holderTokenHash"`
	TargetNodeIDs        []string  `json:"targetNodeIds"`
	IssuedAt             time.Time `json:"issuedAt"`
	ExpiresAt            time.Time `json:"expiresAt"`
	Signature            string    `json:"signature"`
}

OperationFence is a controller-signed, monotonically fenced mutation grant. Workers accept it only after the controller has explicitly activated the exact token for that node. The token binds one project/environment operation to one membership generation and an explicit target set.

func (OperationFence) Targets

func (f OperationFence) Targets(nodeID string) bool

func (OperationFence) Validate

func (f OperationFence) Validate(now time.Time) error

type Reference

type Reference struct {
	ClusterID string `json:"clusterId" yaml:"clusterId"`
	NodeID    string `json:"nodeId" yaml:"nodeId"`
}

Reference identifies an enrolled cluster member without carrying mutable names, addresses, or roles.

func (Reference) Validate

func (r Reference) Validate() error

Validate checks that both immutable identity components are UUIDs.

type SignedInventorySnapshot

type SignedInventorySnapshot struct {
	Kind      string           `json:"kind"`
	Inventory ClusterInventory `json:"inventory"`
	IssuedAt  time.Time        `json:"issuedAt"`
	Signature string           `json:"signature"`
}

SignedInventorySnapshot lets the controller publish a newer trust snapshot to only the nodes an operation actually targets. Nodes verify it against their already trusted controller key and reject generation rollback.

type UpgradeContract

type UpgradeContract struct {
	ClusterID            string   `json:"clusterId"`
	NodeID               string   `json:"nodeId"`
	MembershipGeneration uint64   `json:"membershipGeneration"`
	Lifecycle            string   `json:"lifecycle"`
	Roles                []string `json:"roles"`
}

UpgradeContract binds privileged binary publication to the exact protected identity and inventory generation most recently attested over takod.

func (UpgradeContract) Validate

func (c UpgradeContract) Validate() error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL