agent

package
v0.16.0 Latest Latest
Warning

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

Go to latest
Published: Sep 4, 2026 License: MIT Imports: 34 Imported by: 0

Documentation

Index

Constants

View Source
const SigningPrivateKeyPEMType = "NEBULA ED25519 PRIVATE KEY"

SigningPrivateKeyPEMType is the PEM block type used to persist the Ed25519 signing private key on disk (mode 0600). The block bytes contain the full 64-byte ed25519.PrivateKey (seed + public-key half), so SignerFromDisk can reconstruct the keypair without re-deriving from a seed.

View Source
const SigningPublicKeyPEMType = "NEBULA ED25519 PUBLIC KEY"

SigningPublicKeyPEMType is the PEM block type used by the agent for its Ed25519 poll-signature public key (ADR 0004 §7.1).

Variables

This section is empty.

Functions

func Enroll

func Enroll(ctx context.Context, serverURL, token, dataDir, signingKeyPath, nebulaConfigPath string) error

Enroll performs the enrollment flow: generates keypair, sends public key to the server with the token, saves received cert (and CA cert) to dataDir, writes the rendered Nebula config to nebulaConfigPath, and writes the Ed25519 signing private key to signingKeyPath.

nebulaConfigPath is the path Nebula actually reads its config from; an empty value falls back to dataDir/config.yml for backward compatibility. Honoring it keeps the initial enroll write and the running daemon's rewrites pointed at the same file (#224); the daemon resolves the same path in poller.go.

signingKeyPath is intentionally separate from dataDir — Nebula's data dir holds Nebula-owned secrets (host.key / host.crt / ca.crt / config.yml), while the agent's PoP signing key (ADR 0004) is the agent's concern and lives next to agent.yml (default /etc/nebula-agent/host.signing.key). The parent directory of signingKeyPath is created with mode 0o755 if missing.

func IsRekey

func IsRekey(err error) bool

IsRekey reports whether err carries a server rekey signal.

func IsRevoked

func IsRevoked(err error) bool

IsRevoked reports whether err originates from a 403/410 server response.

func ReadCertFingerprint

func ReadCertFingerprint(dataDir string) (string, error)

ReadCertFingerprint reads the host certificate from dataDir and returns its fingerprint.

func ReadCertFingerprintAt added in v0.8.0

func ReadCertFingerprintAt(path string) (string, error)

ReadCertFingerprintAt reads the host certificate from an explicit path.

func Reenroll

func Reenroll(ctx context.Context, serverURL, token string, options ReenrollOptions) error

Reenroll replaces an existing agent identity using its current profile.

Types

type BootstrapAction added in v0.8.0

type BootstrapAction string
const (
	BootstrapEnroll BootstrapAction = "enroll"
	BootstrapImport BootstrapAction = "import"
)

func DecideBootstrap added in v0.8.0

func DecideBootstrap(state DiscoveryState, token string, force bool) (BootstrapAction, error)

DecideBootstrap is the shared local state/token-purpose gate used by both command entrypoints. It performs no network or filesystem writes.

type DiscoveryState added in v0.8.0

type DiscoveryState string
const (
	DiscoveryNone     DiscoveryState = "none"
	DiscoveryComplete DiscoveryState = "complete"
	DiscoveryUnsafe   DiscoveryState = "unsafe"
)

type EnrollResponse

type EnrollResponse struct {
	CertificatePEM   string `json:"certificate_pem"`
	CACertificatePEM string `json:"ca_certificate_pem"`
	ConfigYAML       string `json:"config_yaml"`
	ConfigVersion    int    `json:"config_version,omitempty"`
}

EnrollResponse is the response from the enrollment endpoint.

type ExistingDiscovery added in v0.8.0

type ExistingDiscovery struct {
	State            DiscoveryState      `json:"state"`
	Manifest         []string            `json:"manifest,omitempty"`
	Issues           []string            `json:"issues,omitempty"`
	Snapshot         meshimport.Snapshot `json:"snapshot"`
	CACertificatePEM string              `json:"ca_certificate_pem,omitempty"`
	PayloadHash      string              `json:"payload_hash,omitempty"`
	HostPrivateKey   []byte              `json:"-"`
}

ExistingDiscovery contains only public upload material plus the local host key needed for the one-time X25519 challenge. HostPrivateKey is excluded from serialization and must be wiped as soon as the challenge proof is computed.

func DiscoverExisting added in v0.8.0

func DiscoverExisting(configPath string) (*ExistingDiscovery, error)

DiscoverExisting inspects one file-backed Nebula installation. Unsafe and partial local states are returned as data so the CLI can explain remediation without making a management-server request.

func (*ExistingDiscovery) Wipe added in v0.8.0

func (d *ExistingDiscovery) Wipe()

type ImportResult added in v0.8.0

type ImportResult struct {
	HostID      string `json:"host_id"`
	Fingerprint string `json:"certificate_fingerprint"`
	Status      string `json:"status"`
	Created     bool   `json:"created"`
	SessionID   string `json:"-"`
}

