Aller au contenu principal

Référence API

Référence complète de l'API REST Wirety.

Présentation générale

URL de base

Tous les endpoints sont relatifs à :

/api/v1

Authentification

La plupart des endpoints nécessitent une authentification. Trois mécanismes sont acceptés et peuvent être combinés :

MécanismeEn-tête / CookieValeur
Hash de sessionAuthorization: Session <hash>Obtenu lors de la connexion ou de l'échange de token OIDC
Token APIAuthorization: Bearer wirety_<hex>Token d'accès personnel à longue durée de vie
Cookie de sessionwirety_session (cookie HttpOnly)Défini automatiquement par le serveur lors de la connexion

Les cookies de session sont définis automatiquement lors de l'utilisation des endpoints de connexion ou d'échange de token.

Rôles

RôleDescription
administratorAccès complet à toutes les ressources sur tous les réseaux
userAccès limité aux réseaux autorisés et aux peers propres

Les endpoints marqués [admin] nécessitent le rôle administrator et retournent 403 Forbidden sinon.

Format des erreurs

Toutes les réponses d'erreur utilisent :

{ "error": "message d'erreur lisible" }

Pagination

Les endpoints paginés acceptent les paramètres page (défaut 1) et page_size (défaut 20) et retournent :

{
"data": [...],
"total": 100,
"page": 1,
"page_size": 20
}

Santé

Vérification de l'état

Vérifie que le serveur API est en cours d'exécution. Aucune authentification requise.

GET /health

Réponse 200

{ "status": "ok" }

Authentification

Obtenir la configuration d'authentification

Retourne la configuration d'authentification publique. Aucune authentification requise.

GET /auth/config

Réponse 200

{
"enabled": true,
"issuer_url": "https://accounts.example.com",
"client_id": "wirety-app",
"simple_auth": false
}
ChampDescription
enabledIndique si l'authentification OIDC est activée
issuer_urlURL de l'émetteur OIDC (vide si OIDC est désactivé)
client_idID client OIDC pour le frontend
simple_authtrue quand AUTH_ENABLED=false — connexion admin/mot de passe utilisée à la place

Échanger un token OIDC

Échange un code d'autorisation OIDC contre une session côté serveur. Disponible uniquement quand OIDC est activé (enabled: true dans la configuration d'authentification).

POST /auth/token

Corps de la requête

{
"code": "authorization_code_from_oidc",
"redirect_uri": "https://app.example.com/callback"
}

Réponse 200

{
"session_hash": "abc123...",
"expires_in": 3600
}

Le serveur définit également un cookie HttpOnly wirety_session. Les requêtes suivantes peuvent utiliser soit la valeur session_hash dans l'en-tête Authorization: Session, soit le cookie.


Connexion (Auth Simple)

Authentification avec nom d'utilisateur/mot de passe. Disponible uniquement quand OIDC est désactivé (simple_auth: true dans la configuration d'authentification).

POST /auth/login

Corps de la requête

{
"username": "admin",
"password": "votre-mot-de-passe-admin"
}

Réponse 200

{
"session_hash": "abc123...",
"expires_in": 2592000
}

Le serveur définit également un cookie HttpOnly wirety_session.


Déconnexion

Invalide la session courante.

POST /auth/logout

