For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
Navegação principal

Gerencie contas de serviço com o Terraform

Crie identidades não humanas com privilégios mínimos e emita chaves de API fora do Terraform.

Uma conta de serviço da OpenAI é uma identidade não humana pertencente a um projeto. O Terraform pode criar a conta sem uma função padrão, definir um conjunto de permissões com privilégios mínimos e atribuir esse conjunto por meio de um grupo. Crie e gerencie chaves de API de contas de serviço fora do Terraform por meio da API de administração.

Este guia segue um fluxo típico de configuração inicial de contas de serviço:

  1. Crie uma conta de serviço sem uma função padrão no projeto nem uma chave de API.
  2. Atribua uma função personalizada de projeto por meio de um grupo, concedendo apenas as permissões necessárias para a carga de trabalho.
  3. Crie uma chave de API com escopo definido e armazene-a no seu gerenciador de segredos.

Antes de começar

Conclua a configuração do provedor Terraform, exporte uma chave da API de administração como OPENAI_ADMIN_KEY e exporte o ID do projeto existente como PROJECT_ID.

Use uma organização de teste ao avaliar a criação, importação, substituição e exclusão de contas de serviço.

Crie uma conta de serviço sem uma função padrão

Crie a conta de serviço com o 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
}

Substitua proj_123 pelo ID do projeto existente ao qual a conta de serviço pertencerá.

O provedor cria a identidade da conta de serviço sem gerar uma chave de API nem atribuir uma função padrão no projeto. O Terraform armazena o ID da conta de serviço e outros metadados não sensíveis no estado. Nesta etapa, a conta de serviço não tem permissões no projeto.

Atribua permissões com privilégios mínimos

Defina uma função personalizada de projeto com apenas as permissões necessárias para a carga de trabalho. Crie um grupo, adicione a conta de serviço a ele e atribua a função ao grupo. Este exemplo permite que os membros do grupo criem respostas:

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
}

O recurso openai_project_role define o conjunto de permissões com privilégios mínimos, openai_group_user adiciona a conta de serviço ao grupo e openai_project_group_role atribui a função a esse grupo. Toda conta de serviço adicionada ao grupo herda a mesma função de projeto. Substitua api.responses.write pelo menor conjunto de permissões aprovado para sua carga de trabalho. Consulte Projetos e acesso para saber mais sobre o acesso a projetos baseado em grupos.

Revise e aplique a configuração:

terraform plan
terraform apply

Não atribua a função integrada member ou owner quando uma função personalizada de projeto fornecer as permissões necessárias para sua carga de trabalho. Mantenha o acesso limitado ao conjunto de permissões aprovado.

Crie uma chave de API com escopo definido

Depois de aplicar a configuração do Terraform, crie uma chave de API por meio do endpoint Criar chave de API de conta de serviço de projeto. A API retorna o valor completo da chave apenas uma vez, portanto proteja o arquivo de resposta antes de fazer a solicitação:

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

Escolha os escopos mais restritos que atendam às necessidades da carga de trabalho. Os escopos da chave de API podem restringir ainda mais as permissões da conta de serviço, mas não podem conceder permissões além das previstas na função de projeto atribuída a ela.

Passe o value de service-account-api-key.json para seu fluxo aprovado de gerenciamento de segredos sem exibi-lo. Depois que o gerenciador de segredos armazenar e verificar o segredo, remova o arquivo de resposta:

rm service-account-api-key.json

Trate service-account-api-key.json como um segredo enquanto o arquivo existir. Não o inclua em commits, não grave a chave na configuração do Terraform, não a exponha por meio de uma saída do Terraform nem a passe como uma variável do Terraform.

A Referência da API inclui a estrutura da resposta e exemplos específicos para cada linguagem. Cargas de trabalho que oferecem suporte à federação de identidades de cargas de trabalho podem usar a mesma conta de serviço e a mesma função com privilégios mínimos sem criar uma chave de API.

Importe uma conta de serviço existente

Você não precisa importar uma conta de serviço criada pelo Terraform. Para passar a gerenciar uma conta de serviço criada fora do Terraform, declare-a com o mesmo ID de projeto e o mesmo nome:

