
# Contrôle d'accès aux formulaires

Un formulaire est une route publique par défaut. C'est le bon comportement pour un formulaire de contact, et le mauvais pour une note de frais interne, un bon de commande réservé aux partenaires ou une enquête réservée aux membres — dans chacun de ces cas, l'URL doit répondre différemment selon qui la demande.

`access` énonce l'exigence, avec le même modèle de permissions que les tables, les pages, les buckets, les automatisations et les agents :

```yaml
forms:
  - id: 2
    name: member-survey
    title: Member Survey
    submitTo: { table: survey_responses }
    access:
      require: authenticated
    fields:
      - { kind: standalone, name: rating, inputType: rating, required: true }
```

## Propriétés d'accès

| Propriété    | Description                                                                                                   | Défaut                           |
| ------------ | ------------------------------------------------------------------------------------------------------------- | -------------------------------- |
| `require`    | `all`, `authenticated`, ou un tableau de noms de rôles — au moins un élément si c'est un tableau.             | `all` lorsque `access` est omis. |
| `redirectTo` | Chemin vers lequel envoyer un contributeur refusé, à la place de la réponse de refus. Doit commencer par `/`. | Aucune redirection.              |

Un tableau de rôles peut aussi désigner un groupe, avec le préfixe `group:` — `['admin', 'group:partners']` admet quiconque a le rôle `admin` ou appartient au groupe `partners`.

`redirectTo` est accepté et validé aujourd'hui ; la route canonique `/forms/{name}` répond pour l'instant à un refus par la réponse décrite ci-dessous plutôt que par une redirection.

## Ce que reçoit un contributeur refusé

Le contrôle s'applique aussi bien à l'ouverture du formulaire qu'à l'envoi. Le refus n'est délibérément pas uniforme.

| `require`       | Visiteur anonyme          | Connecté, mauvais rôle | Connecté, bon rôle |
| --------------- | ------------------------- | ---------------------- | ------------------ |
| omis / `all`    | Autorisé                  | Autorisé               | Autorisé           |
| `authenticated` | `401` — connexion requise | Autorisé               | Autorisé           |
| `['partner']`   | `404`                     | `404`                  | Autorisé           |

Le `401` nomme le formulaire et le niveau exigé, parce que « connectez-vous pour utiliser ceci » est une information utile à donner au visiteur.

:::callout
**Une restriction par rôle répond 404, pas 403 — et c'est voulu.** Un `403` confirmerait l'existence du formulaire à quiconque en a deviné le nom, permettant à un tiers d'énumérer vos formulaires internes en observant quelles URL répondent différemment. Un formulaire restreint par rôle n'existe tout simplement pas pour qui n'a pas ce rôle. Devant un `404` inattendu sur un formulaire que vous savez configuré, vérifiez le rôle de l'utilisateur connecté avant de chercher un problème de routage.
:::

## Accès et références `$user`

Exiger l'authentification est ce qui rend la session disponible au moteur de rendu, et donc ce qui rend `$user.<prop>` résolvable. Sur un formulaire public il n'y a aucune session à lire : un `$user.email` placé dans la table `prefill` est silencieusement abandonné et le champ s'affiche vide.

La forme en ligne de la même référence est plus stricte. Un `defaultValue: $user.email` par champ sur un formulaire public est rejeté au décodage de la configuration, avec un message nommant le formulaire et le champ — une valeur qui ne pourra jamais que se résoudre à vide est une erreur à intercepter avant le démarrage plutôt qu'une saisie vide à livrer.

## Formulaires intégrés

Un formulaire affiché dans une page via `formRef` conserve son propre contrôle, et la page hérite de la réponse la plus stricte : si un seul formulaire intégré refuse la session, la page entière renvoie `404`. L'alternative — afficher la page avec un trou à la place du formulaire — divulguerait l'existence du formulaire par la forme de la page, précisément ce que la restriction par rôle vise à empêcher.

## Qui a soumis

Lorsqu'une session est présente, le registre de soumissions enregistre le `submitter_user_id` à côté des réponses, et la colonne « créé par » d'une table liée reçoit le même identifiant. Les soumissions publiques laissent les deux à null. Le contrôle d'accès est donc aussi ce qui rend une soumission attribuable.

## Pages associées

- [Rôles et RBAC](/fr/docs/auth-roles-rbac) — les noms de rôles auxquels `require` se compare.
- [Groupes d'authentification](/fr/docs/auth-groups) — les groupes désignés par une entrée `group:`.
- [Préremplissage](/fr/docs/form-prefill) — les références `$user`, qui dépendent de ce contrôle.
- [Disponibilité](/fr/docs/form-availability) — l'autre raison pour laquelle un formulaire peut refuser une soumission.