Corps de la requête (optionnel — la session est de préférence résolue depuis le cookie ou l'en-tête Authorization)

{
"session_hash": "abc123..."
}

Réponse 200

{ "message": "Logged out successfully" }

Utilisateurs

Obtenir l'utilisateur courant

Retourne le profil de l'utilisateur authentifié.

GET /users/me

Réponse 200

{
"id": "user-sub-from-oidc",
"email": "alice@example.com",
"name": "Alice",
"role": "user",
"authorized_networks": ["net-id-1", "net-id-2"],
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-10T12:00:00Z",
"last_login_at": "2024-04-10T08:00:00Z"
}

Lister les utilisateurs [admin]

Retourne tous les utilisateurs enregistrés.

GET /users

Réponse 200 — tableau d'objets User (même structure que ci-dessus).


Obtenir un utilisateur [admin]

GET /users/:userId

Paramètres de chemin

ParamètreDescription
userIdID de l'utilisateur

Réponse 200 — objet User.


Mettre à jour un utilisateur [admin]

Met à jour le nom, le rôle ou les réseaux autorisés d'un utilisateur.

PUT /users/:userId

Corps de la requête

{
"name": "Alice Smith",
"role": "administrator",
"authorized_networks": ["net-id-1"]
}

Tous les champs sont optionnels. Réponse 200 — objet User mis à jour.


Supprimer un utilisateur [admin]

DELETE /users/:userId

Réponse 204 No Content


Obtenir les permissions par défaut [admin]

Retourne le rôle et la liste de réseaux par défaut appliqués aux nouveaux utilisateurs.

GET /users/defaults

Réponse 200

{
"default_role": "user",
"default_authorized_networks": ["net-id-1"]
}

Mettre à jour les permissions par défaut [admin]

PUT /users/defaults

Corps de la requête

{
"default_role": "user",
"default_authorized_networks": ["net-id-1"]
}

Réponse 200 — objet DefaultNetworkPermissions mis à jour.


Tokens API

Les tokens appartiennent à l'utilisateur authentifié et utilisent le préfixe wirety_.

Lister les tokens API

GET /users/me/tokens

Réponse 200 — tableau d'objets token (le token brut n'est pas inclus dans la liste).

[
{
"id": "token-uuid",
"name": "ci-bot",
"created_at": "2024-01-01T00:00:00Z",
"expires_at": null,
"last_used_at": "2024-04-10T08:00:00Z"
}
]

Créer un token API

POST /users/me/tokens

Corps de la requête

{
"name": "ci-bot",
"expires_at": "2025-01-01T00:00:00Z"
}

expires_at est optionnel — omettez-le pour un token sans expiration.

Réponse 201

{
"id": "token-uuid",
"name": "ci-bot",
"token": "wirety_deadbeef...",
"created_at": "2024-04-13T00:00:00Z",
"expires_at": "2025-01-01T00:00:00Z",
"last_used_at": null
}

Le champ token n'est affiché qu'une seule fois. Conservez-le en lieu sûr — il ne peut pas être récupéré à nouveau.


Supprimer un token API

DELETE /users/me/tokens/:tokenId

Réponse 204 No Content


Réseaux

Lister les réseaux

Retourne les réseaux accessibles à l'utilisateur authentifié, avec pagination et filtrage optionnel.

GET /networks

Paramètres de requête

ParamètreDéfautDescription
page1Numéro de page
page_size20Éléments par page (max 200)
filterFiltre par sous-chaîne (insensible à la casse) sur le nom, le CIDR ou l'ID

Réponse 200

{
"data": [
{
"id": "net-uuid",
"name": "bureau",
"cidr": "10.10.0.0/16",
"peer_count": 12,
"dns": ["1.1.1.1"],
"domain_suffix": "internal",
"default_group_ids": [],
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-04-01T00:00:00Z"
}
],
"total": 1,
"page": 1,
"page_size": 20
}
ChampDescription
peer_countNombre de peers (calculé)
dnsServeurs DNS supplémentaires poussés aux peers
domain_suffixSuffixe de domaine DNS interne (défaut : internal)
default_group_idsGroupes automatiquement assignés aux peers non-admin

Créer un réseau [admin]

POST /networks

Corps de la requête

{
"name": "bureau",
"cidr": "10.10.0.0/16",
"dns": ["1.1.1.1", "8.8.8.8"],
"domain_suffix": "internal"
}

dns et domain_suffix sont optionnels. Réponse 201 — objet Network.


Obtenir un réseau

GET /networks/:networkId

Réponse 200 — objet Network.


Mettre à jour un réseau [admin]

PUT /networks/:networkId

Corps de la requête (tous les champs optionnels)

