Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrSignatureMismatch = errors.New("signature verification failed")
ErrSignatureMismatch is returned when the Ed25519 signature does not match the payload. This is the only VerifyCommand error worth retrying after a key refresh (key rotation scenario). Other errors (malformed input, wrong sizes) cannot be fixed by fetching a new key.
Functions ¶
func BuildCanonicalPayload ¶
BuildCanonicalPayload constructs the signing payload that must match what the AI server signed. The output is deterministic canonical JSON. Uses json.Encoder with SetEscapeHTML(false) and unescapes U+2028/U+2029 to match Python's json.dumps(ensure_ascii=False) behavior exactly. Go's encoding/json escapes U+2028/U+2029 even with SetEscapeHTML(false), but Python emits them as raw UTF-8.
func IsLocalEnv ¶
IsLocalEnv reports whether the server URL points to a local development environment (localhost, 127.0.0.1, etc.) where the AI signing server is unavailable and command signing cannot work.
func ResolveAuthEnv ¶
ResolveAuthEnv determines the auth environment from the alpacon server URL. dev.alpacon.io → "dev", everything else → "" (prod default). This lets alpamon derive its environment from trusted local config rather than trusting the key_id provided by the relay (alpacon-server).
NOTE: When adding new environments (e.g. staging), add a corresponding hostname check below and update TestResolveAuthEnv.
Types ¶
type KeyManager ¶
type KeyManager struct {
// contains filtered or unexported fields
}
KeyManager fetches and caches the Ed25519 public key from the AI server.
func NewKeyManager ¶
func NewKeyManager(aiBaseURL string, refreshSecs int, authEnv string, client *http.Client) *KeyManager
NewKeyManager creates a key manager that fetches from the AI server. authEnv is the environment identifier (e.g. "dev") derived from the alpacon server URL via ResolveAuthEnv. It is used to scope key fetches so that alpamon only trusts keys for its own environment.
func (*KeyManager) GetPublicKey ¶
func (m *KeyManager) GetPublicKey() (ed25519.PublicKey, error)
GetPublicKey returns a copy of the cached public key, refreshing if stale.
func (*KeyManager) GetPublicKeyForKID ¶
func (m *KeyManager) GetPublicKeyForKID(kid string) (ed25519.PublicKey, error)
GetPublicKeyForKID returns the cached key if its kid matches. If the kid doesn't match (possible key rotation), it refreshes the active key for this environment from the AI server. The key_id from the command is used only as a cache-staleness hint — never as a query parameter — so that a compromised relay cannot direct alpamon to fetch an arbitrary key.
func (*KeyManager) Refresh ¶
func (m *KeyManager) Refresh() error
Refresh fetches the latest public key from the AI server. Only one refresh runs at a time; concurrent callers wait for the in-flight result. If the cache is still valid (another goroutine refreshed), this is a no-op.
func (*KeyManager) RefreshAndGet ¶
func (m *KeyManager) RefreshAndGet() (ed25519.PublicKey, error)
RefreshAndGet fetches the active key unconditionally (ignoring cache TTL) and returns it. Used for one-time retry on signature mismatch when the command has no key_id. This is env-scoped and does not accept any relay-provided key identifier.