# GET /brand/{brand_id}/did.json

Récupérer le document d'identité d'une marque : la liste de ses clefs publiques de signature, au format did:web. Point d'entrée public.

Source : https://docs.sealtrust.io/reference/get-brand-did-json/

---

Vous récupérez les clefs publiques avec lesquelles une marque signe ses
passeports numériques de produit. En quittant cette page, vous saurez demander
ce document, y retrouver la clef qui a signé un justificatif précis, et
comprendre ce que veut dire l'absence d'une clef.

Adresse complète :

```http
GET https://api.sealtrust.io/v1/brand/{brand_id}/did.json
```

Le même point d'entrée répond aussi sans le préfixe `/v1`, à
`https://api.sealtrust.io/brand/{brand_id}/did.json`. Les deux adresses
appellent le même code. Utilisez la forme `/v1` pour une nouvelle intégration.

Ce document est ce qu'un vérificateur va chercher tout seul. Le justificatif
signé d'un passeport porte un identifiant d'émetteur de la forme
`did:web:api.sealtrust.io:brand:4242`. La règle publique du format `did:web`
traduit cet identifiant en l'adresse `https://api.sealtrust.io/brand/4242/did.json`,
c'est-à-dire ce point d'entrée. N'importe quelle bibliothèque `did:web`
standard fait cette traduction sans rien connaître de SealTrust.

> [!INFO] Vous n'avez pas besoin de nous pour vérifier
> Ce point d'entrée sert exactement à cela : vous donner les clefs publiques
> pour que vous vérifiiez une signature vous-même, avec l'outil de votre choix.
> Le point d'entrée `GET /v1/passport/{identifier}/vc/verify` fait la même
> vérification de notre côté. Les deux chemins existent et sont indépendants.

## Autorisation

Aucune, point d'entrée public. Vous n'envoyez ni clef d'API, ni session, ni
en-tête d'origine. La réponse est la même pour tout le monde.

Le document ne contient que des clefs publiques. Aucune clef privée ne sort de
notre système, et aucune n'est reconstructible depuis ce document.

> [!ATTENTION] Le partage entre origines n'est pas ouvert aux tiers
> Les origines autorisées à appeler l'API depuis un navigateur sont celles de
> SealTrust. Une page web tierce qui appelle ce point d'entrée depuis le
> navigateur verra sa requête refusée par le navigateur lui-même. Résolvez ce
> document depuis votre serveur.

## Plafond d'appels

Ce point d'entrée n'a pas de plafond qui lui soit propre. Il partage avec les
autres routes sans plafond propre un compteur général, compté par adresse réseau
appelante sur une tranche de 60 secondes.

Prévoyez le code 429 dans votre client et respectez l'en-tête `Retry-After`
qu'il porte. La valeur du compteur général peut changer sans préavis, donc
n'inscrivez aucun nombre en dur dans votre code.

La réponse porte trois en-têtes qui décrivent ce compteur.

| En-tête | Contenu |
| --- | --- |
| `X-RateLimit-Limit` | le plafond que le compteur général annonce pour la fenêtre |
| `X-RateLimit-Remaining` | ce qu'il vous reste dans la fenêtre en cours |
| `X-RateLimit-Reset` | l'horodatage de fin de la fenêtre, en secondes |

Ce document change seulement quand la marque renouvelle ses clefs de signature,
ce qui est rare. Gardez-en une copie de votre côté. Rafraîchissez-la quand un
justificatif porte un `kid` que votre copie ne contient pas.

## Paramètres de chemin et de requête

| Nom | Type | Obligatoire | Description |
| --- | --- | --- | --- |
| `brand_id` | `integer` | oui | L'identifiant numérique de la marque. C'est le nombre qui suit `brand:` dans l'identifiant d'émetteur du justificatif signé. |

Ce point d'entrée n'a aucun paramètre de requête.

### En-têtes

Aucun en-tête n'est requis.

## Corps de la requête

Aucun. Cette requête n'a pas de corps.

## Requête d'exemple

Document d'identité de la marque dont l'identifiant est `4242`.

> [!INFO] Le SDK TypeScript ne couvre pas ce point d'entrée
> Aucune méthode du paquet `@sealtrust-io/sdk` n'appelle cette adresse.
> L'exemple TypeScript ci-dessous utilise `fetch`, sans dépendance.

