Aller au contenu

Confidentialite

Harbor manipule des données classees Confidentiel : images conteneur embarquant du code proprietaire, des fichiers de configuration et des charts Helm revelant l'architecture interne. Ce chapitre detaille les mesures de protection correspondantes, en référence au cadre de Classification et zones de confiance.

Rappel de classification

Donnée Classification Justification
Images conteneur applicatives Confidentiel Contiennent le code compile et les configs
Charts Helm Confidentiel Révèlent l'architecture de déploiement
SBOM et attestations Confidentiel Révèlent la liste des dependances
Images de base (library) Interne Images publiques validees, pas de code proprietaire
Résultats de scan Confidentiel Révèlent les vulnerabilites exploitables
Credentials robot accounts Restreint Accès direct au push/pull
Logs d'audit Harbor Confidentiel Révèlent les patterns d'usage et de déploiement
Configuration Harbor (DB, cles) Restreint Compromission = contrôle total du registre

Impact d'une compromission

La compromission du registre permet à un attaquant d'injecter des images malveillantes qui seront déployées automatiquement en production. C'est un vecteur d'attaque de la supply chain logicielle.

RBAC par projet

Modèle de rôles

Harbor définit des rôles par projet avec des permissions granulaires :

Rôle Push Pull Scan Delete Config projet Robot mgmt
Project Admin Oui Oui Oui Oui Oui Oui
Maintainer Oui Oui Oui Oui Non Oui
Developer Oui Oui Non Non Non Non
Guest Non Oui Non Non Non Non
Limited Guest Non Oui* Non Non Non Non

*Limited Guest : pull uniquement sur les artefacts explicitement partages.

Configuration des projets

# Projet prive — equipe backend uniquement
curl -X POST https://harbor.example.com/api/v2.0/projects \
  -H "Content-Type: application/json" \
  -u admin:ADMIN_PASSWORD \
  -d '{
    "project_name": "app-backend",
    "public": false,
    "metadata": {
      "auto_scan": "true",
      "severity": "high",
      "enable_content_trust": "true",
      "prevent_vul": "true",
      "reuse_sys_cve_allowlist": "true"
    }
  }'

# Ajouter un membre avec le role Developer
curl -X POST "https://harbor.example.com/api/v2.0/projects/app-backend/members" \
  -H "Content-Type: application/json" \
  -u admin:ADMIN_PASSWORD \
  -d '{
    "role_id": 2,
    "member_user": {
      "username": "dev-jean"
    }
  }'

Matrice d'accès recommandee

Projet Visibilité Équipe DevOps Équipe Dev Kubernetes Auditeurs
library Public* Admin Guest Pull Guest
app-backend Prive Maintainer Developer Pull Guest
app-frontend Prive Maintainer Developer Pull Guest
charts Prive Admin Developer Pull Guest
mirror Public* Admin Guest Pull Guest

*Public interne = visible par tous les utilisateurs authentifies Harbor, pas accessible depuis Internet.

Robot accounts avec scope minimal

Principe du moindre privilege

Chaque robot account ne doit avoir que les permissions strictement nécessaires :

Robot Projets autorises Permissions Expire
robot-ci-backend app-backend Push, Pull 90 jours
robot-ci-frontend app-frontend Push, Pull 90 jours
robot-k8s-prod app-*, library, charts Pull 90 jours
robot-k8s-dev library Pull 30 jours
robot-mirror mirror Push, Pull 180 jours
# Creer un robot CI avec scope minimal
curl -X POST https://harbor.example.com/api/v2.0/robots \
  -H "Content-Type: application/json" \
  -u admin:ADMIN_PASSWORD \
  -d '{
    "name": "robot-ci-backend",
    "description": "CI/CD push for app-backend only",
    "duration": 90,
    "level": "project",
    "permissions": [
      {
        "namespace": "app-backend",
        "kind": "project",
        "access": [
          {"resource": "repository", "action": "push"},
          {"resource": "repository", "action": "pull"},
          {"resource": "tag", "action": "create"},
          {"resource": "artifact-label", "action": "create"}
        ]
      }
    ]
  }'

Ne jamais utiliser le compte admin dans les pipelines

Le compte admin a accès a tous les projets et toutes les fonctions. Utiliser exclusivement des robot accounts avec des scopes limites dans les pipelines CI/CD et les configurations Kubernetes.

Politique de scan de vulnerabilites

Configuration de la politique de blocage

Harbor peut empecher le pull d'images contenant des vulnerabilites critiques :

Sévérité Action Applicable a
Critical Bloquer le pull Tous les projets
High Bloquer le pull Projets applicatifs
Medium Alerte, pull autorise Tous les projets
Low Information, pas d'action Tous les projets
# Configurer la politique de blocage sur un projet
curl -X PUT "https://harbor.example.com/api/v2.0/projects/app-backend" \
  -H "Content-Type: application/json" \
  -u admin:ADMIN_PASSWORD \
  -d '{
    "metadata": {
      "prevent_vul": "true",
      "severity": "high",
      "auto_scan": "true"
    }
  }'

CVE allowlist

Pour les vulnerabilites connues sans correctif disponible (unfixed), Harbor permet de définir une allowlist :

# Ajouter une CVE a la allowlist du projet
curl -X PUT "https://harbor.example.com/api/v2.0/projects/app-backend" \
  -H "Content-Type: application/json" \
  -u admin:ADMIN_PASSWORD \
  -d '{
    "cve_allowlist": {
      "items": [
        {"cve_id": "CVE-2024-12345"},
        {"cve_id": "CVE-2024-67890"}
      ],
      "expires_at": 1735689600
    }
  }'

Allowlist avec expiration

