[refactor](maestro): retire the PKI and federation identity layer

Contract rev 9 removes the instance CA, client certificates, the peer listener and the trust store fleet-wide. Internal traffic is plaintext HTTP on each service single :8080 listener, so there is no peer identity left to authorize: delete lib/pki, lib/federation, devboot, the per-service database role model and the /api/peers* and /api/instances surfaces, and drop the console Trusted services UI. Config delivery now rides a dedicated ES256 token from lib/configsign rather than mTLS, and the instance fingerprint is derived from a persisted random key and is informational only. main.go also wires the surfaces introduced by the later commits, which this change is what makes possible.
This commit is contained in:
2026-10-19 02:39:15 +01:00
parent 3220944b12
commit 17d5307110
29 changed files with 735 additions and 2512 deletions
+60 -6
View File
@@ -15,16 +15,23 @@
// Package instance holds the instance's public identity: a small, self-
// contained file at the data root that answers "who am I" for the hub app's
// public profile (hub-app theme M1) and, later, federation attestation.
// public profile (hub-app theme M1). Rev 9 removed federation, so the
// fingerprint here is informational only (it is no longer a trust anchor).
package instance
import (
"crypto/rand"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"os"
"path/filepath"
)
// keyFileName is the persisted random instance key backing Fingerprint.
const keyFileName = "instance.key"
// Identity is the instance's user-visible self-description. Name falls back to
// DCNTRLIZED_INSTANCE_NAME and then the hostname when instance.json is absent;
// Title and Description are optional and only ever come from the file.
@@ -39,6 +46,55 @@ func Path(dataRoot string) string {
return filepath.Join(dataRoot, "instance.json")
}
// Fingerprint returns the instance's stable app-level identity fingerprint in
// the same "sha256:ab:cd:…" shape the CA fingerprint used to have. Rev 9
// removed the PKI layer, so the value is derived from a persisted 32-byte
// random key at <dataRoot>/instance.key (created on first use, chmod 600) —
// not from any certificate. It is unauthenticated by design; a consumer can
// still compare it to detect a changed peer. Returns "" when the key cannot be
// read or created (the public profile then omits the field).
func Fingerprint(dataRoot string) string {
key, err := loadOrCreateKey(dataRoot)
if err != nil {
return ""
}
sum := sha256.Sum256(key)
hexStr := hex.EncodeToString(sum[:])
b := make([]byte, 0, len(hexStr)+len(hexStr)/2+7)
b = append(b, "sha256:"...)
for i := 0; i < len(hexStr); i += 2 {
if i > 0 {
b = append(b, ':')
}
b = append(b, hexStr[i:i+2]...)
}
return string(b)
}
// loadOrCreateKey reads <dataRoot>/instance.key, generating it atomically on
// first use.
func loadOrCreateKey(dataRoot string) ([]byte, error) {
path := filepath.Join(dataRoot, keyFileName)
if data, err := os.ReadFile(path); err == nil && len(data) == 32 {
return data, nil
}
key := make([]byte, 32)
if _, err := rand.Read(key); err != nil {
return nil, fmt.Errorf("generate instance key: %w", err)
}
tmp := path + ".tmp"
if err := os.WriteFile(tmp, key, 0o600); err != nil {
return nil, fmt.Errorf("write instance key: %w", err)
}
if err := os.Chmod(tmp, 0o600); err != nil {
return nil, fmt.Errorf("chmod instance key: %w", err)
}
if err := os.Rename(tmp, path); err != nil {
return nil, fmt.Errorf("replace instance key: %w", err)
}
return key, nil
}
// Load resolves the instance identity: instance.json when present, else
// DCNTRLIZED_INSTANCE_NAME, else os.Hostname(). Read-on-demand by design —
// no daemon state, so an edited file shows up on the next request.
@@ -61,9 +117,8 @@ func Load(dataRoot string) Identity {
}
// Save atomically writes the identity file (tmp + rename), chmod 600 like the
// rest of Maestro's file stores. The owner-gated edit endpoint that uses this
// lands with the federation theme; the helper exists so both callers share one
// write path.
// rest of Maestro's file stores. The helper exists so the create and edit
// paths share one write path.
func Save(dataRoot string, id Identity) error {
if id.Name == "" {
return fmt.Errorf("instance name must not be empty")
@@ -90,8 +145,7 @@ func defaultIdentity() Identity {
if name := os.Getenv("DCNTRLIZED_INSTANCE_NAME"); name != "" {
return Identity{Name: name}
}
// The domain the instance announces as is its natural public name;
// federation attestation will reuse it.
// The domain the instance announces as is its natural public name.
if domain := os.Getenv("DCNTRLIZED_INSTANCE_DOMAIN"); domain != "" {
return Identity{Name: domain}
}
+6 -6
View File
@@ -77,12 +77,12 @@ func TestDefaultIdentityFallbacks(t *testing.T) {
func TestLooksLikeContainerID(t *testing.T) {
cases := map[string]bool{
"6079761d6e4d": true,
"ABCDEF0123456789abcdef0123456789": true,
"archlinux": false,
"maestro-1": false,
"abc": false,
"": false,
"6079761d6e4d": true,
"ABCDEF0123456789abcdef0123456789": true,
"archlinux": false,
"maestro-1": false,
"abc": false,
"": false,
}
for s, want := range cases {
if got := looksLikeContainerID(s); got != want {