{
"name": "bureau-v2",
"cidr": "10.20.0.0/16",
"dns": ["1.1.1.1"],
"domain_suffix": "corp",
"default_group_ids": ["group-uuid"]
}

Réponse 200 — objet Network mis à jour.


Supprimer un réseau [admin]

DELETE /networks/:networkId

Réponse 204 No Content


Peers

Lister les peers

GET /networks/:networkId/peers

Les utilisateurs non-admin ne voient que leurs propres peers. Supporte la pagination et le filtrage.

Paramètres de requête

ParamètreDéfautDescription
page1Numéro de page
page_size20Éléments par page (max 500)
filterFiltre par sous-chaîne sur le nom, l'adresse IP ou l'ID

Réponse 200

{
"data": [
{
"id": "peer-uuid",
"name": "laptop-alice",
"public_key": "base64pubkey=",
"address": "10.10.0.2",
"endpoint": "203.0.113.5:51820",
"listen_port": 51820,
"additional_allowed_ips": ["192.168.1.0/24"],
"token": "enroll-token-value",
"is_jump": false,
"use_agent": true,
"owner_id": "user-sub-123",
"group_ids": ["group-uuid"],
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-04-01T00:00:00Z"
}
],
"total": 1,
"page": 1,
"page_size": 20
}
ChampDescription
endpointIP:port externe (principalement pour les peers jump)
listen_portPort d'écoute WireGuard (principalement pour les peers jump)
additional_allowed_ipsCIDRs supplémentaires que ce peer peut router
tokenToken d'inscription de l'agent (secret, à traiter avec précaution)
is_jumpIndique si ce peer joue le rôle de hub/serveur jump
use_agentIndique si l'agent dynamique gère ce peer
owner_idID utilisateur du propriétaire du peer (vide pour les peers créés par admin)
group_idsGroupes auxquels ce peer appartient

Créer un peer

POST /networks/:networkId/peers

Les utilisateurs non-admin deviennent automatiquement propriétaires du peer.

Corps de la requête

{
"name": "laptop-alice",
"endpoint": "203.0.113.5:51820",
"listen_port": 51820,
"is_jump": false,
"use_agent": true,
"additional_allowed_ips": ["192.168.1.0/24"]
}

Tous les champs sauf name sont optionnels. Réponse 201 — objet Peer.


Obtenir un peer

GET /networks/:networkId/peers/:peerId

Les utilisateurs non-admin ne peuvent récupérer que leurs propres peers.

Réponse 200 — objet Peer.


Mettre à jour un peer

PUT /networks/:networkId/peers/:peerId

Les utilisateurs non-admin ne peuvent mettre à jour que leurs propres peers. Seuls les admins peuvent modifier owner_id.

Corps de la requête (tous les champs optionnels)

{
"name": "laptop-alice-v2",
"endpoint": "203.0.113.10:51820",
"listen_port": 51820,
"additional_allowed_ips": ["192.168.2.0/24"],
"owner_id": "another-user-id"
}

Réponse 200 — objet Peer mis à jour.


Supprimer un peer

DELETE /networks/:networkId/peers/:peerId

Les utilisateurs non-admin ne peuvent supprimer que leurs propres peers.

Réponse 204 No Content


Obtenir la configuration d'un peer

Retourne le fichier de configuration WireGuard pour un peer.

GET /networks/:networkId/peers/:peerId/config

Les utilisateurs non-admin ne peuvent récupérer que la config de leurs propres peers.

Réponse 200

{ "config": "[Interface]\nPrivateKey = ...\n..." }

Obtenir le statut de session d'un peer

Retourne le statut de la session de sécurité pour un peer (sessions d'agent actives, changements d'endpoint, activité suspecte).

GET /networks/:networkId/peers/:peerId/session

Réponse 200

