fleetmember

package
v0.47.2 Latest Latest
Warning

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

Go to latest
Published: Sep 26, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package fleetmember binds a physical host to one existing member node of a StackInstance. The Home owner on the Foundation Node signs a member admission; the member host verifies it against the pinned Home key, recompiles the same ResolvedPlan, and keeps verify-only custody. It grants no enrollment, signing, credential issuance, or ControlAuthority.

Index

Constants

View Source
const (
	AdmissionAPIVersion = "stackkit.member-admission/v1"
	AdmissionKind       = "MemberAdmission"

	// MaxAdmissionValidity bounds the join window. The resulting member
	// custody does not expire; a changed plan needs a new admission.
	MaxAdmissionValidity = 24 * time.Hour

	// MaxAdmissionBytes bounds the document, which carries spec and inventory.
	MaxAdmissionBytes = 8 << 20
)
View Source
const (
	CustodyAPIVersion = "stackkit.local-member-custody/v1"
	CustodyKind       = "LocalMemberCustody"
)
View Source
const (
	EvidenceKeyRequestAPIVersion = "stackkit.member-evidence-key-request/v1"
	EvidenceKeyRequestKind       = "MemberEvidenceKeyRequest"
	EvidenceKeyAPIVersion        = "stackkit.member-evidence-key/v1"
	EvidenceKeyKind              = "MemberEvidenceKeyCertificate"

	// DefaultEvidenceKeyValidity and MaxEvidenceKeyValidity bound a
	// certificate. An expired certificate stops member Apply and Verify until
	// the Home owner certifies the key again.
	DefaultEvidenceKeyValidity = 30 * 24 * time.Hour
	MaxEvidenceKeyValidity     = 90 * 24 * time.Hour
	// MaxEvidenceKeyBytes bounds a request or certificate document.
	MaxEvidenceKeyBytes = 64 << 10

	// IssuedEvidenceKeysRoot is where the Foundation Node records every
	// certificate it issued. A record makes the Foundation Node leave that
	// member's local runtime targets to the member.
	IssuedEvidenceKeysRoot = ".stackkit/fleet/member-evidence-keys"
)

Integrator decision 2026-09-25 (reversible): a member signs its own Apply and Verify evidence with a member evidence key. The member generates the key at join and sends one request file to the Foundation Node; the Home owner returns one signed certificate file. Verifiers accept member evidence only under a valid certificate for the exact StackInstance, plan, and member Site/node/channel tuple. The certificate grants no enrollment, identity signing, credential issuance, ControlAuthority, or Owner authority.

Variables

This section is empty.

Functions

func IsNotMember

func IsNotMember(err error) bool

IsNotMember reports whether err means the workspace holds no member custody.

func Persist

func Persist(workspaceRoot string, custody Custody) error

Persist installs member custody. The workspace must not hold Home owner custody.

func ReadBounded added in v0.46.8

func ReadBounded(path string) ([]byte, error)

ReadBounded reads one operator-selected request or certificate file.

Types

type Admission

type Admission struct {
	APIVersion               string                                  `json:"apiVersion"`
	Kind                     string                                  `json:"kind"`
	StackID                  string                                  `json:"stackId"`
	FleetRef                 string                                  `json:"fleetRef,omitempty"`
	KitSlug                  string                                  `json:"kitSlug"`
	CompilerVersion          string                                  `json:"compilerVersion"`
	PlanHash                 string                                  `json:"planHash"`
	SpecHash                 string                                  `json:"specHash"`
	InventoryHash            string                                  `json:"inventoryHash"`
	Authority                ExecutionBinding                        `json:"authority"`
	Member                   ExecutionBinding                        `json:"member"`
	MemberRoles              []string                                `json:"memberRoles"`
	Grants                   Grants                                  `json:"grants"`
	Verifier                 HomeVerifier                            `json:"verifier"`
	VerifierDistributionRefs []string                                `json:"verifierDistributionRefs"`
	StackSpec                Payload                                 `json:"stackSpec"`
	Inventory                Payload                                 `json:"inventory"`
	IssuedAt                 time.Time                               `json:"issuedAt"`
	ValidUntil               time.Time                               `json:"validUntil"`
	Signature                localevidence.OwnerPolicyStateSignature `json:"signature"`
}

Admission is the Owner-signed `stackkit.member-admission/v1` document.

func Issue

func Issue(request IssueRequest) (Admission, error)

Issue derives the unsigned admission from the exact compiled plan. The caller signs SigningBytes with the Home owner key.

func (Admission) SigningBytes

func (a Admission) SigningBytes() ([]byte, error)

SigningBytes are the canonical bytes covered by the Owner signature.

type CertifiedMember added in v0.46.8

type CertifiedMember struct {
	StackID string
	Member  ExecutionBinding
}

