Retour au blog

Californie AB 1856: Pourquoi l'Open Source a Échappé à la Loi sur la Vérification de l'Âge

Salut HaWkers, le 26 août 2026 le Sénat de Californie a adopté l'AB 1856 par 39 voix contre 0, et le lendemain l'Assemblée a approuvé les amendements par 69 voix contre 0. Zéro vote contre dans les deux chambres. Le texte retire ceux qui distribuent du logiciel sous licence libre de la définition d'"operating system provider" du Digital Age Assurance Act, la loi qui entre en vigueur le 1er janvier 2027 et oblige les systèmes d'exploitation à collecter l'âge de l'utilisateur.

Vous maintenez un projet open source et vous n'aviez jamais imaginé qu'une loi d'un État américain puisse vous atteindre? Eh bien elle a failli le faire. Dans cet article je montre ce que l'AB 1043 a créé, quel est le texte exact qui a sauvé l'open source, qui reste dans le périmètre, et comment auditer concrètement si les licences de votre projet passent le critère.

Ce Que l'AB 1043 a Créé et Pourquoi Cela a Fait Peur à l'Open Source

Le Digital Age Assurance Act, c'est l'AB 1043, signée par le gouverneur Gavin Newsom le 13 octobre 2025 et applicable à partir du 1er janvier 2027. Sa logique est de déplacer la vérification de l'âge du site vers le système d'exploitation.

En pratique, le texte oblige tout "operating system provider" à deux choses. D'abord, afficher lors de la configuration initiale du compte un écran demandant la date de naissance, l'âge, ou les deux, de l'utilisateur principal de l'appareil. Ensuite, maintenir une API temps réel raisonnablement cohérente qui renvoie la tranche d'âge de cet utilisateur à tout développeur qui la demande, au moment où l'application est téléchargée ou ouverte.

Les tranches sont au nombre de quatre: moins de 13 ans, de 13 à moins de 16 ans, de 16 à moins de 18 ans, et 18 ans ou plus. Et le développeur de l'app ne peut pas simplement ignorer le signal: la loi impose de traiter la réponse du système d'exploitation ou de la boutique d'applications comme l'indicateur principal de la tranche d'âge, sauf preuve claire et convaincante du contraire.

Maintenant relisez cela en pensant à Debian. Qui est le "provider"? L'équipe de release? Chaque mainteneur de paquet? La personne qui héberge un miroir du dépôt? Comment un projet sans entité juridique, sans écran d'onboarding et sans contrat avec l'utilisateur final peut-il livrer une API d'âge en temps réel? C'était une exigence impossible à respecter et coûteuse à enfreindre, et c'est exactement l'alarme que la communauté a tirée.

Le Texte de l'Exemption: Deux Phrases Qui Changent Tout

L'AB 1856 n'abroge pas l'AB 1043. Elle réécrit chirurgicalement deux définitions.

La première porte sur le système d'exploitation. "Operating system provider" ne couvre plus celui qui distribue un système d'exploitation ou une application sous des termes de licence qui permettent au destinataire de copier, redistribuer et modifier le logiciel.

Remarquez que le critère n'est pas une liste de licences approuvées. C'est un test fonctionnel: la licence accorde-t-elle la copie, la redistribution et la modification? Alors vous êtes hors périmètre. GPL, MIT, BSD et Apache passent ce test sans effort, ce qui sort Debian, Fedora, Ubuntu, Arch et la famille BSD du champ de la loi.

La seconde définition est tout aussi importante et elle est passée plus inaperçue. "Application" cesse d'inclure les composants logiciels qui ne sont pas proposés au consommateur comme application exécutable autonome via une boutique d'applications couverte.

Traduction: votre bibliothèque sur npm, votre paquet sur PyPI, ce que vous publiez via apt ou pacman et qui n'arrive pas à l'utilisateur final sous forme d'exécutable dans une boutique, reste lui aussi hors des obligations au niveau applicatif. Cela protège toute la couche de dépendances, celle où vit la majorité d'entre nous.

Qui Reste Dehors et Qui Reste Dedans

Il faut être précis ici, parce que le titre "la Californie exempte Linux" cache la moitié de l'histoire.

Restent dehors: les distributions Linux, les BSD et tout système ou application distribué sous une licence qui permet de copier, redistribuer et modifier. Restent dehors aussi les composants qui n'arrivent pas au consommateur comme exécutable autonome dans une boutique couverte.

Restent dedans, avec l'échéance du 1er janvier 2027 bien réelle: Windows, macOS, iOS et Android. Autrement dit, les quatre systèmes par lesquels passe l'écrasante majorité des utilisateurs finaux restent obligés de collecter l'âge et d'exposer le signal. La loi n'est pas devenue plus petite, elle est devenue plus précise sur ceux qui sont capables de la respecter.

Et il manque une étape. À l'heure où j'écris cet article, l'AB 1856 dépend encore de la signature du gouverneur pour devenir loi. L'adoption unanime dans les deux chambres est un signal fort, mais le processus n'est pas terminé.