{
"peer_id": "peer-uuid",
"has_active_agent": true,
"current_session": {
"peer_id": "peer-uuid",
"hostname": "laptop-alice",
"system_uptime": 86400,
"wireguard_uptime": 3600,
"reported_endpoint": "203.0.113.5:51820",
"last_seen": "2024-04-13T10:00:00Z",
"first_seen": "2024-04-12T09:00:00Z",
"session_id": "sess-uuid"
},
"conflicting_sessions": [],
"recent_endpoint_changes": [],
"suspicious_activity": false,
"last_checked": "2024-04-13T10:05:00Z"
}

Obtenir l'accessibilité d'un peer

Calcule quels peers, règles de politique et routes externes sont accessibles depuis un peer donné, en fonction de la configuration ACL et groupe/politique.

GET /networks/:networkId/peers/:peerId/reachability

Réponse 200

{
"peer_id": "peer-uuid",
"peer_name": "laptop-alice",
"peer_address": "10.10.0.2",
"is_jump": false,
"peer_access": [
{
"peer_id": "peer-uuid-2",
"peer_name": "server-bob",
"address": "10.10.0.3",
"is_jump": false,
"allowed": true,
"reason": "default_allow"
}
],
"rules": [
{
"direction": "output",
"action": "allow",
"target_type": "cidr",
"target": "192.168.1.0/24",
"addresses": ["192.168.1.0/24"],
"policy_name": "allow-bureau",
"group_name": "ingenierie",
"description": "Autoriser le sous-réseau bureau"
}
],
"routes": [
{
"route_id": "route-uuid",
"route_name": "bureau-lan",
"destination_cidr": "192.168.1.0/24",
"jump_peer_id": "jump-uuid",
"jump_peer_name": "jump-server-1",
"group_name": "ingenierie"
}
]
}

Valeurs reason pour peer_access :

ValeurSignification
acl_disabledACL désactivé — tous les peers peuvent communiquer
allow_ruleCorrespondance avec une règle d'autorisation explicite
deny_ruleCorrespondance avec une règle de refus explicite
blockedPeer dans la liste de blocage
default_allowAucune règle correspondante — l'accès par défaut est autorisé

Groupes

Les groupes nécessitent DB_ENABLED=true. Tous les endpoints de groupe sont [admin] uniquement.

Lister les groupes [admin]

GET /networks/:networkId/groups

Réponse 200 — tableau d'objets Group.

[
{
"id": "group-uuid",
"network_id": "net-uuid",
"name": "ingenierie",
"description": "Équipe ingénierie",
"priority": 100,
"peer_ids": ["peer-uuid"],
"policy_ids": ["policy-uuid"],
"route_ids": ["route-uuid"],
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-04-01T00:00:00Z"
}
]
ChampDescription
priorityOrdre d'application des politiques — valeur plus faible = priorité plus élevée (plage 1–999)

Créer un groupe [admin]

POST /networks/:networkId/groups

Corps de la requête

{
"name": "ingenierie",
"description": "Équipe ingénierie",
"priority": 100
}

description et priority sont optionnels (priorité par défaut : 100). Réponse 201 — objet Group.


Obtenir un groupe [admin]

GET /networks/:networkId/groups/:groupId

Réponse 200 — objet Group.


Mettre à jour un groupe [admin]

PUT /networks/:networkId/groups/:groupId

Corps de la requête (tous les champs optionnels)

{
"name": "ingenierie-v2",
"description": "Description mise à jour",
"priority": 50
}

Réponse 200 — objet Group mis à jour.


Supprimer un groupe [admin]

DELETE /networks/:networkId/groups/:groupId

Réponse 204 No Content


Ajouter un peer à un groupe [admin]

POST /networks/:networkId/groups/:groupId/peers/:peerId

Réponse 200

Retourne 400 Bad Request avec des détails si l'ajout du peer crée une dépendance de routage circulaire.


Retirer un peer d'un groupe [admin]

DELETE /networks/:networkId/groups/:groupId/peers/:peerId

Réponse 204 No Content


Obtenir les routes d'un groupe [admin]

GET /networks/:networkId/groups/:groupId/routes

Réponse 200 — tableau d'objets Route attachés au groupe.


Politiques

