Aller au contenu

Confidentialite

Le code source constitue la propriété intellectuelle de l'organisation. Ce chapitre applique le modèle de classification et zones de confiance au service SCM, au niveau Confidentiel.


Rappel du niveau Confidentiel

Propriété Exigence
Accès Restreint par rôle (RBAC)
Authentification SSO + MFA obligatoire
Chiffrement At-rest et in-transit
Journalisation Détaillée, avec retention minimum 1 an
Revue d'accès Periodique (trimestrielle)
Isolation réseau Zone Chaîne logicielle uniquement

Pour le detail complet du modèle, voir :


Permissions par dépôt

Modèle de rôles Gitea

Rôle Permissions Usage
Owner Administration complète du dépôt Tech lead, responsable dépôt
Admin Gestion des settings, webhooks, collaborateurs Ops, maintainers
Write Push, merge PR, gérer issues Développeurs de l'équipe
Read Clone, voir le code, commenter les PR Relecteurs, auditeurs

Bonnes pratiques

  • Attribuer les permissions par équipe (pas par utilisateur individuel)
  • Utiliser les organisations pour regrouper les dépôts par domaine metier
  • Limiter le rôle Owner a 2-3 personnes maximum par dépôt
  • Désactiver la creation de dépôts par defaut (DEFAULT_ALLOW_CREATE_ORGANIZATION = false)
; app.ini — restreindre les creations
[service]
DISABLE_REGISTRATION       = true
DEFAULT_ALLOW_CREATE_ORGANIZATION = false

[repository]
MAX_CREATION_LIMIT = 0  ; seuls les admins creent des depots

Protection de branches