CertifiedMember is one member tuple the Foundation Node certified.

func CertifiedMembers added in v0.46.8

func CertifiedMembers(workspaceRoot string, issuer HomeVerifier) ([]CertifiedMember, error)

CertifiedMembers returns the member tuples the Foundation Node certified, from its own issued records, sorted by StackInstance, Site, and node. Expiry does not matter here: a certified member stays the executor of its own targets, and its evidence is rejected until the key is certified again.

type CertifyRequest added in v0.46.8

type CertifyRequest struct {
	Request   []byte
	Plan      resolvedplan.ResolvedPlan
	Authority localevidence.LocalBinding
	OwnerRef  string
	KeyID     string
	PublicKey ed25519.PublicKey
	Now       time.Time
	ValidFor  time.Duration
}

CertifyRequest is the Foundation Node input for one certificate.

type Custody

type Custody struct {
	APIVersion               string                     `json:"apiVersion"`
	Kind                     string                     `json:"kind"`
	Binding                  localevidence.LocalBinding `json:"localBinding"`
	Authority                localevidence.LocalBinding `json:"authorityBinding"`
	StackID                  string                     `json:"stackId"`
	FleetRef                 string                     `json:"fleetRef,omitempty"`
	PlanHash                 string                     `json:"planHash"`
	Grants                   Grants                     `json:"grants"`
	Verifier                 HomeVerifier               `json:"verifier"`
	VerifierDistributionRefs []string                   `json:"verifierDistributionRefs"`
	AdmissionDigest          string                     `json:"admissionDigest"`
	Admission                Admission                  `json:"admission"`
	JoinedAt                 time.Time                  `json:"joinedAt"`
}

Custody is the verify-only record a member host keeps after joining. It holds no private key: its integrity is the embedded Owner-signed admission, re-verified against the pinned Home key on every load.

func LoadCustody

func LoadCustody(workspaceRoot string) (Custody, error)

LoadCustody reads and re-verifies the member custody of a workspace. It returns os.ErrNotExist when the workspace is not a member.

func NewCustody

func NewCustody(verified Verified, joinedAt time.Time) Custody

NewCustody projects a verified, plan-bound admission into member custody.

type EvidenceKey added in v0.46.8

type EvidenceKey struct {
	KeyID     string `json:"keyId"`
	PublicKey string `json:"publicKey"`
}

EvidenceKey is the public member evidence key.

type EvidenceKeyCertificate added in v0.46.8

type EvidenceKeyCertificate struct {
	APIVersion      string                                  `json:"apiVersion"`
	Kind            string                                  `json:"kind"`
	StackID         string                                  `json:"stackId"`
	PlanHash        string                                  `json:"planHash"`
	AdmissionDigest string                                  `json:"admissionDigest"`
	Authority       ExecutionBinding                        `json:"authority"`
	Member          ExecutionBinding                        `json:"member"`
	Capability      string                                  `json:"capability"`
	Grants          Grants                                  `json:"grants"`
	Key             EvidenceKey                             `json:"key"`
	Issuer          HomeVerifier                            `json:"issuer"`
	IssuedAt        time.Time                               `json:"issuedAt"`
	ValidUntil      time.Time                               `json:"validUntil"`
	Signature       localevidence.OwnerPolicyStateSignature `json:"signature"`
}

EvidenceKeyCertificate travels from the Foundation Node to the member.

func Certify added in v0.46.8

Certify derives the unsigned certificate. The member tuple must be the one the current plan declares under the same admission rules as a join, and the member must hold exactly the current plan. The caller signs SigningBytes with the Home owner key.

func VerifyEvidenceKeyCertificate added in v0.46.8

func VerifyEvidenceKeyCertificate(raw []byte, expect EvidenceKeyExpectation, at time.Time) (EvidenceKeyCertificate, ed25519.PublicKey, error)

VerifyEvidenceKeyCertificate is the single verification helper for member evidence. It accepts a certificate only when the pinned Home owner key signed it for the exact StackInstance, plan, admission, and member tuple, with only the evidence-attestation capability, and when at lies inside its validity.

func (EvidenceKeyCertificate) SigningBytes added in v0.46.8

func (c EvidenceKeyCertificate) SigningBytes() ([]byte, error)

SigningBytes are the canonical bytes covered by the Home owner signature.

type EvidenceKeyExpectation added in v0.46.8

type EvidenceKeyExpectation struct {
	StackID         string
	PlanHash        string
	AdmissionDigest string
	Member          localevidence.LocalBinding
	Issuer          HomeVerifier
}

EvidenceKeyExpectation is what a verifier requires of a certificate.

type EvidenceKeyRequest added in v0.46.8

