identity

package
v0.0.0-...-9e7beb5 Latest Latest
Warning

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

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

Documentation

Overview

Package identity holds the agent's per-cluster mTLS identity.

The private key is generated on the cluster and never leaves it. Enrollment sends a certificate signing request; the SaaS signs it and returns a certificate. That is the difference between a vendor who can impersonate a customer's cluster and one who demonstrably cannot — and it is a property of where the key is made, not of anyone's good intentions.

Index

Constants

View Source
const (
	DefaultDir = "/etc/cube/advisor-agent"
)

Default locations on a CubeCOS node.

Variables

View Source
var (
	ErrTokenRejected   = errors.New("identity: pairing token rejected")
	ErrAlreadyEnrolled = errors.New("identity: this node already has an identity")
)

Enrollment errors a caller should distinguish, because the operator's next action differs for each: get a fresh token, fix connectivity, or re-enroll.

Functions

func CSR

func CSR(key *ecdsa.PrivateKey, clusterID string) ([]byte, error)

CSR returns a PEM certificate signing request for clusterID.

It carries the public key and the cluster's name. It does not, and must not, carry the private key — see the test that inspects the bytes.

func Exists

func Exists(dir string) bool

Exists reports whether dir already holds a key and certificate. Enrollment consults this so a second run cannot silently replace a working identity — re-enrolling is a deliberate act, not an accident of running a command twice.

func Fingerprint

func Fingerprint(pub *ecdsa.PublicKey) (string, error)

Fingerprint is the SHA-256 of the public key in SPKI form, base64 encoded and prefixed — the same shape ssh prints.

This is the value an operator compares on screen during enrollment verify, so it must derive from the key alone: it has to be computable before a certificate exists, and identical on both sides.

func LoadServer

func LoadServer(dir string) (string, error)

LoadServer reads the tunnel address SaveServer persisted. A missing file is not an error — it just means enrolment predates this feature, or never resolved an address — so the caller (run) can fall back to requiring -server explicitly instead of failing to load an identity that is otherwise fine.

func NewKey

func NewKey() (*ecdsa.PrivateKey, error)

NewKey generates a fresh keypair on this machine.

P-256 rather than Ed25519: it is what every TLS stack and every FIPS module on the target platforms already accepts, and enrollment is not the place to spend novelty budget.

func PublicKeyOf

func PublicKeyOf(k *ecdsa.PrivateKey) *ecdsa.PublicKey

PublicKeyOf exposes a key's public half, for callers computing a fingerprint before enrolment.

func Remove

func Remove(dir string) error

Remove deletes a stored identity.

Used only by an explicit re-enrolment. It is a separate function rather than something Save does implicitly, because silently replacing an identity is how a cluster loses the certificate the SaaS is currently accepting.

func SaveServer

func SaveServer(dir, addr string) error

SaveServer persists the tunnel address enrolment resolved, so a later `run` needs no operator argument. Mode 0644, unlike the key: this is not secret, it is the same host:port an operator could read straight off the SaaS.

It is a separate write from Save rather than a field on it, so an existing caller of Save is unaffected and a failure to persist the address (a read-only /etc, say) never looks like a failure to persist the identity.

Types

type EnrollRequest

type EnrollRequest = enrollproto.Request

The wire shapes live in pkg/enrollproto, which the SaaS imports too — one definition rather than two that must be kept in step.

type EnrollResponse

type EnrollResponse = enrollproto.Response

The wire shapes live in pkg/enrollproto, which the SaaS imports too — one definition rather than two that must be kept in step.

type Enroller

type Enroller struct {
	// BaseURL of the SaaS enrollment endpoint.
	BaseURL string
	// HTTPClient is overridable for tests and for sites behind an egress proxy.
	HTTPClient *http.Client
	// AgentVersion is reported so an operator can see what enrolled.
	AgentVersion string
}

Enroller exchanges a pairing token for a signed identity.

func (*Enroller) Enroll

func (e *Enroller) Enroll(ctx context.Context, clusterID, token string) (*Identity, error)

Enroll generates a key, requests a certificate for clusterID with the pairing token, and returns the resulting identity. It does not write anything to disk; the caller decides where an identity lives.

The token authenticates this one request and is deliberately not stored: it is single-use, and an unused copy on disk is a credential nobody is watching.

func (*Enroller) EnrollAndSave

func (e *Enroller) EnrollAndSave(ctx context.Context, dir, clusterID, token string) (*Identity, error)

EnrollAndSave is the operator-facing path: enroll, then persist to dir.

It refuses when dir already holds an identity. Re-enrolling should be a deliberate act — running the command twice must not quietly invalidate the certificate the SaaS is currently accepting.

type Identity

type Identity struct {
	ClusterID string
	// contains filtered or unexported fields
}

Identity is the agent's cluster identity: a private key that never leaves, the certificate the SaaS signed for it, and the CA that certificate chains to.

func Load

func Load(dir string) (*Identity, error)

Load reads an identity from dir.

It refuses a private key whose mode is looser than 0600. A key other users can read is not an identity, and continuing with a warning would make the agent's own logs the only record that its identity was readable.

func (*Identity) Fingerprint

func (i *Identity) Fingerprint() (string, error)

Fingerprint of this identity.

func (*Identity) Save

func (i *Identity) Save(dir string) error

Save writes the identity to dir with the key mode-restricted.

func (*Identity) TLSConfig

func (i *Identity) TLSConfig(serverName string) (*tls.Config, error)

TLSConfig builds the client configuration for the tunnel dial.

The CA obtained at enrollment is the only root trusted for this connection: the agent talks to the service that enrolled it, not to anything holding a certificate from a public CA.

Jump to

Keyboard shortcuts

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