Toute CVE ajoutee a la allowlist doit avoir une date d'expiration. Les exceptions permanentes ne sont pas acceptables — elles doivent etre revues régulièrement.

Tag immutability

L'immutabilite des tags empeche l'ecrasement d'une version déjà poussee. C'est une protection critique contre la modification malveillante d'images en production.

Regles d'immutabilite

Pattern de tag Immutable Justification
v*.*.* Oui Versions semantiques — jamais ecrasees
sha-* Oui Hash de commit — identifiant unique
latest Non Tag mutable par nature, usage dev uniquement
*-dev Non Tags de développement, réutilisables
# Creer une regle d'immutabilite
curl -X POST "https://harbor.example.com/api/v2.0/projects/app-backend/immutabletagrules" \
  -H "Content-Type: application/json" \
  -u admin:ADMIN_PASSWORD \
  -d '{
    "tag_selectors": [
      {
        "kind": "doublestar",
        "decoration": "matches",
        "pattern": "v*.*.*"
      },
      {
        "kind": "doublestar",
        "decoration": "matches",
        "pattern": "sha-*"
      }
    ],
    "scope_selectors": {
      "repository": [
        {
          "kind": "doublestar",
          "decoration": "repoMatches",
          "pattern": "**"
        }
      ]
    }
  }'

Audit log

Événements traces

Harbor journalise toutes les opérations sur les artefacts :

Événement Données enregistrees Retention
Push artefact Qui, quoi, digest, tag, timestamp 1 an
Pull artefact Qui, quoi, digest, tag, IP source, timestamp 1 an
Delete artefact Qui, quoi, digest, tag, timestamp 5 ans
Scan lance/termine Artefact, résultats (nb vulns), timestamp 1 an
Réplication Source, destination, artefacts, statut, timestamp 1 an
Creation/suppression robot Admin, robot name, scope, timestamp 5 ans
Modification projet Admin, projet, changements, timestamp 5 ans
Connexion/deconnexion Utilisateur, IP, méthode auth, timestamp 1 an

Exporter les logs vers le SIEM

# Configurer Alloy/Promtail pour collecter les logs Harbor
# alloy-harbor.river
loki.source.kubernetes "harbor" {
  targets = discovery.kubernetes.harbor.targets
  forward_to = [loki.write.default.receiver]

  clustering {
    enabled = true
  }
}

discovery.kubernetes "harbor" {
  role = "pod"
  namespaces {
    names = ["harbor"]
  }
  selectors {
    role = "pod"
    label = "app=harbor"
  }
}

Alertes de sécurité sur les logs

Alerte Condition Sévérité
Push non autorise Push depuis une IP hors CI/CD Critical
Suppression d'artefact en prod Delete sur un projet applicatif Warning
Echec de scan répète > 3 scan failures consecutifs Warning
Robot token expire utilise Authentification échouée avec robot token Warning
Modification de politique projet Changement de sévérité ou d'immutabilite Info

Stockage chiffre

Chiffrement au repos

Composant Méthode de chiffrement
Blobs (images) MinIO server-side encryption (SSE-S3 ou SSE-KMS)
PostgreSQL TDE (Transparent Data Encryption) ou chiffrement volume
Redis Chiffrement volume
Backups AES-256 via Vault Transit
# Configurer MinIO avec chiffrement SSE-KMS
mc admin config set minio identity_openid \
  config_url="https://keycloak.example.com/realms/organization/.well-known/openid-configuration"

# Activer le chiffrement par defaut sur le bucket
mc encrypt set sse-s3 minio/harbor-registry

Chiffrement en transit

Flux Protocole Port
Client → Harbor TLS 1.3 443
Harbor Core → Registry mTLS 5000
Harbor → PostgreSQL TLS (require) 5432
Harbor → Redis TLS 6380
Harbor → MinIO TLS 9000
Réplication inter-Harbor TLS 443

Isolation réseau

Harbor est déployé dans la zone Chaîne logicielle avec des regles de flux strictes :

┌─────────────────────────────────────────────────────────┐
│              Zone Chaine logicielle                       │
│                                                         │
│  ┌──────────────────────────────────────────────┐       │
│  │       Segment Registre (10.30.2.0/24)        │       │
│  │                                              │       │
│  │  ┌────────┐  ┌────────┐  ┌───────┐  ┌─────┐ │       │
│  │  │ Harbor │  │ Harbor │  │ Trivy │  │Redis│ │       │
│  │  │ Core#1 │  │ Core#2 │  │       │  │     │ │       │
│  │  └────────┘  └────────┘  └───────┘  └─────┘ │       │
│  │                                              │       │
│  │  ┌────────┐  ┌───────────┐                   │       │
│  │  │Registry│  │PostgreSQL │                   │       │
│  │  └────────┘  └───────────┘                   │       │
│  └──────────────────────────────────────────────┘       │
│                                                         │
└─────────────────────────────────────────────────────────┘

Regles de flux

Source Destination Port Protocole Justification
CI/CD (Gitea Actions) Harbor 443/TCP HTTPS Push images et charts
Kubernetes (prod) Harbor 443/TCP HTTPS Pull images
Kubernetes (dev) Harbor 443/TCP HTTPS Pull images de base
Harbor PostgreSQL 5432/TCP TLS Metadonnees
Harbor MinIO 9000/TCP TLS Stockage blobs
Harbor Redis 6380/TCP TLS Cache et queue
Harbor NVD/GitHub 443/TCP HTTPS Mise à jour base CVE
Harbor Harbor DR 443/TCP HTTPS Réplication
Management Harbor 9090/TCP HTTPS Metriques Prometheus

Aucun accès direct aux composants internes

PostgreSQL, Redis et MinIO ne sont accessibles que depuis les composants Harbor. Aucun autre service ne doit pouvoir s'y connecter directement.