:::onglets
```bash title="curl"
curl -i https://api.sealtrust.io/v1/brand/4242/did.json
```
```typescript
const reponse = await fetch(
  "https://api.sealtrust.io/v1/brand/4242/did.json",
);

if (reponse.status === 404) {
  console.log("Aucune marque ne porte cet identifiant.");
} else if (reponse.ok) {
  const document = await reponse.json();

  console.log("Identifiant de la marque :", document.id);
  console.log("Clefs publiées :", document.verificationMethod.length);

  for (const methode of document.verificationMethod) {
    console.log(methode.id, methode.type, methode.publicKeyJwk.crv);
  }

  // Retrouver la clef qui a signé un justificatif précis.
  const kid = "did:web:api.sealtrust.io:brand:4242#key-2";
  const clef = document.verificationMethod.find((m) => m.id === kid);

  if (clef) {
    console.log("Clef de signature trouvée :", clef.publicKeyJwk);
  } else {
    console.log("Cette clef n'est plus publiée. Signature à rejeter.");
  }
} else {
  console.log(reponse.status, await reponse.json());
}
```
```python
import requests

response = requests.get(
    "https://api.sealtrust.io/v1/brand/4242/did.json",
    timeout=30,
)

if response.status_code == 404:
    print("Aucune marque ne porte cet identifiant.")
elif response.ok:
    document = response.json()

    print("Identifiant de la marque :", document["id"])
    print("Clefs publiées :", len(document["verificationMethod"]))

    for methode in document["verificationMethod"]:
        print(methode["id"], methode["type"], methode["publicKeyJwk"]["crv"])

    # Retrouver la clef qui a signé un justificatif précis.
    kid = "did:web:api.sealtrust.io:brand:4242#key-2"
    clef = next(
        (m for m in document["verificationMethod"] if m["id"] == kid),
        None,
    )

    if clef:
        print("Clef de signature trouvée :", clef["publicKeyJwk"])
    else:
        print("Cette clef n'est plus publiée. Signature à rejeter.")
else:
    print(response.status_code, response.json())
```
:::

## Réponse d'exemple

Code HTTP `200`. Le corps est du JSON, servi avec l'en-tête
`Content-Type: application/json`.

Ici, la marque `Exemple SAS` a renouvelé sa clef une fois. Les deux versions
restent publiées, donc les justificatifs signés sous l'ancienne restent
vérifiables.

```json
{
  "@context": [
    "https://www.w3.org/ns/did/v1",
    "https://w3id.org/security/suites/jws-2020/v1"
  ],
  "id": "did:web:api.sealtrust.io:brand:4242",
  "verificationMethod": [
    {
      "id": "did:web:api.sealtrust.io:brand:4242#key-1",
      "type": "JsonWebKey2020",
      "controller": "did:web:api.sealtrust.io:brand:4242",
      "publicKeyJwk": {
        "kty": "EC",
        "crv": "P-256",
        "x": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
        "y": "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
      }
    },
    {
      "id": "did:web:api.sealtrust.io:brand:4242#key-2",
      "type": "JsonWebKey2020",
      "controller": "did:web:api.sealtrust.io:brand:4242",
      "publicKeyJwk": {
        "kty": "EC",
        "crv": "P-256",
        "x": "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC",
        "y": "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
      }
    }
  ],
  "assertionMethod": [
    "did:web:api.sealtrust.io:brand:4242#key-1",
    "did:web:api.sealtrust.io:brand:4242#key-2"
  ],
  "authentication": [
    "did:web:api.sealtrust.io:brand:4242#key-1",
    "did:web:api.sealtrust.io:brand:4242#key-2"
  ]
}
```

Les cinq champs de premier niveau sont toujours présents.

| Champ | Type | Description |
| --- | --- | --- |
| `@context` | `string[]` | Les deux vocabulaires qui donnent leur sens aux champs du document. Toujours ces deux valeurs, dans cet ordre. |
| `id` | `string` | L'identifiant de la marque, au format `did:web`. C'est la valeur que porte le champ émetteur d'un justificatif signé. |
| `verificationMethod` | `object[]` | Une entrée par clef publique publiée, de la plus ancienne version à la plus récente. |
| `assertionMethod` | `string[]` | Les identifiants des clefs autorisées à signer un justificatif. Reprend les mêmes entrées que `verificationMethod`, dans le même ordre. |
| `authentication` | `string[]` | Les identifiants des clefs autorisées à prouver le contrôle de cet identifiant. Reprend les mêmes entrées. |

