Sécurité & Configuration (Agent)
1. Heartbeat et health check
Section titled “1. Heartbeat et health check”Par défaut, un heartbeat est envoyé toutes les 30 secondes. Son payload contient : agent_id, version, hostname (selon politique de confidentialité), timestamp UTC, durée depuis démarrage, état Docker, nombre de containers connus, dernière collecte métrique, version du protocole et capacité (logs, pull, exec). L’API répond par un ACK et peut transmettre une configuration révisée non sensible.
- Health Docker : timeout court sur
Ping; l’Agent reste vivant mais signaledocker_unhealthy. - Health API : un heartbeat manqué n’entraîne pas l’arrêt du processus ; l’état passe
degradedaprès quelques échéances. - Reconnexion : nouveaux appels gRPC après fermeture du canal, avec backoff exponentiel borné (1 s, 2 s, 4 s… maximum 60 s) et jitter.
- Shutdown : arrêt des workers, annulation des streams, flush du spool dans une deadline courte, puis fermeture Docker et gRPC.
Le heartbeat ne remplace pas les probes systemd. Un watchdog local peut vérifier que la boucle principale progresse ; il ne doit pas redémarrer l’Agent sur une simple coupure réseau.
2. Sécurité
Section titled “2. Sécurité”mTLS Agent ↔ API
Section titled “mTLS Agent ↔ API”- L’API possède une CA de confiance (ou une PKI d’entreprise) et un certificat serveur dont le SAN correspond au nom gRPC.
- L’Agent possède un certificat client signé par cette CA et sa clé privée lisible uniquement par le compte de service.
- Chaque partie vérifie le certificat de l’autre pendant le handshake TLS ; l’API mappe le sujet/SAN du certificat à un
agent_idet au client mono-tenant. - Le token d’enrôlement n’est pas utilisé comme secret permanent : après émission du certificat, l’Agent utilise mTLS et, si souhaité, un token opaque court dans les métadonnées gRPC pour une défense en profondeur.
func ClientTLS(certFile, keyFile, caFile string) (*tls.Config, error) { cert, err := tls.LoadX509KeyPair(certFile, keyFile); if err != nil { return nil, err } caPEM, err := os.ReadFile(caFile); if err != nil { return nil, err } roots := x509.NewCertPool(); if !roots.AppendCertsFromPEM(caPEM) { return nil, errors.New("invalid CA") } return &tls.Config{MinVersion: tls.VersionTLS13, Certificates: []tls.Certificate{cert}, RootCAs: roots, ServerName: "berth-api"}, nil}Enrôlement et rotation
Section titled “Enrôlement et rotation”- L’administrateur crée dans l’API un Agent et un token unique, aléatoire, à usage unique, avec expiration courte et empreinte stockée côté API (jamais le token en clair).
- L’Agent est installé avec ce token hors du dépôt Git et contacte l’API en bootstrap TLS contrôlé ; il envoie son token, une clé publique/CSR et sa version.
- L’API valide le token, associe la demande au client et signe le certificat client. L’Agent écrit certificat et clé avec permissions
0600, efface le token et redémarre sa connexion mTLS. - La rotation est proactive avant expiration : nouvelle clé/CSR, validation par l’ancien certificat, installation atomique, puis révocation de l’ancien certificat après chevauchement.
- Une révocation (compromission, désinstallation) bloque l’agent côté API via serial/SAN et invalide les secrets associés.
Ne pas placer une clé privée dans une image de container, un fichier de configuration versionné ou les logs. En déploiement containerisé, monter les certificats en lecture seule et protéger le volume hôte.
3. Configuration
Section titled “3. Configuration”agent_id: "" # fourni après enrollmentapi: address: "api.berth.example.com:443" server_name: "berth-api" enrollment_token_file: "/etc/berth-agent/enrollment-token" request_timeout: 10sheartbeat_interval: 30smetrics_interval: 15sdiscovery_interval: 60s
docker: host: "unix:///var/run/docker.sock" request_timeout: 10s labels_allowlist: ["com.berth.application_id", "com.berth.managed"]
tls: ca_file: "/etc/berth-agent/tls/ca.pem" cert_file: "/etc/berth-agent/tls/agent.crt" key_file: "/etc/berth-agent/tls/agent.key" renew_before: 168h
resilience: spool_dir: "/var/lib/berth-agent/spool" max_spool_bytes: 104857600 max_retries: 5 backoff_max: 60slogs: level: "info" format: "json"Les secrets et chemins peuvent être surchargés par variables d’environnement (BERTH_API_ADDRESS, BERTH_TLS_KEY_FILE, etc.). La configuration est validée au démarrage : URL gRPC, intervalle positif, certificats lisibles, spool sous une limite et socket Docker accessible.