Les politiques nécessitent DB_ENABLED=true. Tous les endpoints de politique sont [admin] uniquement.

Lister les politiques [admin]

GET /networks/:networkId/policies

Réponse 200 — tableau d'objets Policy.

[
{
"id": "policy-uuid",
"network_id": "net-uuid",
"name": "allow-bureau",
"description": "Autoriser l'accès au sous-réseau bureau",
"rules": [
{
"id": "rule-uuid",
"direction": "output",
"action": "allow",
"target": "192.168.1.0/24",
"target_type": "cidr",
"description": "LAN Bureau"
}
],
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-04-01T00:00:00Z"
}
]

Champs PolicyRule

ChampValeurs
direction"input" ou "output"
action"allow" ou "deny"
target_type"cidr", "peer", ou "group"
targetChaîne CIDR, ID de peer ou ID de groupe selon target_type

Créer une politique [admin]

POST /networks/:networkId/policies

Corps de la requête

{
"name": "allow-bureau",
"description": "Autoriser l'accès au sous-réseau bureau",
"rules": [
{
"direction": "output",
"action": "allow",
"target": "192.168.1.0/24",
"target_type": "cidr",
"description": "LAN Bureau"
}
]
}

description et rules sont optionnels. Réponse 201 — objet Policy.


Obtenir une politique [admin]

GET /networks/:networkId/policies/:policyId

Réponse 200 — objet Policy.


Mettre à jour une politique [admin]

PUT /networks/:networkId/policies/:policyId

Corps de la requête (tous les champs optionnels)

{
"name": "allow-bureau-v2",
"description": "Description mise à jour"
}

Réponse 200 — objet Policy mis à jour.


Supprimer une politique [admin]

DELETE /networks/:networkId/policies/:policyId

Réponse 204 No Content


Ajouter une règle à une politique [admin]

POST /networks/:networkId/policies/:policyId/rules

Corps de la requête

{
"direction": "output",
"action": "allow",
"target": "192.168.1.0/24",
"target_type": "cidr",
"description": "LAN Bureau"
}

Réponse 201 — objet PolicyRule.


Retirer une règle d'une politique [admin]

DELETE /networks/:networkId/policies/:policyId/rules/:ruleId

Réponse 204 No Content


Attacher une politique à un groupe [admin]

POST /networks/:networkId/groups/:groupId/policies/:policyId

Réponse 200


Détacher une politique d'un groupe [admin]

DELETE /networks/:networkId/groups/:groupId/policies/:policyId

Réponse 204 No Content


Obtenir les politiques d'un groupe [admin]

GET /networks/:networkId/groups/:groupId/policies

Réponse 200 — tableau d'objets Policy attachés au groupe.


Réordonner les politiques d'un groupe [admin]

Définit l'ordre d'évaluation des politiques au sein d'un groupe. Le tableau doit contenir tous les IDs de politiques actuellement attachés au groupe.

PUT /networks/:networkId/groups/:groupId/policies/order

Corps de la requête

{
"policy_ids": ["policy-uuid-1", "policy-uuid-2"]
}

Réponse 200

{ "message": "Policies reordered successfully" }

Routes

Les routes nécessitent DB_ENABLED=true. Tous les endpoints de route sont [admin] uniquement.

Lister les routes [admin]

GET /networks/:networkId/routes

Réponse 200 — tableau d'objets Route.

[
{
"id": "route-uuid",
"network_id": "net-uuid",
"name": "bureau-lan",
"description": "Réseau interne bureau",
"destination_cidr": "192.168.1.0/24",
"jump_peer_id": "jump-uuid",
"domain_suffix": "bureau.internal",
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-04-01T00:00:00Z"
}
]

Créer une route [admin]

POST /networks/:networkId/routes

Corps de la requête

{
"name": "bureau-lan",
"description": "Réseau interne bureau",
"destination_cidr": "192.168.1.0/24",
"jump_peer_id": "jump-uuid",
"domain_suffix": "bureau.internal"
}

description et domain_suffix sont optionnels. Réponse 201 — objet Route.


