Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Note d’étude — Manifeste de privilèges embarqué et signé dans l’exécutable

Statut : note d’étude, NON normative — graine de vision. Capture une direction sécurité-first exprimée par le BDFL (2026-07-28) : à terme, tout exécutable / application / service Air déclare les privilèges qu’il requiert, ce manifeste est embarqué dans l’exécutable (pas un fichier à côté), et la couche de sécurité Air vérifie au lancement que la demande est conforme à la policy du poste — sinon le binaire n’est pas exécutable (fail-closed). Rien n’est engagé ni implémenté ; à rouvrir après la vague 1 (air-sshd). Prolonge ADR-089 (réservation SecurityManager), ADR-112 (air-sandbox) et la doctrine d’exécution par provenance (air-libc-rust-vision).

1. L’idée

Un manifeste déclaratif de privilèges — l’ensemble des Capability et le profil sandbox (allow-list seccomp + chemins Landlock + besoins réseau) dont un exécutable a besoin — embarqué dans l’exécutable lui-même. Au lancement, la couche de sécurité Air calcule demandé ∧ policy-du-poste :

  • si la demande est applicable et conforme à la policy → Air pose la cage correspondante puis exécute ;
  • sinon → refus.

Un exécutable sans ce manifeste (ou avec un manifeste non valide/non signé) n’est pas exécutable. C’est le moindre privilège par construction : le binaire s’exécute avec exactement ce qu’il a déclaré et que la policy autorise, jamais plus.

Préférence BDFL explicite : le manifeste dans l’exécutable, pas un fichier additionnel livré en parallèle (un seul artefact, il voyage avec le binaire).

2. Ça branche des briques qu’Air a DÉJÀ

Cette feature n’est pas un départ de zéro : elle unifie trois doctrines réservées.

  • ADR-112 air-sandbox — le compilateur seccomp (arch-aware, fail-closed, fuzzé) + le poseur Landlock. C’est l’exécuteur du manifeste : il sait déjà transformer un profil en cage et la poser.
  • ADR-126Capability complet (41/41) — depuis cet additif, la couche 0 nomme toutes les capabilities du noyau : le vocabulaire déclaratif du manifeste existe et est exhaustif.
  • ADR-089 SecurityManager — réservé comme « consulté par tous les Managers sensibles → Allow/Deny + log, per-process, embarqué par libair, pas un daemon ». C’est précisément le point de décision « demandé ⊆ policy ».
  • Exécution par provenance (air-libc-rust-vision) — « rustc + signé → natif ; sinon confiné ». Le « sans pattern → pas exécutable » est la version dure de cette porte.

3. Le précédent qui valide l’approche

Le modèle est éprouvé, on le porte (en plus strict), on ne l’invente pas :

  • Entitlements macOS : un ensemble de droits embarqué dans la signature de code du binaire, vérifié par l’OS au lancement. ≈ exactement le manifeste embarqué + signé.
  • Capability routing de Fuchsia : un composant déclare les capacités dont il a besoin ; refus par défaut, routage/vérif par le framework.
  • (À distinguer de : file-capabilities Linux = xattr hors contenu ELF, et accordées pas demandées ; systemd CapabilityBoundingSet=/SystemCallFilter= = déclaratif mais fichier unit à côté ; AppArmor/SELinux = policy attachée au système, pas au binaire. Aucun ne colle aussi bien que macOS/Fuchsia.)

4. Esquisse de mécanisme

  1. Où embarquer — une section ELF dédiée (.note.air.security / .air.caps). Embarquée dans l’exécutable, voyage avec lui, un seul fichier (préférence BDFL). Émise via #[link_section] sur un static, ou une passe de packaging (cargo xtask deb).
  2. Formatbinaire (enveloppe AIRCFGv1 + message capnp), cohérent avec la doctrine config binaire (binary-config-doctrine). Contenu : ensemble de Capability + référence (ou inline) d’un profil sandbox (classe d’allow-list seccomp + chemins Landlock) + besoins réseau.
  3. Intégrité — la section doit être couverte par une signature (air-keystore / air-keysign, ADR-108) et un build reproductible (ADR-025) : sinon un attaquant réécrit la section pour « ne rien demander », et l’enforcement fait confiance à un mensonge. C’est le lien direct avec la provenance.
  4. Décision — au lancement (chemin exec d’air-process), on lit la section ; le SecurityManager calcule demandé ∧ policy-du-poste → pose la cage et exec, ou refuse. La policy du poste est un artefact binaire, dépendant du profil du poste (ADR-006) : elle fixe le plafond de ce qu’un exécutable peut demander.

5. Le point dur — l’inviolabilité passe par le kernel

Faire tenir « sans pattern → pas exécutable » de façon robuste dépasse le userland. Si la vérification ne vit que dans le lanceur Air, un execve émis hors de ce lanceur (par n’importe quel autre programme) la contourne. Pour l’inviolabilité, il faut une porte kernel :

  • un bpf-LSM sur le hook bprm_check_security (au moment exact de l’exec) qui refuse un binaire sans section valide et signée ; ou
  • le modèle provenance-confinement : seuls les binaires signés Air s’exécutent natifs ; les autres sont confinés d’office dans une cage restrictive par défaut.

C’est le morceau à concevoir. Le reste (section, format binaire, décision userland) est du connu.

6. Gradient de déploiement réaliste

  1. Section + décision userland dans le lanceur Air (advisory) — utile tout de suite pour les services Air (ex. les workers d’air-sshd déclarent leur profil).
  2. Signature / provenance de la section (air-keystore, build reproductible).
  3. Porte kernel bpf-LSM — l’inviolabilité (« aucun binaire sans manifeste signé ne s’exécute », même lancé hors du lanceur Air).

7. Questions ouvertes (à trancher en ADR le moment venu)

  • Granularité : capabilities (coarse) + profil sandbox (seccomp/Landlock, fin) — le manifeste porte-t-il un profil inline ou une référence à un profil nommé connu du poste ?
  • Binaires non-Air (glibc, tiers, sans section) : refus strict, ou cage par défaut restrictive ? (relève de la doctrine provenance).
  • Langage de policy du poste : format binaire, héritage/profils (ADR-006), mise à jour.
  • Cycle de révocation : que se passe-t-il si un profil/une clé de signature est révoqué alors qu’un binaire signé avec circule encore ?
  • Interaction avec le privsep (ADR-124) : un service comme air-sshd a plusieurs étages (monitor/enfant/worker) aux profils différents — un manifeste par étage ou un manifeste composite décrivant les transitions ?

8. Suite

  • Rouvrir après la clôture de la vague 1. Candidat à un ADR dédié (« Manifeste de privilèges embarqué + enforcement ») une fois la porte kernel étudiée.
  • Prérequis déjà en place : air-sandbox (poseur), Capability 41/41 (vocabulaire), SecurityManager (décideur, réservé), keystore/provenance (intégrité).