### Une entrée de `verificationMethod`

| Champ | Type | Description |
| --- | --- | --- |
| `id` | `string` | L'identifiant de la clef, de la forme `<identifiant de la marque>#key-<numéro de version>`. |
| `type` | `string` | Toujours `JsonWebKey2020`. |
| `controller` | `string` | L'identifiant de la marque qui contrôle cette clef. Vaut toujours le champ `id` du document. |
| `publicKeyJwk` | `object` | La clef publique elle-même, au format JWK. |

`publicKeyJwk` porte quatre champs : `kty` vaut `EC`, `crv` vaut `P-256`, `x` et
`y` sont les deux coordonnées du point public, encodées en base64url. Ces
valeurs se passent telles quelles à une bibliothèque de vérification JWS.

### Retrouver la clef qui a signé un justificatif

L'en-tête d'un justificatif de passeport porte un champ `kid`. Ce `kid` vaut
exactement l'un des `id` de `verificationMethod`, par exemple
`did:web:api.sealtrust.io:brand:4242#key-2`. Vous cherchez cette valeur dans la
liste, vous prenez le `publicKeyJwk` correspondant, et vous vérifiez la
signature avec l'algorithme `ES256`.

Si le `kid` ne figure pas dans la liste, la signature doit être rejetée.

### Ce que dit l'absence d'une clef

Une clef révoquée sort du document. Tous les justificatifs signés sous cette
version cessent d'être vérifiables, et c'est le résultat voulu.

Une clef remplacée par une version plus récente reste publiée. Elle n'est plus
utilisée pour signer de nouveaux justificatifs, et les anciens continuent de se
vérifier.

`verificationMethod` peut être une liste vide, avec `assertionMethod` et
`authentication` vides eux aussi. Cela veut dire que la marque n'a encore
publié aucune clef de signature. Aucun justificatif de cette marque n'est alors
vérifiable.

### Quand le champ `id` ne correspond pas à l'adresse appelée

Une marque peut porter son identité sur son propre nom de domaine. Le champ
`id` du document vaut alors `did:web:<son domaine>`, et le document de
référence se trouve à `https://<son domaine>/.well-known/did.json`.

Dans ce cas, prenez le champ `id` du justificatif que vous vérifiez comme point
de départ, appliquez la règle de traduction `did:web`, et allez chercher le
document à l'adresse obtenue. Ne construisez jamais l'adresse vous-même à
partir de l'identifiant de marque.

## Erreurs

Le corps d'une réponse d'erreur porte un champ `detail`. Toute réponse de ce
point d'entrée, réussie ou en erreur, porte un en-tête `X-Request-Id`.

| Code | Condition | Que faire |
| --- | --- | --- |
| 404 | Aucune marque ne porte cet identifiant. `detail` vaut `Brand not found`. | Vérifiez le nombre qui suit `brand:` dans l'identifiant d'émetteur. Rejetez la signature : un émetteur dont le document d'identité est introuvable ne prouve rien. |
| 422 | La valeur envoyée dans le chemin n'est pas un nombre entier. `detail` porte la liste des erreurs de validation, avec le nom du paramètre en cause. | Corrigez l'identifiant. Un identifiant de marque s'écrit uniquement en chiffres. |
| 422 | Le document d'identité de la marque trouvée ne peut pas être construit. | Signalez-le au support en indiquant l'identifiant appelé. Vous ne pouvez rien corriger de votre côté. |
| 500 | Une erreur inattendue s'est produite pendant le traitement de votre appel. `detail` vaut `Internal Server Error`. | Réessayez. Si l'erreur persiste, contactez le support en indiquant la valeur de `X-Request-Id`. |

Ce point d'entrée ne renvoie ni 401, ni 403 : il est public et ne lit aucune
autorisation.

## Voir aussi

- [`GET /.well-known/did.json`](/reference/get-well-known-did-json/),
  servir le document d'identité d'une marque sur son propre domaine.
- [`GET /passport/{identifier}/vc`](/reference/get-passport-vc/),
  récupérer le justificatif signé du passeport, au format SD-JWT-VC.
- [`GET /passport/{identifier}/vc/verify`](/reference/get-passport-vc-verify/),
  contrôler la signature du justificatif et lire les données révélées.
- [Confiance et preuves](/confiance-et-preuves/),
  ce que chaque preuve établit et comment un tiers refait la vérification.