Obtenir une route [admin]

GET /networks/:networkId/routes/:routeId

Réponse 200 — objet Route.


Mettre à jour une route [admin]

PUT /networks/:networkId/routes/:routeId

Corps de la requête (tous les champs optionnels)

{
"name": "bureau-lan-v2",
"description": "Description mise à jour",
"destination_cidr": "192.168.2.0/24",
"jump_peer_id": "jump-uuid-2",
"domain_suffix": "corp.internal"
}

Réponse 200 — objet Route mis à jour.


Supprimer une route [admin]

DELETE /networks/:networkId/routes/:routeId

Réponse 204 No Content


Attacher une route à un groupe [admin]

POST /networks/:networkId/groups/:groupId/routes/:routeId

Réponse 200

Retourne 400 Bad Request avec des détails si l'attachement crée une dépendance de routage circulaire.


Détacher une route d'un groupe [admin]

DELETE /networks/:networkId/groups/:groupId/routes/:routeId

Réponse 204 No Content


Correspondances DNS

Les correspondances DNS nécessitent DB_ENABLED=true. Tous les endpoints DNS sont [admin] uniquement.

Les correspondances DNS résolvent des noms d'hôte dans le CIDR d'une route vers des adresses IP spécifiques. Le format FQDN est <nom>.<nom_route>.<suffixe_domaine>.

Lister les correspondances DNS [admin]

GET /networks/:networkId/routes/:routeId/dns

Réponse 200 — tableau d'objets DNSMapping.

[
{
"id": "dns-uuid",
"route_id": "route-uuid",
"name": "server1",
"ip_address": "192.168.1.10",
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-04-01T00:00:00Z"
}
]

Créer une correspondance DNS [admin]

POST /networks/:networkId/routes/:routeId/dns

Corps de la requête

{
"name": "server1",
"ip_address": "192.168.1.10"
}

Le champ name doit respecter les règles des labels DNS (alphanumérique + tirets, max 63 caractères). Réponse 201 — objet DNSMapping.


Mettre à jour une correspondance DNS [admin]

PUT /networks/:networkId/routes/:routeId/dns/:dnsId

Corps de la requête (tous les champs optionnels)

{
"name": "server1-nouveau",
"ip_address": "192.168.1.11"
}

Réponse 200 — objet DNSMapping mis à jour.


Supprimer une correspondance DNS [admin]

DELETE /networks/:networkId/routes/:routeId/dns/:dnsId

Réponse 204 No Content


Obtenir les enregistrements DNS d'un réseau [admin]

Retourne tous les enregistrements DNS pour un réseau (basés sur les peers et les correspondances de route).

GET /networks/:networkId/dns

Réponse 200 — tableau d'objets d'enregistrement DNS.

[
{
"name": "laptop-alice",
"ip_address": "10.10.0.2",
"fqdn": "laptop-alice.bureau.internal",
"type": "peer"
},
{
"name": "server1",
"ip_address": "192.168.1.10",
"fqdn": "server1.bureau-lan.bureau.internal",
"type": "route"
}
]
typeSource
"peer"Peer dans le réseau
"route"Correspondance DNS attachée à une route

ACL

Les endpoints ACL sont [admin] uniquement.

L'ACL est une couche légère d'autorisation/refus opérant au niveau peer-à-peer. Elle complète les politiques de groupe. Lorsqu'elle est désactivée, tous les peers peuvent communiquer librement.

Obtenir l'ACL [admin]

GET /networks/:networkId/acl

Réponse 200

{
"id": "acl-uuid",
"name": "default",
"enabled": true,
"blocked_peers": {
"peer-uuid-bad": true
},
"rules": [
{
"id": "rule-uuid",
"source_peer": "*",
"target_peer": "peer-uuid-3",
"action": "deny",
"description": "Bloquer l'accès au serveur"
}
]
}
ChampDescription
enabledQuand false, l'ACL est contournée et tous les peers peuvent communiquer
blocked_peersMap des IDs de peers inconditionnellement bloqués
rulesListe ordonnée de règles ; la première correspondance l'emporte ; défaut : autoriser
source_peer / target_peerID de peer ou "*" pour tous les peers