Configurer des regles de protection sur les branches critiques (main, release/*) :

Regle Valeur recommandee Justification
Bloquer les push directs Oui Forcer le passage par PR
Approbations requises >= 1 Revue par un pair minimum
Statut CI requis Oui Tests passes avant merge
Bloquer le force push Oui Preserver l'historique
Bloquer la suppression de branche Oui Protéger les branches critiques
Commits signes requis Recommande Garantir l'authenticite

Configuration via API

curl -X POST "https://gitea.example.com/api/v1/repos/mon-org/mon-repo/branch_protections" \
  -H "Content-Type: application/json" \
  -H "Authorization: token ${GITEA_ADMIN_TOKEN}" \
  -d '{
    "branch_name": "main",
    "enable_push": false,
    "enable_push_whitelist": true,
    "push_whitelist_usernames": [],
    "require_signed_commits": true,
    "required_approvals": 1,
    "enable_status_check": true,
    "status_check_contexts": ["ci/build", "ci/test"],
    "block_on_rejected_reviews": true,
    "block_on_outdated_branch": true,
    "dismiss_stale_approvals": true
  }'

Commits signes (GPG / SSH)

La signature des commits garantit l'authenticite de l'auteur. Gitea supporte la vérification GPG et SSH.

Configurer la signature SSH (recommande)

# Generer une cle de signature SSH
ssh-keygen -t ed25519 -C "dev@example.com" -f ~/.ssh/signing_key

# Configurer Git pour signer avec SSH
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/signing_key.pub
git config --global commit.gpgsign true
git config --global tag.gpgsign true

Configurer la signature GPG

# Generer une cle GPG
gpg --full-generate-key

# Configurer Git
git config --global user.signingkey ABCDEF1234567890
git config --global commit.gpgsign true

Politique de signature dans Gitea

; app.ini
[repository.signing]
SIGNING_KEY    = default
INITIAL_COMMIT = always
CRUD_ACTIONS   = pubkey, twofa, parentsigned
MERGES         = pubkey, twofa, basesigned, commitssigned

SSH vs GPG

Privilegiez la signature SSH : les développeurs ont déjà une cle SSH pour l'accès au dépôt, pas besoin de gérer une infrastructure GPG séparée.


Journal d'audit

Gitea enregistre les événements d'accès et de modification dans son journal d'audit.

Événements traces

Événement Niveau Données enregistrees
Connexion utilisateur Info User, IP, méthode (local/OIDC), date
Echec de connexion Warn User tente, IP, date
Creation de dépôt Info User, org, nom du dépôt, date
Suppression de dépôt Warn User, org, nom du dépôt, date
Push Info User, dépôt, branche, commits
Merge de PR Info User, dépôt, PR, branche cible
Changement de permissions Warn User, cible, ancien rôle, nouveau rôle
Creation de token API Info User, nom du token, scopes, date

Configuration du journal

; app.ini
[log]
MODE      = console, file
LEVEL     = info
ROOT_PATH = /data/gitea/log

[log.file]
FILE_NAME = gitea.log
MAX_SIZE  = 100  ; Mo
MAX_DAYS  = 365
MAX_BACKUPS = 12
COMPRESS  = true

Export vers un SIEM

Pour centraliser les logs dans un SIEM (ELK, Loki, Splunk), configurer un sidecar Fluentd/Fluent Bit ou un volume partage :

# Fluent Bit config
[INPUT]
    Name tail
    Path /data/gitea/log/gitea.log
    Tag  gitea

[OUTPUT]
    Name  loki
    Match gitea
    Host  loki.example.com
    Port  3100
    Labels job=gitea

Isolation réseau

Zone Chaîne logicielle

Le service SCM est déployé dans la zone Chaîne logicielle. Les flux autorises sont strictement limites :

Source Destination Port Autorisation
Zone Chaîne logicielle Gitea 443, 22 Autorise
Zone Entreprise Gitea 443 Autorise (lecture web)
Zone Production Gitea Non Bloque
Internet Gitea Non Bloque
Gitea Keycloak 443 Autorise
Gitea Internet 443 Autorise (mirroring seulement)

Pas d'exposition publique

Gitea ne doit jamais etre expose sur Internet. Si des contributeurs externes doivent accéder au code, utiliser un miroir push vers une plateforme publique (GitHub) ou un VPN.

Firewall applicatif

Configurer les regles de rate limiting dans Caddy :

# Caddyfile — rate limiting
gitea.example.com {
    rate_limit {
        zone gitea_api {
            match {
                path /api/*
            }
            key {remote_host}
            events 100
            window 1m
        }
    }
    reverse_proxy gitea:3000
}

Sauvegardes chiffrees

Stratégie de sauvegarde

Composant Méthode Fréquence Retention Chiffrement
Base PostgreSQL pg_dump + compression Quotidien 30 jours AES-256
Dépôts Git gitea dump ou rsync Quotidien 30 jours AES-256
Stockage LFS Snapshot MinIO Quotidien 30 jours SSE-S3
Configuration Copie app.ini + secrets À chaque changement 90 jours AES-256

Script de sauvegarde

#!/bin/bash
# backup-gitea.sh
set -euo pipefail

BACKUP_DIR="/srv/backups/gitea/$(date +%Y-%m-%d)"
ENCRYPTION_KEY="/etc/gitea/backup.key"

mkdir -p "${BACKUP_DIR}"

# 1. Sauvegarde PostgreSQL
podman exec gitea-postgres pg_dump -U gitea gitea | \
  gzip | \
  openssl enc -aes-256-cbc -salt -pbkdf2 -pass file:"${ENCRYPTION_KEY}" \
  > "${BACKUP_DIR}/postgres.sql.gz.enc"

# 2. Sauvegarde Gitea (depots + config)
podman exec gitea gitea dump -c /data/gitea/conf/app.ini -f /tmp/gitea-dump.zip
podman cp gitea:/tmp/gitea-dump.zip "${BACKUP_DIR}/"
openssl enc -aes-256-cbc -salt -pbkdf2 -pass file:"${ENCRYPTION_KEY}" \
  -in "${BACKUP_DIR}/gitea-dump.zip" \
  -out "${BACKUP_DIR}/gitea-dump.zip.enc"
rm "${BACKUP_DIR}/gitea-dump.zip"

# 3. Nettoyage des sauvegardes > 30 jours
find /srv/backups/gitea/ -maxdepth 1 -type d -mtime +30 -exec rm -rf {} +

echo "Sauvegarde terminee : ${BACKUP_DIR}"

Prevention des fuites de secrets

Secret scanning

Empecher les développeurs de commiter accidentellement des secrets (cles API, mots de passe, tokens) :

Pre-commit hook (côté client)

#!/bin/bash
# .git/hooks/pre-commit
# Detecter les patterns de secrets courants

PATTERNS=(
  'AKIA[0-9A-Z]{16}'           # AWS Access Key
  'ghp_[a-zA-Z0-9]{36}'        # GitHub Personal Token
  'glpat-[a-zA-Z0-9\-]{20}'    # GitLab Personal Token
  'sk-[a-zA-Z0-9]{48}'         # OpenAI API Key
  'password\s*=\s*["\x27].+'   # Mot de passe en clair
  'PRIVATE KEY'                 # Cle privee
)

for pattern in "${PATTERNS[@]}"; do
  if git diff --cached --diff-filter=ACM | grep -qP "${pattern}"; then
    echo "ERREUR : Secret detecte dans le commit (pattern: ${pattern})"
    echo "Utilisez un gestionnaire de secrets (Vault, .env) au lieu de commiter des secrets."
    exit 1
  fi
done

Pre-receive hook (côté serveur)

Configurer un hook pre-receive sur Gitea pour bloquer les push contenant des secrets, même si le développeur n'a pas le hook local :

#!/bin/bash
# hooks/pre-receive
while read oldrev newrev refname; do
  DIFF=$(git diff --diff-filter=ACM "${oldrev}..${newrev}" 2>/dev/null || git diff-tree -r --diff-filter=ACM "${newrev}")
  if echo "${DIFF}" | grep -qP 'AKIA[0-9A-Z]{16}|PRIVATE KEY|password\s*='; then
    echo "REJECTED: Secret detected in push to ${refname}"
    exit 1
  fi
done

Defense en profondeur

Le secret scanning n'est pas infaillible. Combinez-le avec une rotation régulière des secrets et un gestionnaire de secrets (HashiCorp Vault) pour minimiser l'impact d'une fuite.