Guide de développement de connecteur
English version: ../../en/guides/connector-development.md
Ce guide montre comment écrire, valider, enregistrer, configurer, tester, synchroniser, versionner et retirer un
connecteur vers un système métier. Il s'adresse aux développeurs qui ont le rôle developer ou tenant_admin ;
enregistrer des identifiants demande tenant_admin ou security_officer, et supprimer un connecteur demande
tenant_admin.
Concept
Un connecteur est un manifeste de kind Connector qui déclare un système métier, son authentification, ses ressources
et leur classification. Le Control Plane conserve le manifeste ; le Credential Broker garde les identifiants et remet
des baux courts au moteur d'exécution, si bien qu'un agent ne voit jamais un secret. Chaque appel sortant passe par le
contrôle d'egress et par la politique connector.test ou connector.sync. Un connecteur est active ou disabled.
Champs du manifeste
Le manifeste suit contracts/v1/connector-manifest.schema.json.
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
apiVersion, kind, metadata | oui | enterprise-ai.io/v1, Connector, name, version, owner. | |
spec.description | chaîne | non | Ce que le connecteur lit ou écrit. |
spec.system | chaîne | oui | Type de système, comme rest. |
spec.base_url | chaîne | non | Adresse de base, vérifiée par le contrôle d'egress à l'enregistrement. |
spec.auth | objet | oui | type (oauth2, api_key, service_account, basic, mtls, none), authorization_url, token_url (obligatoire pour oauth2), oauth_scopes, credential_ref, delegation (service, on_behalf_of_user). |
spec.scopes | tableau | non | Droits que le connecteur peut obtenir par bail. |
spec.resources | tableau | oui | Chaque élément : name, operations (read, write, delete, subscribe), classification. |
spec.sync | objet | non | mode (none, pull, push, cdc), schedule (cron), incremental. |
spec.webhooks | objet | non | enabled, signature (hmac_sha256 ; none est refusé), secret_ref (openbao:// ou env://). |
spec.rate_limit | objet | non | requests_per_minute. |
spec.data_residency | non | Région où les données doivent rester. |
Créer un connecteur
Le modèle sdks/python/src/enterprise_ai/templates/connector fournit connector.py, connector.yaml (contracts/v1/connector-manifest.schema.json), des politiques et des tests.
enterprise-ai create connector sharepoint
enterprise-ai validate -f sharepoint/connector.yaml
Étapes
-
Créer le projet à partir du modèle. Il écrit le manifeste, le code, une politique OPA avec ses tests et des tests pytest. Dans le portail : Studio développeur > Studio de connecteurs > Nouveau.
enterprise-ai create connector sharepointRésultat attendu : les fichiers sont listés et
connector.yamlest déclaré valide.En cas d'échec : code de sortie 1 avec « exists » ; ajoutez
--forceou choisissez un autre nom. -
Modifier le manifeste. Renseignez le système,
base_url, l'authentification et une entrée par ressource avec ses opérations et sa classification. N'écrivez qu'une référence danscredential_ref(openbao://...), jamais une valeur.Résultat attendu : chaque ressource utile aux agents est déclarée avec le plus petit ensemble d'opérations.
En cas d'échec : voyez la table des champs ci-dessus.
-
Valider et tester en local. Le contrôle hors ligne lit le contrat ; les tests du modèle exécutent la politique et le code.
enterprise-ai validate -f sharepoint/connector.yamlcd sharepointpython -m pytest -q testsenterprise-ai test authzRésultat attendu : code de sortie 0 partout.
En cas d'échec : corrigez les champs ou les règles listés.
-
Enregistrer le connecteur. POST /v1/connectors le crée, ou le met à jour quand le nom existe. Dans le portail : Enregistrer comme nouvelle version.
enterprise-ai apply -f connector.yamlRésultat attendu : statut
createdouupdated.En cas d'échec : 422
invalid_manifestavecauth.token_url(OAuth 2 sans adresse de jeton) ouwebhooks.signature(webhooks non signés), 403egress_deniedpour une adresse hors de la politique d'egress. -
Enregistrer les identifiants. POST /v1/connectors/{name}/credentials les confie au Credential Broker ; ils sont écrits une fois et jamais renvoyés. Le champ
kindchoisit les champs :oauth2_client(client_id,client_secret),oauth2_code(code,redirect_uri,code_verifieroptionnel),api_key(api_key,headeroptionnel),service_account(private_keyoutoken),basic(username,password),webhook_secret(secret).client.connectors.set_credentials("sharepoint", {"kind": "oauth2_client", "client_id": "<client-id>", "client_secret": "<secret>"})Résultat attendu :
stored: trueavec la liste des noms de champs enregistrés.En cas d'échec : 400
invalid_requestliste les champs manquants ou les types autorisés ; 409credential_unavailablepouroauth2_codeavantoauth2_client. -
Tester la connexion. POST /v1/connectors/{name}/test résout les identifiants et appelle
base_urlà travers le contrôle d'egress. Dans le portail : Studio de connecteurs > connecteur > Test > Tester la connexion.Résultat attendu :
ok: true,credentials: ok, lehttp_statusetlatency_ms.En cas d'échec :
errordonne la cause :egress_denied,upstream_unavailable,credential_unavailableoucredential_rejected. -
Synchroniser. POST /v1/connectors/{name}/sync met en file une synchronisation (202) sur les ressources lisibles ; une synchronisation incrémentale reprend au dernier curseur sauf si
fullest posé. GET /v1/connectors/{name}/sync-runs liste les synchronisations.client.connectors.sync("sharepoint", full=True)Résultat attendu : une synchronisation en
queued, puisrunningetsucceeded.En cas d'échec : 409
sync_disabled(sync.modevautnone), 409connector_disabled, 409sync_in_progress, 400invalid_requestpour une ressource non lisible. -
Publier une nouvelle version. Augmentez
metadata.versionet appliquez de nouveau le manifeste ; les identifiants enregistrés sont conservés.Résultat attendu : statut
updated.En cas d'échec : testez de nouveau la connexion (étape 6) après un changement de
auth. -
Désactiver ou supprimer. PATCH /v1/connectors/{name} avec
status: disabledarrête les nouveaux baux et révoque les baux actifs ; DELETE /v1/connectors/{name} supprime aussi les secrets enregistrés.client.connectors.update("sharepoint", status="disabled")Résultat attendu : statut
disabled, ou 204 à la suppression.En cas d'échec : 404
connector_not_found.
Supprimer un connecteur supprime ses identifiants du coffre de secrets. Désactivez-le d'abord si vous pouvez en avoir de nouveau besoin.
OAuth, clés d'API et secrets
Les identifiants (secret client OAuth, clé d'API d'un service métier) sont en écriture seule : POST /v1/connectors/{name}/credentials les confie au Credential Broker et ils ne sont jamais renvoyés ni exposés aux agents. Les secrets génériques passent par POST /v1/secrets.
client.connectors.set_credentials("sharepoint", {"kind": "oauth2_client", "client_id": "<client-id>", "client_secret": "<secret>"})
À l'exécution, le moteur demande à POST /v1/credentials/broker/lease un bail (30 à 3600 secondes) limité à des droits du connecteur. Les webhooks d'un connecteur arrivent sur POST /v1/webhooks/{connector}, signés en HMAC-SHA256 avec un horodatage de moins de 5 minutes.
Tester et synchroniser
POST /v1/connectors crée le connecteur, POST /v1/connectors/{name}/test vérifie la connexion, POST /v1/connectors/{name}/sync lance une synchronisation.
Dépannage
| Symptôme | Cause | Correction |
|---|---|---|
404 connector_not_found | Nom inconnu dans le tenant. | Vérifiez avec enterprise-ai get connectors. |
422 invalid_manifest | auth.token_url absent pour oauth2, ou webhooks.signature: none. | Ajoutez l'adresse de jeton ; gardez hmac_sha256. |
403 egress_denied | base_url, token_url ou authorization_url est hors de la politique d'egress. | Demandez à l'administrateur d'autoriser l'hôte. |
400 invalid_request | kind d'identifiant inconnu ou champs manquants. | Envoyez les champs du type listés à l'étape 5. |
502 credential_unavailable | Aucun identifiant enregistré, ou la référence de secret ne se résout pas. | Enregistrez les identifiants, vérifiez credential_ref. |
502 credential_rejected | Le point de jeton a refusé le client. | Vérifiez l'identifiant et le secret client avec le responsable du système. |
409 sync_disabled, sync_in_progress, connector_disabled | Synchronisation non configurée, déjà en cours, ou connecteur désactivé. | Réglez sync.mode, attendez la fin, ou réactivez le connecteur. |
403 scope_not_allowed | Le bail demande un droit hors de spec.scopes. | Ajoutez le droit au manifeste ou demandez moins. |
401 invalid_lease | Le bail est expiré ou révoqué. | Demandez un nouveau bail. |
401 invalid_signature, webhook_replay | Signature du webhook fausse ou horodatage trop ancien. | Signez avec le secret de webhook enregistré et l'heure courante. |
Étapes suivantes
- Guide de développement MCP pour exposer le connecteur sous forme d'outils.
- Guide de développement des packs pour le connecteur d'un pack.
- Guide de développement de politiques et guide de référence de l'API.