Mettre à jour l'ACL [admin]

Remplace la configuration ACL complète.

PUT /networks/:networkId/acl

Corps de la requête — objet ACL complet (même structure que la réponse GET).

Réponse 200 — objet ACL mis à jour. Notifie les agents connectés via WebSocket.


Sécurité / Incidents

Lister les incidents de sécurité

Retourne les incidents de sécurité. Les utilisateurs non-admin ne voient que les incidents pour leurs propres peers.

GET /security/incidents

Paramètres de requête

ParamètreDescription
resolvedtrue ou false pour filtrer par statut résolu ; omettez pour tous

Réponse 200 — tableau d'objets SecurityIncident.

[
{
"id": "incident-uuid",
"peer_id": "peer-uuid",
"peer_name": "laptop-alice",
"network_id": "net-uuid",
"network_name": "bureau",
"incident_type": "session_conflict",
"detected_at": "2024-04-13T08:00:00Z",
"public_key": "base64pubkey=",
"endpoints": ["203.0.113.5:51820", "198.51.100.1:51820"],
"details": "Plusieurs agents actifs détectés pour le même peer",
"resolved": false,
"resolved_at": null,
"resolved_by": null
}
]

Valeurs incident_type :

ValeurDescription
shared_configMême clé WireGuard utilisée depuis plusieurs IPs
session_conflictPlusieurs agents actifs pour le même peer
suspicious_activityChangements d'endpoint rapides détectés

Lister les incidents de sécurité d'un réseau

GET /networks/:networkId/security/incidents

Même comportement que l'endpoint global mais limité à un réseau. Accepte le même paramètre resolved.

Réponse 200 — tableau d'objets SecurityIncident.


Obtenir un incident de sécurité

GET /security/incidents/:incidentId

Les utilisateurs non-admin ne peuvent récupérer que les incidents pour leurs propres peers.

Réponse 200 — objet SecurityIncident.


Résoudre un incident de sécurité [admin]

POST /security/incidents/:incidentId/resolve

Réponse 200

{ "message": "Incident resolved successfully" }

Obtenir la configuration de sécurité d'un réseau [admin]

GET /networks/:networkId/security/config

Réponse 200

{
"id": "cfg-uuid",
"network_id": "net-uuid",
"enabled": true,
"session_conflict_threshold_minutes": 5,
"endpoint_change_threshold_minutes": 5,
"max_endpoint_changes_per_day": 10,
"port_change_threshold_minutes": 5,
"max_port_changes_per_window": 5,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-04-13T00:00:00Z"
}

Toutes les valeurs de seuil sont en minutes.


Mettre à jour la configuration de sécurité d'un réseau [admin]

PUT /networks/:networkId/security/config

Corps de la requête (tous les champs optionnels)

{
"enabled": true,
"session_conflict_threshold_minutes": 5,
"endpoint_change_threshold_minutes": 10,
"max_endpoint_changes_per_day": 20,
"port_change_threshold_minutes": 5,
"max_port_changes_per_window": 10
}

Validation : toutes les valeurs de seuil doivent être ≥ 1. max_endpoint_changes_per_day et max_port_changes_per_window doivent être entre 1 et 1000.

Réponse 200 — objet SecurityConfigResponse mis à jour.


IPAM

Suggérer des CIDRs disponibles

Suggère un ou plusieurs CIDRs de la bonne taille pour un nombre cible de peers, découpés depuis un CIDR de base. Utile lors de la planification d'un nouveau réseau.

GET /ipam/available-cidrs

Paramètres de requête

ParamètreRequisDéfautDescription
max_peersOuiNombre minimum d'adresses d'hôtes utilisables nécessaires
countNon1Nombre de CIDRs à retourner (max 20)
base_cidrNon10.0.0.0/8CIDR racine depuis lequel découper

