Côté shell, BeamReactor n'applique aucun contrôle d'accès. Le modèle est :
Être sur la machine = tout pouvoir. La couche de droits, c'est le système de fichiers.
Ce n'est pas un oubli. Qui peut lancer php lib/apiauth/bin/apikey.php peut aussi lire user/conf/cog.php (identifiants de base) et user/conf/secret.key.php, donc faire la même chose directement en SQL. Un verrou en PHP serait un verrou à l'intérieur quand la porte d'entrée est ouverte — du théâtre.
Ce qui existe réellement côté console :
| Mécanisme | Ce que c'est | Ce que ce n'est pas |
|---|
if (PHP_SAPI !== 'cli') die('forbidden'); | une garde de direction : le script ne s'exécute pas par le web | un contrôle de droits |
lib/.htaccess, plugins/.htaccess | Apache ne sert pas les bin/ | idem |
FairQueue::actAs(), pipeline_jobs.submitted_by | une persona d'ordonnancement : quel seau est débité | une identité de droits |
api_journal.actor | une piste d'audit : qui était au clavier | une authentification |
Points d'entrée console du moteur :
lib/apiauth/bin/apikey.php émission/révocation/journal des clés d'API
plugins/pipeline/bin/dispatcher.php ordonnanceur résident de la file
plugins/pipeline/bin/worker.php une étape d'un job (process jetable)
plugins/notepad/bin/rekey_notepad.php re-chiffrement du notepad
plugins/testrunner/bin/secure_scenario.php scénarios secure() en process jetable
secure() en CLI #
Sans session, $_SESSION est vide : secure() rend toujours false (« simple visiteur »). Un script de console qui a besoin de droits doit donc, explicitement :
- poser
CRON_CONTEXT (handler de cron), ou - forger une session depuis un compte réel (
Agent::run), ou - ne pas passer par
secure() du tout — ce que font le dispatcher et le worker, qui agissent sur la base sans persona.
La persona d'un job #
Le pipeline porte submitted_by : la persona qui a soumis le document (0 en CLI). Le worker prend ses tickets au nom de cette persona (FairQueue::actAs()), c'est son seau qui est débité, et la file est ordonnée par la priorité de ce seau.
C'est une question de partage équitable, pas de droits : le quota est une priorité, jamais un refus. Une persona à sec attend plus longtemps ; elle n'est jamais éconduite.
La trace des actes de console #
Un appel HTTP se désigne tout seul : la clé présentée dit quelle persona agit. Un acte de console n'a ni clé ni session — api_keys.created_by y vaut 0.
Depuis la migration 002_journal_actor, émission et révocation en console laissent une ligne de journal :
2026-09-23 01:28:10.457 Genoh@Stormwing clé 6 user 214 CLI apikey:issue 200
2026-09-23 01:28:15.148 Genoh@Stormwing clé 6 user — CLI apikey:revoke 200
method = CLI, ip vide — il n'y a pas d'appelant réseau, on ne lui en invente pas ;actor = utilisateur système et hôte, via ApiKeys::operator().
Ce n'est pas une identité vérifiée : c'est ce que la machine sait de la personne devant le clavier. Sur une installation client (RGPD art. 9), « qui a émis cette clé, quand » doit avoir une réponse — c'est celle-là.
Émission par l'interface (plugin ulev) : created_by porte l'identifiant de l'admin, la ligne de clé suffit.