package machine_identity import ( "bytes" "crypto/ed25519" "encoding/base64" "encoding/json" "errors" "io" "os" "strings" ) type registryDocument struct { Version string `json:"version"` Audience string `json:"audience"` Principals []registryPrincipal `json:"principals"` } type registryPrincipal struct { PrincipalID string `json:"principal_id"` Enabled bool `json:"enabled"` Keys []registryKey `json:"keys"` } type registryKey struct { KeyID string `json:"kid"` PublicKey string `json:"public_key_base64url"` Status string `json:"status"` Scopes []string `json:"scopes"` } func LoadRegistry(filePath, expectedAudience string) (*Registry, error) { if strings.TrimSpace(filePath) == "" || !validAudiences[expectedAudience] { return nil, errors.New("machine principal registry path and audience are required") } raw, err := os.ReadFile(filePath) if err != nil { return nil, errors.New("read machine principal registry") } decoder := json.NewDecoder(bytes.NewReader(raw)) decoder.DisallowUnknownFields() var document registryDocument if err = decoder.Decode(&document); err != nil { return nil, errors.New("invalid machine principal registry") } if err = decoder.Decode(&struct{}{}); !errors.Is(err, io.EOF) { return nil, errors.New("invalid machine principal registry") } if document.Version != "yovision.machine-principal-registry/v1" || document.Audience != expectedAudience || len(document.Principals) == 0 { return nil, errors.New("invalid machine principal registry") } records := make([]KeyRecord, 0) for _, principal := range document.Principals { if len(principal.Keys) == 0 { return nil, errors.New("invalid machine principal registry") } for _, key := range principal.Keys { publicKey, decodeErr := base64.RawURLEncoding.Strict().DecodeString(key.PublicKey) if decodeErr != nil || len(publicKey) != ed25519.PublicKeySize || (key.Status != "active" && key.Status != "revoked") { return nil, errors.New("invalid machine principal registry") } records = append(records, KeyRecord{Principal: principal.PrincipalID, KeyID: key.KeyID, PublicKey: ed25519.PublicKey(publicKey), Audience: document.Audience, Scopes: key.Scopes, Enabled: principal.Enabled, Revoked: key.Status == "revoked"}) } } return NewRegistry(records...) }