Un compte de service OpenAI est une identité non humaine appartenant à un projet. Terraform peut créer le compte sans rôle par défaut, définir un ensemble d’autorisations selon le principe du moindre privilège et attribuer cet ensemble par l’intermédiaire d’un groupe. Créez et gérez les clés API des comptes de service en dehors de Terraform, via l’API d’administration.
Ce guide suit un workflow courant de mise en service d’un compte de service :
- Créez un compte de service sans rôle de projet par défaut ni clé API.
- Attribuez un rôle de projet personnalisé par l’intermédiaire d’un groupe, en accordant uniquement les autorisations nécessaires à la charge de travail.
- Créez une clé API à portée limitée et stockez-la dans votre gestionnaire de secrets.
Avant de commencer
Terminez la configuration du fournisseur Terraform, exportez une clé de l’API d’administration dans OPENAI_ADMIN_KEY et exportez l’ID du projet existant dans PROJECT_ID.
Utilisez une organisation de test pour évaluer la création, l’importation, le remplacement et la suppression des comptes de service.
Créez un compte de service sans rôle par défaut
Créez le compte de service avec Terraform :
resource "openai_project_service_account" "application" {
project_id = "proj_123"
name = "example-application-development-service-account"
}
output "service_account_id" {
value = openai_project_service_account.application.service_account_id
}
Remplacez proj_123 par l’ID du projet existant auquel appartiendra le compte de service.
Le fournisseur crée l’identité du compte de service sans générer de clé API ni attribuer de rôle de projet par défaut. Terraform stocke l’ID du compte de service et les autres métadonnées non sensibles dans son état. À ce stade, le compte de service ne dispose d’aucune autorisation sur le projet.
Attribuez les autorisations selon le principe du moindre privilège
Définissez un rôle de projet personnalisé qui inclut uniquement les autorisations nécessaires à la charge de travail. Créez un groupe, ajoutez-y le compte de service et attribuez le rôle au groupe. Cet exemple permet aux membres du groupe de créer des réponses :
resource "openai_project_role" "application" {
project_id = openai_project_service_account.application.project_id
role_name = "Application response writer"
description = "Allows the application to create responses"
permissions = ["api.responses.write"]
}
resource "openai_group" "application_access" {
name = "example-application-development-access"
}
resource "openai_group_user" "application" {
group_id = openai_group.application_access.group_id
user_id = openai_project_service_account.application.id
}
resource "openai_project_group_role" "application_access" {
project_id = openai_project_service_account.application.project_id
group_id = openai_group.application_access.group_id
role_id = openai_project_role.application.role_id
}
La ressource openai_project_role définit l’ensemble d’autorisations selon le principe du moindre privilège, openai_group_user ajoute le compte de service au groupe et openai_project_group_role attribue le rôle à ce groupe. Chaque compte de service ajouté au groupe hérite du même rôle de projet. Remplacez api.responses.write par l’ensemble minimal d’autorisations approuvées pour votre charge de travail. Consultez Projets et accès pour en savoir plus sur l’accès aux projets par l’intermédiaire de groupes.
Examinez et appliquez la configuration :
terraform plan
terraform apply
N’attribuez pas le rôle intégré member ou owner lorsqu’un rôle de projet personnalisé
fournit les autorisations nécessaires à votre charge de travail. Limitez l’accès à
l’ensemble d’autorisations approuvé.
Créez une clé API à portée limitée
Après avoir appliqué la configuration Terraform, créez une clé API via le point de terminaison Créer une clé API de compte de service de projet. L’API ne renvoie la valeur complète de la clé qu’une seule fois : protégez donc le fichier de réponse avant d’effectuer la requête :
SERVICE_ACCOUNT_ID="$(terraform output -raw service_account_id)"
umask 077
curl -X POST \
"https://api.openai.com/v1/organization/projects/$PROJECT_ID/service_accounts/$SERVICE_ACCOUNT_ID/api_keys" \
-H "Authorization: Bearer $OPENAI_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Production App",
"scopes": ["api.responses.write"]
}' \
--output service-account-api-key.json
Choisissez les portées les plus restreintes qui répondent aux besoins de la charge de travail. Les portées d’une clé API peuvent restreindre davantage les autorisations du compte de service, mais elles ne peuvent pas accorder d’autorisations au-delà de celles du rôle de projet qui lui est attribué.
Transmettez le champ value de service-account-api-key.json à votre workflow approuvé de gestion des secrets, sans en afficher le contenu. Une fois le secret stocké et vérifié par votre gestionnaire de secrets, supprimez le fichier de réponse :
rm service-account-api-key.json
Traitez service-account-api-key.json comme un secret tant que ce fichier existe. Ne l’incluez pas dans un commit, n’écrivez pas la clé dans la configuration Terraform, ne l’exposez pas dans une sortie Terraform et ne la transmettez pas comme variable Terraform.
La Référence de l’API présente la structure de la réponse et des exemples propres à chaque langage. Les charges de travail qui prennent en charge la fédération d’identités de charge de travail peuvent utiliser le même compte de service et le même rôle respectant le principe du moindre privilège, sans créer de clé API.
Importez un compte de service existant
Vous n’avez pas besoin d’importer un compte de service créé par Terraform. Pour prendre en charge un compte de service créé en dehors de Terraform, déclarez-le avec le même ID de projet et le même nom :
resource "openai_project_service_account" "application" {
project_id = "proj_123"
name = "example-application-development-service-account"
}
Importez l’identité existante avant d’appliquer la configuration normalement :
SERVICE_ACCOUNT_ID="<existing-service-account-id>"
terraform import \
openai_project_service_account.application \
"$PROJECT_ID/$SERVICE_ACCOUNT_ID"
terraform plan
Le premier plan après l’importation ne devrait proposer aucune modification du compte de service. S’il propose un remplacement, faites correspondre le nom et le projet configurés à ceux du compte existant avant d’appliquer le plan.
L’importation ne récupère ni ne stocke de clé API, ne modifie pas le rôle de projet existant du compte de service et n’importe pas son appartenance à un groupe. Déclarez et importez les ressources openai_project_role, openai_group, openai_group_user et openai_project_group_role existantes si Terraform doit les gérer. La charge de travail continue de lire les secrets existants depuis votre gestionnaire de secrets.
Importez le compte de service avant d’appliquer la déclaration de ressource. Si vous l’appliquez d’abord, Terraform crée un autre compte de service au lieu de prendre en charge l’identité existante.
Récupérez ou renouvelez les identifiants
La valeur complète d’une clé API n’est disponible que dans la réponse à sa création. Les récupérations ultérieures de la clé API du projet renvoient une valeur masquée : vous ne pouvez donc pas récupérer une clé perdue.
Remplacez un identifiant perdu ou à renouveler sans interrompre la charge de travail :
- Déclarez le compte de remplacement comme une nouvelle ressource
openai_project_service_account, en utilisant un nom de ressource Terraform différent de celui de l’ancien compte. - Appliquez la configuration pour créer le compte de service de remplacement.
- Ajoutez le compte de remplacement au groupe existant avec
openai_group_userpour qu’il hérite du rôle de projet respectant le principe du moindre privilège. - Créez une clé API pour le compte de remplacement via l’API d’administration et stockez-la à l’aide de votre workflow approuvé de gestion des secrets.
- Déployez la clé de remplacement et vérifiez le fonctionnement de la charge de travail avec le compte de remplacement.
- Retirez l’ancienne ressource
openai_project_service_accountet sa ressourceopenai_group_userde la configuration Terraform. Conservez le rôle, le groupe et l’attribution du rôle au groupe que le compte de service de remplacement utilise toujours. - Examinez et appliquez le plan qui supprime l’ancien compte de service et son appartenance au groupe, puis exécutez
terraform planet exigez un résultat ne proposant aucune modification.
La suppression d’une ressource openai_project_service_account supprime le compte de service distant. Exigez un examen explicite de cette modification, surtout si l’ancien identifiant est encore utilisé pour traiter des requêtes.
Pour en savoir plus sur la prise en charge de ressources dans l’état et leur retrait, consultez Importation et réconciliation.
Exécutez l’exemple complet
Les exemples ciblés utilisent des valeurs concrètes pour expliquer la création d’un compte de service, l’attribution de rôles et la création d’une clé API. La configuration complète remplace les valeurs et les autorisations propres au projet par des variables, afin que vous puissiez la réutiliser dans différents environnements.
Enregistrez la configuration suivante dans main.tf :
terraform {
required_version = ">= 1.0"
required_providers {
openai = {
source = "openai/openai"
version = ">= 1.0.0"
}
}
}
provider "openai" {}
variable "project_id" {
type = string
description = "ID of the existing OpenAI project."
}
variable "service_account_name" {
type = string
description = "Name of the application service account."
}
variable "project_role_permissions" {
type = list(string)
description = "Least-privilege project permissions for the application."
validation {
condition = length(var.project_role_permissions) > 0
error_message = "Provide at least one approved project permission."
}
}
resource "openai_project_service_account" "application" {
project_id = var.project_id
name = var.service_account_name
}
resource "openai_project_role" "application" {
project_id = var.project_id
role_name = "Application API access"
description = "Least-privilege permissions approved for the application"
permissions = var.project_role_permissions
}
resource "openai_group" "application_access" {
name = "${var.service_account_name}-access"
}
resource "openai_group_user" "application" {
group_id = openai_group.application_access.group_id
user_id = openai_project_service_account.application.id
}
resource "openai_project_group_role" "application_access" {
project_id = var.project_id
group_id = openai_group.application_access.group_id
role_id = openai_project_role.application.role_id
}
output "project_id" {
value = var.project_id
}
output "service_account_id" {
value = openai_project_service_account.application.service_account_id
}
output "group_id" {
value = openai_group.application_access.group_id
}
output "project_role_id" {
value = openai_project_role.application.role_id
}
Créez terraform.tfvars avec l’ID d’un projet existant, un nom de compte de service unique et l’ensemble minimal d’autorisations de projet approuvées :
project_id = "proj_123"
service_account_name = "example-application-development-service-account"
project_role_permissions = [
"api.responses.write",
]
Initialisez Terraform, puis examinez et appliquez un plan enregistré :
terraform init
terraform fmt
terraform validate
terraform plan -out=tfplan
terraform show tfplan
terraform apply tfplan
Le premier plan devrait comporter cinq ressources à ajouter : le compte de service, son rôle de projet personnalisé, le groupe, l’appartenance au groupe et l’attribution du rôle au groupe. Exécutez à nouveau terraform plan pour confirmer que la configuration n’entraîne aucune modification supplémentaire.
Créez la clé API du compte de service en dehors de Terraform :
PROJECT_ID="$(terraform output -raw project_id)"
SERVICE_ACCOUNT_ID="$(terraform output -raw service_account_id)"
umask 077
curl -X POST \
"https://api.openai.com/v1/organization/projects/$PROJECT_ID/service_accounts/$SERVICE_ACCOUNT_ID/api_keys" \
-H "Authorization: Bearer $OPENAI_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Production App",
"scopes": ["api.responses.write"]
}' \
--output service-account-api-key.json
Transférez la valeur de la clé API renvoyée dans votre gestionnaire de secrets approuvé, puis supprimez service-account-api-key.json. Ne stockez pas la clé dans la configuration, l’état ou les sorties Terraform.