func ImportExisting added in v0.8.0

func ImportExisting(
	ctx context.Context,
	serverURL, token, signingKeyPath string,
	discovery *ExistingDiscovery,
) (*ImportResult, error)

ImportExisting registers a discovered installation without writing any Nebula-owned file. It creates or reuses only the agent Ed25519 signing key.

type PollHTTPError added in v0.8.0

type PollHTTPError struct {
	StatusCode int
	Body       string
	ReadErr    error
}

PollHTTPError preserves a non-terminal poll status so bootstrap recovery can distinguish an unknown signing identity (401) from transport ambiguity.

func (*PollHTTPError) Error added in v0.8.0

func (e *PollHTTPError) Error() string

type Poller

type Poller struct {
	// contains filtered or unexported fields
}

Poller periodically checks the management server for updates.

func NewPoller

func NewPoller(cfg PollerConfig, logger *slog.Logger) (*Poller, error)

NewPoller creates a new Poller and loads the Ed25519 signing key needed to sign poll requests (ADR 0004 §7.1). If the key cannot be loaded the returned error is propagated to the caller; the agent must re-enroll before polling can resume.

func (*Poller) PollOnce

func (p *Poller) PollOnce(ctx context.Context) error

PollOnce performs a single signed poll iteration and returns. The enroll subcommand uses it to verify the freshly enrolled host can reach the server before exiting. Errors are informational — callers decide whether to gate behavior on them; the daemon's Run() never invokes PollOnce.

func (*Poller) Run

func (p *Poller) Run(ctx context.Context) error

Run starts the poll loop, blocking until ctx is canceled. The signing key is zeroized on return so it does not linger in heap memory.

type PollerConfig

type PollerConfig struct {
	ServerURL      string
	Fingerprint    string
	DataDir        string
	SigningKeyPath string
	Interval       time.Duration
	PIDFile        string
	// ReloadCommand, when set, replaces the SIGHUP-to-PIDFile reload with a
	// shell command (see nebulaReloader).
	ReloadCommand string
	// NebulaConfigPath is where the rendered Nebula config.yml is written.
	// Empty falls back to DataDir/config.yml. Honors agent.yml's
	// nebula_config_path so the daemon writes the config to the file Nebula
	// actually reads, not always DataDir/config.yml (#224).
	NebulaConfigPath string
	NebulaCAPath     string
	NebulaCertPath   string
	NebulaKeyPath    string
	ImportSessionID  string
	// HTTPTimeout bounds a single poll request. Zero or negative falls back
	// to defaultAgentHTTPTimeout.
	HTTPTimeout time.Duration
}

PollerConfig holds configuration for the Poller.

type ReenrollOptions added in v0.8.0

type ReenrollOptions struct {
	DataDir        string
	SigningKeyPath string
	PIDFile        string
	// ReloadCommand, when set, replaces the SIGHUP-to-PIDFile reload with a
	// shell command (see nebulaReloader).
	ReloadCommand string
	Profile       models.AgentProfile
}

ReenrollOptions preserves the resolved paths of an existing agent during a server-requested rekey.

type RekeyError

type RekeyError struct {
	Token string
}

RekeyError is returned by Poller.poll when the server signals that the agent must regenerate its keypair (force-rotate with new_key=true, ADR 0004 §7.1). The token attached to the error is single-use and short-lived; the caller is expected to invoke agent.Reenroll with it.

func (*RekeyError) Error

func (e *RekeyError) Error() string

type RevocationError

type RevocationError struct {
	StatusCode int
	Reason     string
	Body       string
}

RevocationError is returned by Poller.poll when the management server signals that the agent should stop polling — either 403 revoked (the host is blocked) or 410 gone (the host row has been deleted). Run() returns this error so callers can exit with status 0 and avoid systemd auto-restart loops.

func (*RevocationError) Error

func (e *RevocationError) Error() string

type UpdatesResponse

type UpdatesResponse struct {
	HasUpdates      bool     `json:"has_updates"`
	CertificatePEM  *string  `json:"certificate_pem,omitempty"`
	CACertPEM       *string  `json:"ca_certificate_pem,omitempty"`
	ConfigYAML      *string  `json:"config_yaml,omitempty"`
	ConfigVersion   int      `json:"config_version,omitempty"`
	Blocklist       []string `json:"blocklist"`
	ImportPending   bool     `json:"import_pending,omitempty"`
	RekeyRequired   bool     `json:"rekey_required,omitempty"`
	EnrollmentToken string   `json:"enrollment_token,omitempty"`
}

UpdatesResponse is the response from the agent updates endpoint.

Directories

Path Synopsis
Package pop is the agent-side proof-of-possession helper for ADR 0004 (#75): it owns the Ed25519 signing private key, knows how to load it from disk, and signs poll-request canonical strings.
Package pop is the agent-side proof-of-possession helper for ADR 0004 (#75): it owns the Ed25519 signing private key, knows how to load it from disk, and signs poll-request canonical strings.

Jump to

Keyboard shortcuts

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