# Domaines personnalisés

Chaque environnement reçoit une adresse composée par la plateforme ; un domaine personnalisé y ajoute un nom qui vous appartient, comme `boutique.exemple.fr`. Cette page explique comment rattacher un domaine, les enregistrements DNS à créer, la délivrance des certificats et ce qui arrive quand un domaine cesse de pointer vers Bastide.

## Concepts

Un projet a deux sortes de noms d'hôte, que la liste des domaines distingue par leur genre (`kind`).

- **auto** : l'adresse que la plateforme compose pour chaque environnement au premier déploiement qui le met en service. Elle est servie en HTTPS sans rien à faire.
- **custom** : un domaine à vous, rattaché à un environnement du projet. La production par défaut, ou l'environnement que vous choisissez.

Rattacher un domaine suit trois étapes : une **revendication** (vous déclarez le nom), une **preuve** (un enregistrement DNS montre qu'il est à vous), puis le **service** (le nom entre dans la table de routes, et l'edge peut le certifier). Rien n'est servi ni certifié avant la preuve.

Un domaine n'est servi que par un seul projet à la fois, quel que soit le locataire. Les noms sous `bastide.app` et sous les zones de la plateforme sont réservés et ne se rattachent pas.

## Les enregistrements à créer

Le rattachement rend la liste exacte des enregistrements à poser chez votre registraire ou votre hébergeur DNS.

| Rôle | Type | Nom | Valeur |
| --- | --- | --- | --- |
| Preuve de possession | TXT | `_glowsoft-challenge.<domaine>` | Le jeton rendu, de la forme `bastide-…` |
| Trafic d'un sous-domaine | CNAME | `<domaine>` | L'adresse automatique de l'environnement servi |
| Trafic d'un apex | A et AAAA | `<domaine>` | Les adresses publiées de l'edge, rendues par la réponse |
| Facultatif : certificat avant bascule | CNAME | `_acme-challenge.<domaine>` | La cible rendue dans `acmeChallenge`, quand la plateforme la propose |

Deux voies prouvent la possession : le TXT, ou un CNAME qui pointe déjà vers l'adresse automatique de l'environnement. Le TXT ne touche pas au trafic : vous pouvez garder votre hébergement actuel pendant la préparation, puis basculer le CNAME ou les A et AAAA le moment venu.

Le jeton est à usage unique et vaut sept jours. Passé ce délai sans preuve, rattachez le domaine de nouveau : un jeton neuf est tiré.

### Apex et www

Un apex (`exemple.fr`) ne peut pas porter de CNAME : le DNS l'interdit à la racine d'une zone. Il se route par des enregistrements A et AAAA vers les adresses que la réponse indique. Un sous-domaine (`www.exemple.fr`) se route par CNAME.

`exemple.fr` et `www.exemple.fr` sont deux domaines distincts : rattachez-les l'un après l'autre, chacun avec sa preuve. Pour que l'un redirige vers l'autre, déclarez des redirections conditionnées par l'hôte dans le fichier `glowsoft.json` du dépôt ; voir [Routage](routing.md). Le motif `/:path*` ne couvre pas la racine `/` : elle a sa propre règle.

```json
{
  "redirects": [
    {
      "source": "/",
      "has": [{ "type": "host", "value": "www.exemple.fr" }],
      "destination": "https://exemple.fr/",
      "permanent": true
    },
    {
      "source": "/:path*",
      "has": [{ "type": "host", "value": "www.exemple.fr" }],
      "destination": "https://exemple.fr/:path*",
      "permanent": true
    }
  ]
}
```

## La vérification

La plateforme lit le DNS d'elle-même : plusieurs fois dans les premières minutes, puis une fois par heure jusqu'à l'échéance du jeton. Elle interroge les serveurs qui font autorité sur votre zone, pour ne pas dépendre d'un cache resté sur l'ancien enregistrement. Rattacher de nouveau un domaine en attente rend le même jeton et relance une lecture aussitôt.

Tant que la preuve manque, l'état du domaine dit ce qui n'est pas visible : aucun enregistrement, un TXT qui ne porte pas le bon jeton, ou un CNAME qui pointe ailleurs.

## Les certificats TLS

Le certificat d'un domaine personnalisé est délivré automatiquement par l'edge, par le protocole ACME, après la preuve, et renouvelé de la même façon. Vous n'avez aucun certificat à fournir.

L'enregistrement facultatif `_acme-challenge` délègue la validation du certificat à la plateforme : le certificat peut alors être émis avant que le trafic n'arrive, pour une bascule sans coupure. Sans lui, l'émission attend que le domaine pointe vers l'edge.

## La revérification quotidienne

Un domaine prouvé est relu au moins une fois toutes les 24 heures. Il « pointe » encore si l'une de ces conditions tient :

- un CNAME vers l'adresse automatique de l'environnement ;
- une adresse A ou AAAA parmi celles de l'edge ;
- le TXT de preuve, toujours en place avec son jeton.

Si aucune ne tient, la ligne du domaine affiche **Ne pointe plus** et une notification part. Sept jours plus tard, si le domaine n'a pas reparu, il est retiré comme par un retrait manuel, et le journal d'audit le dit. Une lecture qui le revoit efface la perte : une panne passagère chez votre hébergeur DNS ne retire rien.

