Documentation
¶
Overview ¶
Package store persists coordinator state in SQLite.
Index ¶
- Constants
- Variables
- func SanitizeName(hostname string) string
- func ValidateCredentials(username, password string) error
- type APIToken
- type Admin
- type AuditEntry
- type AuthKey
- type AuthKeyOptions
- type Node
- type RegisterRequest
- type Store
- func (s *Store) AdminCount(ctx context.Context) (int, error)
- func (s *Store) AppendAudit(ctx context.Context, e AuditEntry) error
- func (s *Store) Authenticate(ctx context.Context, username, password string) (Admin, error)
- func (s *Store) Backup(ctx context.Context, path string) error
- func (s *Store) ChangePassword(ctx context.Context, adminID, current, next, keepSessionToken string) error
- func (s *Store) Check(ctx context.Context) error
- func (s *Store) Close() error
- func (s *Store) CreateAPIToken(ctx context.Context, adminID, description string, ttl time.Duration) (APIToken, string, error)
- func (s *Store) CreateAdmin(ctx context.Context, username, password string) (Admin, error)
- func (s *Store) CreateAuthKey(ctx context.Context, opts AuthKeyOptions) (AuthKey, string, error)
- func (s *Store) CreateFirstAdmin(ctx context.Context, username, password string) (Admin, error)
- func (s *Store) CreateSession(ctx context.Context, adminID string, ttl time.Duration) (string, time.Time, error)
- func (s *Store) DeleteAPIToken(ctx context.Context, id string) error
- func (s *Store) DeleteNode(ctx context.Context, id string) error
- func (s *Store) DeleteSession(ctx context.Context, token string) error
- func (s *Store) EnsureAuthKey(ctx context.Context, secret string, opts AuthKeyOptions) (AuthKey, error)
- func (s *Store) ExpireNode(ctx context.Context, id string) (Node, error)
- func (s *Store) ListAPITokens(ctx context.Context) ([]APIToken, error)
- func (s *Store) ListAudit(ctx context.Context, limit int, before int64) ([]AuditEntry, error)
- func (s *Store) ListAuthKeys(ctx context.Context) ([]AuthKey, error)
- func (s *Store) ListNodes(ctx context.Context) ([]Node, error)
- func (s *Store) NodeByID(ctx context.Context, id string) (Node, error)
- func (s *Store) NodeByName(ctx context.Context, name string) (Node, error)
- func (s *Store) NodeByToken(ctx context.Context, token string) (Node, error)
- func (s *Store) OIDCAdmin(ctx context.Context, subject, username string) (Admin, error)
- func (s *Store) Postgres() bool
- func (s *Store) RegisterNode(ctx context.Context, req RegisterRequest) (Node, string, error)
- func (s *Store) RenameNode(ctx context.Context, id, name string) (Node, error)
- func (s *Store) RevokeAuthKey(ctx context.Context, id string) error
- func (s *Store) SessionAdmin(ctx context.Context, token string) (Admin, error)
- func (s *Store) SetAdvertisedRoutes(ctx context.Context, id string, routes []netip.Prefix) error
- func (s *Store) SetApprovedRoutes(ctx context.Context, id string, routes []netip.Prefix) (Node, error)
- func (s *Store) SetNodeExpiry(ctx context.Context, id string, disabled bool, ttl time.Duration) (Node, error)
- func (s *Store) SetNodeTags(ctx context.Context, id string, tags []string) (Node, error)
- func (s *Store) SetSetting(ctx context.Context, key, value string) error
- func (s *Store) Setting(ctx context.Context, key string) (string, error)
- func (s *Store) TokenAdmin(ctx context.Context, secret string) (Admin, string, error)
- func (s *Store) TouchNode(ctx context.Context, id string) error
- func (s *Store) UpdateNodeEndpoints(ctx context.Context, id string, endpoints []string) error
- type ValidationError
Constants ¶
const ( SettingPublicURL = "public_url" // SettingPolicy holds the access-control policy (HuJSON text). SettingPolicy = "policy" // SettingDNS holds the DNS configuration (JSON). SettingDNS = "dns" // SettingKeyExpiryDays is how long node keys last (0 or unset: forever). SettingKeyExpiryDays = "key_expiry_days" )
Setting keys.
const APITokenPrefix = "tpa_"
APITokenPrefix starts every API token.
const AuthKeyPrefix = "trk_"
AuthKeyPrefix starts every pre-auth key, making leaked keys easy to recognise.
const DBFile = "coordinator.db"
DBFile is the database file name inside the data directory.
const NodeTokenPrefix = "trn_"
NodeTokenPrefix starts every node token.
const SessionTokenPrefix = "trs_"
SessionTokenPrefix starts every admin session token.
Variables ¶
var ( // ErrConflict is returned when a unique value (name, username) is taken. ErrConflict = errors.New("already exists") // ErrInvalidCredentials is returned for a wrong username or password. ErrInvalidCredentials = errors.New("invalid username or password") // ErrSetupDone is returned when creating the first admin after setup. ErrSetupDone = errors.New("setup has already been completed") )
var ( // ErrNotFound is returned when a requested record does not exist. ErrNotFound = errors.New("not found") // ErrInvalidAuthKey is returned for unknown, revoked, expired or used-up auth keys. ErrInvalidAuthKey = errors.New("invalid or expired auth key") )
var ErrPostgresBackup = errors.New("the database is Postgres: back it up with pg_dump")
ErrPostgresBackup is returned by Backup on Postgres, which has its own tools for that.
Functions ¶
func SanitizeName ¶
SanitizeName turns a hostname into a DNS label: lowercase letters, digits and hyphens, at most 63 characters.
func ValidateCredentials ¶
ValidateCredentials checks username and password requirements.
Types ¶
type APIToken ¶
type APIToken struct {
ID string
Description string
AdminID string
Admin string // username
CreatedAt time.Time
ExpiresAt *time.Time
LastUsed *time.Time
}
APIToken lets scripts call the admin API as the admin who created it.
type Admin ¶
type Admin struct {
ID string
Username string
CreatedAt time.Time
// HasPassword is false for admins who sign in through OIDC only.
HasPassword bool
}
Admin is a user of the configuration UI.
type AuditEntry ¶
type AuditEntry struct {
ID int64
// Time is set by AppendAudit.
Time time.Time
// Actor is the admin's username, or e.g. "cli" or "policy".
Actor string
Action string
Target string
Detail string
}
AuditEntry records an administrative change.
type AuthKey ¶
type AuthKey struct {
ID string
Description string
Reusable bool
UsedCount int
Revoked bool
// Tags are given to nodes the key enrolls.
Tags []string
CreatedAt time.Time
ExpiresAt *time.Time
}
AuthKey is a pre-auth key used to enroll nodes. The secret itself is only returned once, at creation time.
type AuthKeyOptions ¶
type AuthKeyOptions struct {
Description string
Reusable bool
// TTL is the key lifetime; zero means it never expires.
TTL time.Duration
Tags []string
}
AuthKeyOptions configures a new auth key.
type Node ¶
type Node struct {
ID string
Name string
Hostname string
OS string
WGPublicKey [32]byte
IPv4 netip.Addr
Endpoints []string
Tags []string
// AdvertisedRoutes are the subnet routes the node offers to forward
// (0.0.0.0/0 for an exit node); ApprovedRoutes are those an admin or the
// policy allowed. Routes() is what is in effect.
AdvertisedRoutes []netip.Prefix
ApprovedRoutes []netip.Prefix
CreatedAt time.Time
LastSeen time.Time
// ExpiresAt is when the node must re-authenticate; nil means never.
ExpiresAt *time.Time
// ExpiryDisabled exempts the node from key expiry.
ExpiryDisabled bool
}
Node is a machine enrolled in the mesh.
type RegisterRequest ¶
type RegisterRequest struct {
AuthKey string
WGPublicKey [32]byte
Hostname string
OS string
// Prefix is the overlay network new addresses are allocated from.
Prefix netip.Prefix
// KeyExpiry is how long the node may stay connected before it has to
// re-authenticate with an auth key; zero means indefinitely.
KeyExpiry time.Duration
}
RegisterRequest holds what a node presents when enrolling.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is a handle to the coordinator database.
func OpenMemory ¶
OpenMemory opens a private in-memory database, for tests.
func OpenPostgres ¶
OpenPostgres opens a Postgres database (a postgres:// URL or key=value DSN) and applies migrations. One coordinator should use it at a time: online state lives in the coordinator's memory.
func (*Store) AdminCount ¶
AdminCount returns the number of admins.
func (*Store) AppendAudit ¶
func (s *Store) AppendAudit(ctx context.Context, e AuditEntry) error
AppendAudit adds an entry to the audit log.
func (*Store) Authenticate ¶
Authenticate checks a username and password.
func (*Store) Backup ¶
Backup writes a consistent copy of the database to path, which must not exist. It is safe while the coordinator is running.
func (*Store) ChangePassword ¶
func (s *Store) ChangePassword(ctx context.Context, adminID, current, next, keepSessionToken string) error
ChangePassword replaces an admin's password after checking the current one, and ends all of that admin's other sessions.
func (*Store) CreateAPIToken ¶
func (s *Store) CreateAPIToken(ctx context.Context, adminID, description string, ttl time.Duration) (APIToken, string, error)
CreateAPIToken creates a token for adminID and returns it with its secret, which is not stored. A zero ttl never expires.
func (*Store) CreateAdmin ¶
CreateAdmin adds another admin.
func (*Store) CreateAuthKey ¶
CreateAuthKey creates a key and returns it with its one-time-visible secret.
func (*Store) CreateFirstAdmin ¶
CreateFirstAdmin creates the initial admin. It fails with ErrSetupDone if any admin exists, atomically, so two concurrent setups cannot both win.
func (*Store) CreateSession ¶
func (s *Store) CreateSession(ctx context.Context, adminID string, ttl time.Duration) (string, time.Time, error)
CreateSession starts a session for an admin and returns its token.
func (*Store) DeleteAPIToken ¶
DeleteAPIToken revokes a token.
func (*Store) DeleteNode ¶
DeleteNode removes a node; its address becomes free for reuse.
func (*Store) DeleteSession ¶
DeleteSession ends a session.
func (*Store) EnsureAuthKey ¶
func (s *Store) EnsureAuthKey(ctx context.Context, secret string, opts AuthKeyOptions) (AuthKey, error)
EnsureAuthKey makes sure a key with the given secret exists, creating it with opts if needed. It is used to bootstrap a coordinator from config.
func (*Store) ExpireNode ¶
ExpireNode expires a node's key now: it must re-authenticate.
func (*Store) ListAPITokens ¶
ListAPITokens returns all tokens, newest first.
func (*Store) ListAudit ¶
ListAudit returns up to limit entries older than before (all when before is 0), newest first.
func (*Store) ListAuthKeys ¶
ListAuthKeys returns all keys, newest first.
func (*Store) NodeByName ¶
NodeByName returns a node by name.
func (*Store) NodeByToken ¶
NodeByToken returns the node that owns token.
func (*Store) OIDCAdmin ¶
OIDCAdmin returns the admin linked to an OIDC subject ("<issuer> <sub>"), creating one named username on first sign-in. Such admins have no password. An existing password admin with the same name is never linked: that could hand their account to whoever controls the identity provider account, so it is reported as ErrConflict instead.
func (*Store) RegisterNode ¶
RegisterNode validates the auth key and enrolls the node, or re-enrolls it if its WireGuard key is already known. It returns the node and a new token; any previous token for the node stops working.
func (*Store) RenameNode ¶
RenameNode changes a node's name, sanitising it to a DNS label.
func (*Store) RevokeAuthKey ¶
RevokeAuthKey marks a key unusable. Nodes it enrolled are unaffected.
func (*Store) SessionAdmin ¶
SessionAdmin returns the admin owning a valid session token.
func (*Store) SetAdvertisedRoutes ¶
SetAdvertisedRoutes records the routes a node offers.
func (*Store) SetApprovedRoutes ¶
func (s *Store) SetApprovedRoutes(ctx context.Context, id string, routes []netip.Prefix) (Node, error)
SetApprovedRoutes replaces the routes a node may use.
func (*Store) SetNodeExpiry ¶
func (s *Store) SetNodeExpiry(ctx context.Context, id string, disabled bool, ttl time.Duration) (Node, error)
SetNodeExpiry exempts a node from key expiry, or subjects it again with a fresh expiry ttl from now (none when ttl is zero).
func (*Store) SetNodeTags ¶
SetNodeTags replaces a node's tags.
func (*Store) SetSetting ¶
SetSetting stores a setting.
func (*Store) TokenAdmin ¶
TokenAdmin returns the admin a valid token acts as, and the token's ID.
type ValidationError ¶
type ValidationError struct{ Msg string }
ValidationError reports input that breaks a rule (as opposed to a failure).
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string