Aller au contenu

Gouvernance — Apportez votre clé (BYOK)

AKKO embarque par défaut une couche IA souveraine — chaque modèle tourne localement via la couche AI Runtime (Ollama + famille Qwen 2.5 + Nomic Embed). Certaines charges de travail réclament malgré tout un fournisseur hébergé (long contexte, vision, tool-calling avancé). La fonctionnalité Apportez votre clé (BYOK) permet à un administrateur plateforme d'enregistrer une clé de fournisseur IA externe (OpenAI, Anthropic, Mistral, Cohere ou tout endpoint compatible OpenAI) sur la passerelle IA AKKO sans renoncer à la souveraineté par défaut.

Modèle de menace

  • Plaintext dans Git — fichiers values committés par accident. Mitigé : la clé n'est jamais saisie dans un fichier YAML, uniquement via le modal du cockpit.
  • Plaintext dans les logs containerprint(key) accidentel. Mitigé : le modèle Pydantic enveloppe api_key dans SecretStr, donc repr(), str() et model_dump_json() retournent tous **********.
  • Plaintext au repos — le chiffrement de disque ne protège pas contre une exfiltration via pg_dump. Mitigé : chiffrement colonne pgp_sym_encrypt(plaintext, master_key, 'cipher-algo=aes256') ; la clé maître vit dans un Secret k8s séparé.
  • Plaintext dans les réponses HTTP — les administrateurs ne voient que la forme masquée (sk-…XXXX). Le plaintext n'est jamais renvoyé par le cockpit-backend.

Architecture (en un paragraphe)

La page cockpit #ai-models embarque une section dédiée « Apportez votre clé », visible uniquement par le rôle realm admin. Ajouter une clé POSTe sur /api/governance/byok/keys. Le cockpit-backend (akko-cockpit-backend) enveloppe le plaintext dans SecretStr, ouvre une courte transaction Postgres, positionne akko.master_key via SET LOCAL, et INSERTe pgp_sym_encrypt(plain, master, 'cipher-algo=aes256') dans akko_governance.byok_keys. La variable plaintext locale sort de portée immédiatement. Le futur worker de synchronisation LiteLLM (PR-D, sprint séparé) déchiffre dans Postgres et émet une clé virtuelle liée au rbac_label.

Activation du coffre (opérateur)

La fonctionnalité est désactivée par défaut. Deux valeurs Helm + deux Secrets à câbler :

# 1. Générer une clé maître 256 bits.
kubectl -n akko create secret generic akko-cockpit-backend-byok \
  --from-literal=master-key="$(openssl rand -hex 32)"

# 2. Câbler le DSN Postgres vers l'instance data.
kubectl -n akko create secret generic akko-cockpit-backend-byok-pg \
  --from-literal=dsn="postgresql://akko:$AKKO_PG_PASSWORD@akko-postgresql-data:5432/akko"

# 3. Patcher les valeurs Helm.
cat >> my-values.yaml <<EOF
akko-cockpit-backend:
  byok:
    encryptionKey:
      secretName: akko-cockpit-backend-byok
    dsnSecretRef:
      name: akko-cockpit-backend-byok-pg
EOF

# 4. helm upgrade — le job akko-init crée la table de manière idempotente.
helm upgrade akko helm/akko -n akko -f my-values.yaml

Enregistrer une clé (administrateur)

  1. Connectez-vous au cockpit en alice (akko-admin).
  2. Ouvrez l'entrée latérale AI Models.
  3. Faites défiler jusqu'à la section « Apportez votre clé ». Cliquez sur Ajouter une clé fournisseur.
  4. Choisissez le fournisseur (OpenAI / Anthropic / Mistral / Cohere / Custom).
  5. Renseignez un Libellé unique (par ex. corp-prod-key).
  6. Collez la Clé API. Validez.

La ligne apparaît dans le tableau avec le masque sk-…XXXX. Le plaintext n'est jamais réaffiché ; si vous le perdez, regénérez-en un côté fournisseur et ré-uploadez.

Désactiver une clé sans la supprimer

Basculez le bouton Activer / Désactiver dans la colonne Actions. Le ciphertext reste dans le coffre — réactiver restaure le routage sans ré-upload. C'est le kill-switch supporté pendant une panne fournisseur.

Supprimer définitivement une clé

Cliquez sur Supprimer dans la colonne Actions et confirmez. La ligne est supprimée. Il n'y a pas de corbeille.

Piste d'audit

Chaque action BYOK (add / toggle / delete / list) émet un événement OCSF class_uid 3008 (LLM Access Mgmt). Exemple :

{
  "class_uid": 3008,
  "type_uid": 300801,
  "activity_id": 1,
  "activity_name": "byok.key.add",
  "actor": { "user": { "uid": "...alice...", "name": "alice", "email_addr": "alice@akko-ai.com", "type_id": 1 } },
  "resources": [ { "type_name": "byok-key", "name": "corp-prod-key" } ],
  "status": "Success"
}

Le champ plaintext api_key n'est JAMAIS sérialisé dans les événements OCSF.

Rotation de la clé maître

Procédure de rotation annuelle :

ALTER SYSTEM SET akko.master_key = '<nouvelle-clé>';
SELECT pg_reload_conf();
UPDATE akko_governance.byok_keys
   SET encrypted_key = akko.reencrypt(encrypted_key, '<ancienne-clé>', '<nouvelle-clé>');

Mêmes helpers que pour le chiffrement des colonnes PII — voir Admin / Chiffrement.

Références

  • ADR-068 — design du coffre BYOK
  • feedback_layer_first_abstraction — vocabulaire « passerelle IA » / « clé fournisseur IA »
  • feedback_lego_zero_hardcoded — clés via Secret, jamais en ligne
  • postgres/init/12-pgcrypto.sqlakko.encrypt_pii / akko.decrypt_pii / akko.reencrypt