type EvidenceKeyRequest struct {
	APIVersion      string                                `json:"apiVersion"`
	Kind            string                                `json:"kind"`
	StackID         string                                `json:"stackId"`
	PlanHash        string                                `json:"planHash"`
	AdmissionDigest string                                `json:"admissionDigest"`
	Authority       ExecutionBinding                      `json:"authority"`
	Member          ExecutionBinding                      `json:"member"`
	HomeKeyID       string                                `json:"homeKeyId"`
	Capability      string                                `json:"capability"`
	Key             EvidenceKey                           `json:"key"`
	RequestedAt     time.Time                             `json:"requestedAt"`
	Proof           localevidence.MemberEvidenceSignature `json:"proof"`
}

EvidenceKeyRequest travels from the member to the Foundation Node.

func DecodeEvidenceKeyRequest added in v0.46.8

func DecodeEvidenceKeyRequest(raw []byte) (EvidenceKeyRequest, error)

DecodeEvidenceKeyRequest strictly decodes a request and verifies its proof of possession.

func NewEvidenceKeyRequest added in v0.46.8

func NewEvidenceKeyRequest(custody Custody, key localevidence.MemberEvidenceKey, now time.Time) (EvidenceKeyRequest, error)

NewEvidenceKeyRequest builds the proof-of-possession request for the member evidence key of one joined member.

func (EvidenceKeyRequest) SigningBytes added in v0.46.8

func (r EvidenceKeyRequest) SigningBytes() ([]byte, error)

SigningBytes are the canonical bytes covered by the proof of possession.

type ExecutionBinding

type ExecutionBinding struct {
	SiteRef             string `json:"siteRef"`
	SiteKind            string `json:"siteKind"`
	NodeRef             string `json:"nodeRef"`
	ExecutionChannelRef string `json:"executionChannelRef"`
}

ExecutionBinding is one exact Site/node/execution-channel tuple.

func (ExecutionBinding) LocalBinding

func (b ExecutionBinding) LocalBinding() localevidence.LocalBinding

LocalBinding projects the tuple into the local custody binding shape.

type Grants

type Grants struct {
	Enrollment         bool `json:"enrollment"`
	Signing            bool `json:"signing"`
	CredentialIssuance bool `json:"credentialIssuance"`
	ControlAuthority   bool `json:"controlAuthority"`
}

Grants are closed: a member is verify-only. Every field must be false.

type HomeVerifier

type HomeVerifier struct {
	OwnerRef  string `json:"ownerRef"`
	KeyID     string `json:"keyId"`
	PublicKey string `json:"publicKey"`
}

HomeVerifier is the public Home owner key a member uses to verify Home-signed documents. It never carries private or credential material.

type IssueRequest

type IssueRequest struct {
	Plan            resolvedplan.ResolvedPlan
	StackSpec       []byte
	Inventory       []byte
	InventoryFormat string
	MemberNodeRef   string
	Authority       localevidence.LocalBinding
	OwnerRef        string
	KeyID           string
	PublicKey       ed25519.PublicKey
	Now             time.Time
	ValidFor        time.Duration
}

IssueRequest is the Foundation Node input for one member admission.

type MemberEvidence added in v0.46.8

type MemberEvidence struct {
	Custody     Custody
	Key         localevidence.MemberEvidenceKey
	Certificate EvidenceKeyCertificate
	Public      ed25519.PublicKey
}

MemberEvidence is the verified evidence-attestation custody of a member.

func ImportEvidenceKeyCertificate added in v0.46.8

func ImportEvidenceKeyCertificate(workspaceRoot string, raw []byte, now time.Time) (MemberEvidence, error)

ImportEvidenceKeyCertificate verifies a Home-issued certificate against the member custody and the member's own key and stores it.

func LoadMemberEvidence added in v0.46.8

func LoadMemberEvidence(workspaceRoot string, now time.Time) (MemberEvidence, error)

LoadMemberEvidence returns the verified evidence custody of a member host at now. It fails closed when the certificate is missing, expired, or bound to another tuple or plan.

type Payload

type Payload struct {
	Format  string `json:"format"`
	SHA256  string `json:"sha256"`
	Content string `json:"content"`
}

Payload carries the exact bytes both hosts compile.

type Verified

type Verified struct {
	Admission Admission
	Digest    string
	StackSpec []byte
	Inventory []byte
}

Verified is an admission whose signature, pin, window, and payloads hold.

func Verify

func Verify(raw []byte, pinnedKeyID string, now time.Time) (Verified, error)

Verify decodes one bounded admission and verifies it against the Home key ID the member operator pinned out of band.

func (Verified) BindPlan

func (v Verified) BindPlan(plan resolvedplan.ResolvedPlan) error

BindPlan requires the plan the member compiled from the admitted payloads to reproduce every admitted fact, including the exact plan hash.

Jump to

Keyboard shortcuts

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