## Depuis la console

Ouvrez **Domaines** dans le menu du projet. Le tableau liste les adresses du projet, l'environnement que chacune sert et son état : **Vérifié**, **En attente de preuve** ou **Preuve introuvable**.

1. Dans la barre du haut, saisissez le domaine et choisissez l'environnement servi (la production par défaut).
2. Cliquez sur **Rattacher**. Le panneau **Preuve à publier** montre les enregistrements à créer, avec un bouton pour copier chacun.
3. Créez-les chez votre registraire. La plateforme relit le DNS d'elle-même ; l'état passe à **Vérifié** une fois la preuve lue.

Pour retirer un domaine, ouvrez le menu « ⋯ » de sa ligne. Une revendication en attente se retire d'un clic. Un domaine servi se retire en deux temps : la fenêtre montre l'impact (**Trafic coupé**), puis vous confirmez. Le retrait est réservé au rang Administrateur.

## Par un agent, la ligne de commande ou l'API

Les outils sont `domain_add`, `domain_list` et `domain_delete`.

```json
{
  "projectId": "prj_01JQ8ZK4M7NP2RSTVWXYZ34567",
  "domain": "boutique.exemple.fr",
  "idempotencyKey": "rattachement-boutique-2026-09-14"
}
```

La réponse de `domain_add` porte `status` (`pending` ou `verified`), `verification` (le TXT à poser et son échéance), `routing` (la cible CNAME et les adresses A et AAAA) et `acmeChallenge`. `verified` signifie que ce projet sert déjà le domaine : il n'y a rien à poser.

`domain_list` rend chaque nom avec `kind`, `status`, l'environnement servi et `lostSince`, la date depuis laquelle la revérification ne le voit plus pointer.

`domain_delete` sur un domaine servi demande une confirmation en deux temps : le premier appel est refusé avec `confirmation_requise` et porte un nonce et l'impact ; votre client MCP vous demande alors de confirmer, et le second appel reprend le nonce dans les cinq minutes.

```sh
bastide domain add --project-id prj_01JQ8ZK4M7NP2RSTVWXYZ34567 --domain boutique.exemple.fr
bastide domain list --project-id prj_01JQ8ZK4M7NP2RSTVWXYZ34567
bastide domain delete --project-id prj_01JQ8ZK4M7NP2RSTVWXYZ34567 --domain boutique.exemple.fr
```

Par l'API : `POST /v1/projects/{projectId}/domains`, `GET /v1/projects/{projectId}/domains` et `DELETE /v1/projects/{projectId}/domains/{domain}` sur `https://api.bastide.app`.

| Geste | Rang minimal | Compte de service |
| --- | --- | --- |
| Lister | Lecteur | oui |
| Rattacher | Mainteneur | non |
| Retirer | Administrateur | non, et validation humaine exigée |

## Limites par palier

| | Découverte | Standard | Pro | Souverain |
| --- | --- | --- | --- | --- |
| Domaines personnalisés par projet | 1 | 10 | 100 | 500 |

Un nom pleinement qualifié compte 253 caractères au plus. Un projet créé par un agent et pas encore revendiqué ne reçoit aucun domaine personnalisé.

## Erreurs fréquentes

| Code ou état | Cause | Remède |
| --- | --- | --- |
| `domaine_reserve` | Le nom est sous une zone de la plateforme. | Rattacher un domaine qui vous appartient. |
| `domaine_deja_servi` | Un autre projet sert déjà ce domaine. | Le retirer de ce projet-là avant de le rattacher ici. |
| `projet_non_revendique` | Le projet a été créé par un agent et n'est pas revendiqué. | Revendiquer le projet depuis la console, puis rattacher. |
| En attente : aucun enregistrement visible | Le TXT n'est pas encore publié, ou la propagation n'est pas faite. | Vérifier le nom exact `_glowsoft-challenge.<domaine>` ; attendre la lecture suivante. |
| En attente : TXT sans le bon jeton | Un ancien jeton est resté, ou la valeur a été tronquée. | Recopier le jeton rendu par le dernier rattachement, sans guillemets ni espace. |
| Jeton expiré | Sept jours sans preuve. | Rattacher de nouveau : un jeton neuf est tiré. |
| **Ne pointe plus** | Le DNS a été modifié, ou le domaine a quitté la plateforme. | Remettre le CNAME ou les A et AAAA dans les sept jours, ou retirer le domaine. |
| `confirmation_requise` | Retrait d'un domaine servi. | Reprendre l'appel avec `confirmationNonce` dans les cinq minutes. |

Un domaine prouvé mais inscrit sur une liste de réputation n'entre pas dans la table de routes ; son état dit pourquoi et à qui écrire.

## Voir aussi

- [Environnements et variables](environments.md)
- [Routage](routing.md)
- [Cache et images](cache.md)
- [Pages d'erreur et limites de débit](firewall.md)
- [domain.add](../reference/operations/domain.add.md), [domain.delete](../reference/operations/domain.delete.md)