Comment Auditer les Licences de Votre Projet en Pratique

Le critère de la loi porte sur les termes que vous accordez à celui qui reçoit le logiciel. Cela devient une question concrète et vérifiable: le champ de licence de votre projet et de vos dépendances déclare-t-il quelque chose qui permet la copie, la redistribution et la modification?

Commencez par votre propre paquet. Le champ license accepte un identifiant SPDX, et c'est lui que lisent les outils automatisés:

{
  "name": "mon-projet",
  "version": "1.4.0",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/utilisateur/mon-projet.git"
  }
}

Un license absent, ou la valeur UNLICENSED, signifie que vous n'avez rien accordé. Sans concession expresse de copie, redistribution et modification, le test de l'AB 1856 n'est pas satisfait, et le défaut du droit d'auteur reste "tous droits réservés".

Passons à l'arbre de dépendances. Le script ci-dessous parcourt node_modules, lit la licence déclarée de chaque paquet et sépare ce qui passe le critère de ce qui demande un regard humain:

// audit-licences.mjs - classe les licences de l'arbre de dépendances
import { readdirSync, readFileSync, statSync } from 'node:fs'
import { join } from 'node:path'

// Licences qui accordent la copie, la redistribution et la modification
const AUTORISE_REDISTRIBUTION = new Set([
  'MIT',
  'ISC',
  'BSD-2-Clause',
  'BSD-3-Clause',
  'Apache-2.0',
  'MPL-2.0',
  'GPL-2.0-only',
  'GPL-3.0-only',
  'LGPL-3.0-only',
  'AGPL-3.0-only',
])

function lirePaquets(racine) {
  const trouves = []

  for (const entree of readdirSync(racine)) {
    const chemin = join(racine, entree)
    if (!statSync(chemin).isDirectory()) continue

    // Les scopes comme @nuxt rangent les paquets un niveau plus bas
    if (entree.startsWith('@')) {
      trouves.push(...lirePaquets(chemin))
      continue
    }

    try {
      const pkg = JSON.parse(readFileSync(join(chemin, 'package.json'), 'utf8'))
      trouves.push({ nom: pkg.name, licence: pkg.license ?? null })
    } catch {
      // Répertoire sans package.json lisible: on ignore
    }
  }

  return trouves
}

const paquets = lirePaquets('node_modules')
const aRevoir = paquets.filter((p) => !p.licence || !AUTORISE_REDISTRIBUTION.has(p.licence))

console.log(`Analysés: ${paquets.length}`)
console.log(`À revoir manuellement: ${aRevoir.length}`)

for (const p of aRevoir) {
  console.log(`  ${p.nom} -> ${p.licence ?? 'aucune licence déclarée'}`)
}

Deux réserves honnêtes sur ce script. Il lit la licence déclarée, pas le vrai fichier LICENSE, et il existe des paquets dont le package.json ment ou utilise des expressions SPDX composées comme (MIT OR Apache-2.0). Et la liste ci-dessus est un point de départ technique, pas un avis juridique: MPL et AGPL permettent la copie, la redistribution et la modification, mais avec des contreparties qui changent beaucoup ce que vous assumez en redistribuant.

Une Barrière de CI Qui Bloque une Licence Hors Critère

Un audit manuel vieillit en une semaine. Le bon endroit pour cette vérification, c'est le pipeline, en faisant échouer le build quand une nouvelle dépendance entre sans licence compatible:

# .github/workflows/licences.yml
name: Audit des licences

on:
  pull_request:
    paths:
      - 'package.json'
      - 'yarn.lock'
      - 'package-lock.json'

jobs:
  auditer:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 22

      # Installe sans lancer les scripts de paquet: on ne veut que les métadonnées
      - run: npm ci --ignore-scripts

      # Le script sort avec un code différent de zéro dès qu'il trouve un cas en attente
      - run: node audit-licences.mjs

Pour que le script bloque vraiment le merge, il suffit de terminer avec un code d'erreur quand la liste à revoir n'est pas vide:

// À la fin de audit-licences.mjs
if (aRevoir.length > 0) {
  console.error('\nDépendances hors du critère de redistribution libre.')
  console.error('À revoir avant de poursuivre le merge.')
  process.exit(1)
}

Le gain ici va bien au-delà de l'AB 1856. Savoir avec précision sous quels termes chaque pièce de votre projet arrive à l'utilisateur est la base de toute conversation sur la conformité, et c'est maintenant aussi la différence entre être dedans ou dehors d'une obligation réglementaire concrète.

De l'Autre Côté: Qui Va Devoir Consommer le Signal d'Âge

Si vous publiez une application dans une boutique couverte, l'exemption ne vous concerne pas et vous devrez demander le signal au système d'exploitation à partir de 2027.

Le format concret de cette API dépend encore de chaque fournisseur. Ce que la loi fixe, ce sont les quatre tranches et l'obligation de traiter le signal comme indicateur principal. La signature ci-dessous est illustrative, pour que vous isoliez cette dépendance dès maintenant et n'éparpilliez pas la réglementation dans tout le code:

// Tranches définies par l'AB 1043
type TrancheAge = 'moins_13' | 'de_13_a_15' | 'de_16_a_17' | 'adulte'

interface SignalAge {
  tranche: TrancheAge
  origine: 'systeme_exploitation' | 'boutique' | 'indisponible'
}

// Couche d'accès unique: le reste de l'app ne parle jamais à la plateforme
export async function obtenirSignalAge(): Promise<SignalAge> {
  try {
    const brut = await plateforme.requestAgeSignal()

    return { tranche: mapperTranche(brut), origine: 'systeme_exploitation' }
  } catch {
    // Plateforme exemptée ou sans support: ne bloquez pas l'app
    return { tranche: 'adulte', origine: 'indisponible' }
  }
}

Le catch n'est pas un détail. Après l'AB 1856 il existe toute une classe de plateformes légitimement exemptées, qui ne répondront jamais à cet appel. Une app qui casse quand le signal n'arrive pas cesse tout simplement de fonctionner sous Linux, et c'est votre bug, pas celui de la distribution.

Cela vaut la peine de centraliser la décision produit en un seul endroit, loin de l'appel à la plateforme:

// Une fonction pure, facile à tester, avec la règle métier isolée
export function autoriseFonctionAdulte(signal: SignalAge): boolean {
  // Sans signal fiable, décidez selon la politique du produit, pas par hasard
  if (signal.origine === 'indisponible') return POLITIQUE_PAR_DEFAUT_ADULTE

  return signal.tranche === 'adulte'
}

Ce Que l'EFF Continue de Critiquer

Il serait confortable de refermer le sujet sur une victoire nette, mais ce n'est pas ce qui s'est passé.

L'Electronic Frontier Foundation s'est opposée à l'AB 1856 pour deux raisons distinctes. La première était le dommage disproportionné que l'AB 1043 imposait aux développeurs open source, et cette raison-là, l'exemption l'a réglée. La seconde tient toujours: la fondation soutient que tout régime de contrôle d'âge nuit à la liberté d'expression, à la vie privée et à l'anonymat de tous les utilisateurs, exemptés ou non.

Il y avait aussi un facteur aggravant. Des versions antérieures du texte étendaient le système de tranches d'âge aux navigateurs et aux sites, ce qui aurait démultiplié la portée de la loi. C'est de là qu'est venu le titre de l'article de l'EFF en mai 2026, "One Step Forward, Two Steps Back": un pas en avant pour l'open source, deux en arrière pour tout le reste. En juillet la législature a reculé et a supprimé cette extension, et c'est la version déjà élaguée qui est passée à l'unanimité en août.

Autrement dit, le texte qui reste est bien meilleur que celui qui était entré. Mais la critique de fond du modèle de vérification de l'âge dans le système d'exploitation reste sans réponse.

Ce Que Cela Signale Pour la Régulation du Logiciel

Le détail le plus intéressant de l'AB 1856 est technique, pas politique: le législateur a choisi de définir l'exemption par les termes de la licence et non par une liste de projets.

Une liste vieillirait en un an et deviendrait une bataille sur qui y entre. Un test fonctionnel, "la licence permet de copier, redistribuer et modifier", s'applique tout seul à des projets qui n'existent pas encore. C'est le même type de raisonnement que la communauté réclamait sur d'autres fronts, comme dans le vote de Debian sur l'usage de l'IA générative dans le code, où la sortie a aussi été de définir un critère plutôt qu'une liste d'outils autorisés.

Deux conséquences pratiques pour les prochains mois. La première, c'est que le champ de licence de votre projet a cessé d'être de la paperasse de package.json pour devenir un fait à effet juridique. Cela vaut la peine de vérifier aujourd'hui si ce qui est déclaré correspond au fichier LICENSE du dépôt.

La seconde, c'est que ce design a de bonnes chances d'être copié. Quand une loi d'un État américain passe à l'unanimité dans les deux chambres, elle devient un modèle de rédaction pour d'autres juridictions. Si le critère "permet de copier, redistribuer et modifier" s'impose comme la frontière standard entre logiciel régulé et non régulé, choisir une licence cesse d'être seulement une décision de communauté pour devenir aussi une décision d'exposition réglementaire.

Allez, on y va! 🦅

📚 Vous Voulez Suivre Ce Qui Arrive?

Cet article a couvert l'AB 1856 et l'exemption de l'open source dans la loi californienne sur la vérification de l'âge, mais l'écosystème change chaque semaine et tout ne devient pas un article ici.

Sur X je partage ce que je teste, les coulisses des projets et les nouveautés qui apparaissent avant de devenir un post.

Suivez-Moi Là-Bas

👉 Suivre @jeffbruchado sur X

💡 Du contenu quotidien sur le développement, la carrière et les outils que j'utilise vraiment

Commentaires (0)

Cet article n'a pas encore de commentaires. Soyez le premier!

Ajouter des commentaires