Réponse 200

{
"base_cidr": "10.0.0.0/8",
"requested_max_peers": 50,
"suggested_prefix": 26,
"usable_hosts": 62,
"cidrs": ["10.0.0.0/26", "10.0.0.64/26"]
}

Lister les allocations IPAM

Retourne toutes les allocations IP sur les réseaux accessibles, avec pagination et filtrage.

GET /ipam

Les utilisateurs non-admin ne voient que les peers dont ils sont propriétaires.

Paramètres de requête

ParamètreDéfautDescription
page1Numéro de page
page_size20Éléments par page (max 100)
filterFiltre par sous-chaîne sur le nom du réseau, l'IP ou le nom du peer

Réponse 200

{
"data": [
{
"network_id": "net-uuid",
"network_name": "bureau",
"network_cidr": "10.10.0.0/16",
"ip": "10.10.0.2",
"peer_id": "peer-uuid",
"peer_name": "laptop-alice",
"allocated": true
}
],
"total": 1,
"page": 1,
"page_size": 20
}

Obtenir les allocations IPAM d'un réseau

GET /ipam/networks/:networkId

Réponse 200 — tableau d'objets IPAMAllocation pour le réseau spécifié.


Sessions

Lister les sessions d'un réseau

Retourne les sessions d'agent actives dans un réseau.

GET /networks/:networkId/sessions

Réponse 200 — tableau d'objets AgentSession.

[
{
"peer_id": "peer-uuid",
"hostname": "laptop-alice",
"system_uptime": 86400,
"wireguard_uptime": 3600,
"reported_endpoint": "203.0.113.5:51820",
"last_seen": "2024-04-13T10:00:00Z",
"first_seen": "2024-04-12T09:00:00Z",
"session_id": "sess-uuid"
}
]

Inscription de l'agent

Résoudre un token d'agent

Échange un token d'inscription de peer contre les identifiants du peer et sa configuration WireGuard. Cet endpoint n'est pas authentifié (utilise le token lui-même comme authentification via Authorization: Bearer).

GET /agent/resolve

En-têtes

Authorization: Bearer <enrollment-token>

Réponse 200

{
"network_id": "net-uuid",
"peer_id": "peer-uuid",
"peer_name": "laptop-alice",
"config": "[Interface]\nPrivateKey = ...\n..."
}

Retourne 404 Not Found si le token est invalide ou expiré.


Serveur MCP

Wirety expose un serveur Model Context Protocol (MCP) sur /api/v1/mcp en utilisant le transport SSE. Les méthodes GET (flux) et POST (messages) sur le même chemin sont supportées. L'authentification est requise (mêmes mécanismes de session/token que les autres endpoints).

Consultez la documentation MCP pour la liste des outils disponibles.


WebSocket

WebSocket (basé sur un token)

GET /ws

Connexion avec un token WebSocket à courte durée de vie. Délivre des mises à jour de configuration de peer en temps réel.

WebSocket (héritage)

GET /ws/:networkId/:peerId

Connexion WebSocket spécifique à un peer en utilisant directement les IDs de réseau et de peer.


Portail captif

Créer un token de portail captif

Appelé par un agent de peer jump (authentifié via un token d'inscription) lorsqu'un nouveau peer se connecte et doit s'authentifier.

POST /captive-portal/token

En-têtes

Authorization: Bearer <jump-peer-enrollment-token>

Corps de la requête

{ "peer_ip": "10.10.0.5" }

Réponse 201 — objet token de portail captif.

Nécessite que l'authentification OIDC soit activée (AUTH_ENABLED=true).


Authentifier le portail captif

Valide le token de portail captif contre la session utilisateur courante et met le peer sur liste blanche.

POST /captive-portal/authenticate

Nécessite la présence du cookie wirety_session (défini lors de la connexion).

Corps de la requête

{ "captive_token": "captive-token-value" }

Réponse 200

{
"peer_ip": "10.10.0.5",
"network_id": "net-uuid",
"whitelisted": true
}