Terraform Provider
O provider oficial ciphervault/ciphervault permite gerenciar vaults,
secrets, policies e AppConnections como código.
Instalação
terraform {
required_version = ">= 1.5"
required_providers {
ciphervault = {
source = "ciphervault/ciphervault"
version = "~> 1.6"
}
}
}
provider "ciphervault" {
endpoint = "https://api.ciphervault.com.br"
# Auth via env CIPHERVAULT_TOKEN, ou OIDC para CI/CD:
# auth = "oidc"
# oidc_role = "terraform-prod"
}
Exemplos
Vault
resource "ciphervault_vault" "producao" {
name = "producao"
description = "Cofre de produção"
environment = "production"
encryption {
algorithm = "AES-256-GCM"
key_source = "byok"
kms_key_arn = "arn:aws:kms:sa-east-1:123:key/abc"
rotation_days = 90
}
tags = {
cost_center = "billing"
compliance = "lgpd,pci"
}
}
Policy
resource "ciphervault_policy" "billing_readers" {
name = "billing-readers"
document = jsonencode({
version = "2025-01-01"
statement = [
{
sid = "read-stripe"
effect = "allow"
action = ["secrets:read"]
resource = "vault/${ciphervault_vault.producao.name}/api/stripe/*"
principal = { group = ["billing-team"] }
condition = {
stringEquals = { "request:mfaPresent" = "true" }
}
}
]
})
}
Secret (somente para dados estáticos não sensíveis — dados sensíveis devem ser inseridos via UI/API)
resource "ciphervault_secret" "stripe_webhook" {
vault = ciphervault_vault.producao.name
path = "api/stripe/webhook_secret"
type = "api_key"
# ATENÇÃO: o valor entrará no state. Use apenas para secrets de
# baixa criticidade ou marque o state como sensível e cifrado.
value = var.stripe_webhook_secret
metadata = {
description = "Webhook signing secret"
owner = "billing-team@acme.com.br"
}
}
Database secret com rotação
resource "ciphervault_database_secret" "billing_db" {
vault = ciphervault_vault.producao.name
path = "db/postgres/billing-master"
engine = "postgresql"
connection {
host = "db-billing.internal.acme.com.br"
port = 5432
database = "billing"
admin_username = "ciphervault_admin"
admin_password_secret = "db/postgres/admin"
}
rotation {
enabled = true
interval_days = 30
grace_window_minutes = 5
rollback_on_failure = true
}
}
AppConnection
resource "ciphervault_app_connection" "billing_api" {
name = "billing-api"
vault = ciphervault_vault.producao.name
allowed_paths = ["api/stripe/*", "db/postgres/billing-master"]
ip_allowlist = ["10.0.0.0/8"]
mtls_required = true
}
output "billing_api_client_id" {
value = ciphervault_app_connection.billing_api.client_id
sensitive = false
}
output "billing_api_client_secret" {
value = ciphervault_app_connection.billing_api.client_secret
sensitive = true
}
client_secret aparece apenas na criação — após o apply, futuros
plan não conseguem lê-lo. Trate o state como secret.
OIDC Provider e Role
resource "ciphervault_oidc_provider" "github" {
name = "github-acme"
issuer = "https://token.actions.githubusercontent.com"
audience = "https://ciphervault.com.br"
}
resource "ciphervault_oidc_role" "deploy_prod" {
name = "deploy-producao"
provider = ciphervault_oidc_provider.github.name
trust = {
repository = "acme-corp/billing-api"
environment = "production"
ref = "refs/heads/main"
}
policies = [ciphervault_policy.billing_readers.name]
ttl_seconds = 900
}
Boas práticas
- State remoto criptografado. S3 + KMS, GCS + CMEK ou Terraform Cloud.
- Workspace separado para CipherVault. Não misture com infra de aplicação.
- OIDC para o próprio Terraform Cloud. Sem token estático no
provider. - Use
lifecycle.prevent_destroyem vaults de produção. - Não armazene secrets sensíveis no state se possível. Prefira inserir via API/UI e usar
data "ciphervault_secret"para referenciar.