resource "openai_project_service_account" "application" {
  project_id = "proj_123"
  name       = "example-application-development-service-account"
}

Importe a identidade existente antes de aplicar a configuração normalmente:

SERVICE_ACCOUNT_ID="<existing-service-account-id>"

terraform import \
  openai_project_service_account.application \
  "$PROJECT_ID/$SERVICE_ACCOUNT_ID"

terraform plan

O primeiro plano após a importação não deve propor alterações na conta de serviço. Se ele propuser uma substituição, ajuste o nome e o projeto configurados para que correspondam aos da conta existente antes de aplicar o plano.

A importação não recupera nem armazena uma chave de API, não altera a função de projeto existente da conta de serviço nem importa sua associação ao grupo. Declare e importe os recursos existentes openai_project_role, openai_group, openai_group_user e openai_project_group_role se o Terraform precisar gerenciá-los. A carga de trabalho continua lendo qualquer segredo existente do seu gerenciador de segredos.

Importe a conta de serviço antes de aplicar a declaração do recurso. Se você aplicar primeiro, o Terraform criará outra conta de serviço em vez de passar a gerenciar a identidade existente.

Recupere ou rotacione credenciais

O valor completo da chave de API só está disponível na resposta de criação da chave. Consultas posteriores à chave de API do projeto retornam um valor ocultado, portanto não é possível recuperar uma chave perdida.

Substitua uma credencial perdida ou em rotação sem interromper a carga de trabalho:

  1. Declare a conta substituta como um novo recurso openai_project_service_account, usando um nome de recurso do Terraform diferente do usado para a conta antiga.
  2. Aplique a configuração para criar a conta de serviço substituta.
  3. Adicione a conta substituta ao grupo existente com openai_group_user para que ela herde a função de projeto com privilégios mínimos.
  4. Crie uma chave de API para a conta substituta por meio da API de administração e armazene a chave usando seu fluxo aprovado de gerenciamento de segredos.
  5. Implante a chave substituta e verifique a carga de trabalho com a conta substituta.
  6. Remova o openai_project_service_account antigo e seu recurso openai_group_user da configuração do Terraform. Mantenha a função, o grupo e a atribuição de função ao grupo que a conta de serviço substituta ainda usa.
  7. Revise e aplique o plano que exclui a conta de serviço antiga e sua associação ao grupo. Em seguida, execute terraform plan e exija um resultado sem alterações.

Excluir um recurso openai_project_service_account exclui a conta de serviço remota. Exija uma revisão explícita dessa alteração, especialmente enquanto a credencial antiga ainda estiver sendo usada para atender ao tráfego.

Para saber mais sobre o comportamento de incorporação e remoção de recursos no estado, consulte Importação e reconciliação.

Execute o exemplo completo

Os exemplos de cada etapa usam valores concretos para explicar a criação de contas de serviço, a atribuição de funções e a criação de chaves de API. A configuração completa substitui valores e permissões específicos do projeto por variáveis para que você possa reutilizá-la em diferentes ambientes.

Salve a configuração a seguir como 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
}

Crie terraform.tfvars com o ID de um projeto existente, um nome exclusivo para a conta de serviço e o menor conjunto de permissões de projeto aprovado:

project_id           = "proj_123"
service_account_name = "example-application-development-service-account"

project_role_permissions = [
  "api.responses.write",
]

Inicialize o Terraform e, em seguida, revise e aplique um plano salvo:

terraform init
terraform fmt
terraform validate
terraform plan -out=tfplan
terraform show tfplan
terraform apply tfplan

O primeiro plano deve conter cinco recursos a adicionar: a conta de serviço, sua função personalizada de projeto, o grupo, a associação ao grupo e a atribuição de função ao grupo. Execute terraform plan novamente para confirmar que a configuração não gera mais alterações.

Crie a chave de API da conta de serviço fora do 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

Transfira o valor retornado da chave de API para seu gerenciador de segredos aprovado e, em seguida, exclua service-account-api-key.json. Não armazene a chave na configuração, no estado nem nas saídas do Terraform.