Skip to content

Terraform Provider for MazeVault

The MazeVault Terraform Provider allows you to manage your MazeVault organization, projects, secrets, certificates, rotations, integrations, and access control entirely as code. The provider is built on the Terraform Plugin Framework and targets Terraform 1.5+.


Installation

terraform {
  required_version = ">= 1.5"
  required_providers {
    mazevault = {
      source  = "MazeVault/mazevault"
      version = "~> 1.0"
    }
  }
}

Provider Configuration

provider "mazevault" {
  server_url    = "https://vault.example.com"
  api_token     = var.mazevault_api_token   # recommended: use a variable, never hardcode
  # Optional: service account credentials (alternative to api_token)
  # client_id     = var.mazevault_client_id
  # client_secret = var.mazevault_client_secret
  timeout        = "30s"
  skip_tls_verify = false  # set true only in development environments
}

Provider Arguments

Argument Type Required Description
server_url string No MazeVault server URL. Defaults to MAZEVAULT_SERVER_URL environment variable.
api_token string No API token for authentication. Sensitive. Defaults to MAZEVAULT_API_TOKEN.
client_id string No Service account client ID. Alternative to api_token.
client_secret string No Service account client secret. Sensitive.
timeout string No API request timeout (e.g. 30s, 1m). Default: 30s.
skip_tls_verify bool No Skip TLS verification. Development only — never enable in production.

Secret handling

Never put credentials directly in .tf files. Use environment variables (MAZEVAULT_API_TOKEN) or a secrets backend such as Vault or Azure Key Vault to inject sensitive values at plan/apply time.


Authentication Methods

export MAZEVAULT_API_TOKEN="mv_pat_xxxxx"
export MAZEVAULT_SERVER_URL="https://vault.example.com"

Generate tokens in Admin → API Tokens or via the mazevault_api_token resource.

Service Account (CI/CD pipelines)

provider "mazevault" {
  server_url    = var.server_url
  client_id     = var.client_id
  client_secret = var.client_secret
}

Resources

mazevault_organization

Manages the top-level organization configuration.

resource "mazevault_organization" "main" {
  name = "Acme Corp"
}
Attribute Type Required Description
id string Computed Organization UUID.
name string Yes Organization name.
created_at string Computed Creation timestamp (ISO 8601).

mazevault_project

Groups secrets and certificates under a logical boundary with its own RBAC.

resource "mazevault_project" "backend" {
  organization_id = mazevault_organization.main.id
  name            = "Backend Services"
  environment     = "production"
}
Attribute Type Required Description
id string Computed Project UUID.
organization_id string Yes Parent organization ID.
name string Yes Project name.
environment string No Primary environment label.
created_at string Computed Creation timestamp.

mazevault_secret

Manages an encrypted secret inside a project. The secret value is stored as an AES-256-GCM encrypted blob in MazeVault and is marked sensitive in Terraform state.

resource "mazevault_secret" "db_password" {
  project_id  = mazevault_project.backend.id
  key         = "DB_PASSWORD"
  value       = var.db_password
  environment = "production"

  ttl_hours = 8760  # 1 year

  metadata = {
    owner = "backend-team"
    tier  = "critical"
  }

  rotation {
    enabled       = true
    interval_days = 90
    notification_emails = ["ops@example.com"]
  }
}
Attribute Type Required Description
id string Computed Secret UUID.
project_id string Yes Parent project ID.
key string Yes Secret name/key (e.g. DB_PASSWORD).
value string Yes Secret value. Sensitive.
environment string Yes Environment (dev, staging, production, …).
ttl_hours number No Time-to-live in hours. Omit for no expiry.
metadata map(string) No Arbitrary key/value labels.
version number Computed Current version counter.
status string Computed Secret lifecycle status.
created_at string Computed Creation timestamp.

rotation block

Attribute Type Required Description
enabled bool Yes Activate automatic rotation.
schedule string No Cron expression for rotation schedule.
interval_days number No Rotation interval in days (alternative to cron).
notification_emails list(string) No Notify these addresses on rotation failure.

Orchestrator Mode

When MazeVault is configured in Orchestrator Mode, the value field is forwarded directly to the configured external secrets manager (Azure Key Vault, AWS Secrets Manager, or HashiCorp Vault). The value is not stored locally.


Links a secret to an integration so that rotation writes the new value into an external system (database, Kubernetes secret, DevOps pipeline variable, etc.).

resource "mazevault_secret_link" "db_link" {
  secret_id      = mazevault_secret.db_password.id
  integration_id = mazevault_integration.azure_kv.id
  link_type      = "database"
  metadata = {
    db_user = "app_user"
    db_host = "db.prod.example.com"
  }
}
Attribute Type Required Description
id string Computed Link UUID.
secret_id string Yes Secret to link.
integration_id string Yes Target integration.
link_type string No database, agent, devops, or generic.
metadata map(string) No Integration-specific configuration.

mazevault_rotation_config

Defines a full rotation pipeline for a secret, including reconciler inputs, grace periods, and write-back targeting.

resource "mazevault_rotation_config" "db_rotation" {
  secret_id          = mazevault_secret.db_password.id
  environment        = "production"
  ttl_hours          = 720            # 30 days
  rotation_strategy  = "rolling"
  grace_period_minutes = 60

  workflow_steps_json = jsonencode([
    {
      type   = "postgres_rotation"
      config = {
        host     = "db.prod.example.com"
        port     = 5432
        database = "appdb"
        username = "app_user"
      }
    }
  ])
}
Attribute Type Required Description
id string Computed Rotation config UUID.
secret_id string Yes Secret to rotate.
environment string Yes Environment this config applies to.
ttl_hours number Yes Rotation interval in hours.
rotation_strategy string No rolling, immediate, or blue-green.
target_environment string No Override write-back environment. Defaults to environment.
scope string No project (default) or organization.
grace_period_minutes number No Minutes the old credential stays valid after rotation (0 = hard cutover).
workflow_steps_json string No JSON array of rotation step configurations.

mazevault_rotation_workflow

Creates a rotation workflow directly for a secret (simpler alternative to mazevault_rotation_config when only one workflow is needed).

resource "mazevault_rotation_workflow" "api_key" {
  secret_id   = mazevault_secret.api_key.id
  environment = "production"
  schedule    = "0 2 * * 1"  # Every Monday at 02:00
}
Attribute Type Required Description
id string Computed Workflow UUID.
secret_id string Yes Secret this workflow rotates.
environment string Yes Target environment.
schedule string No Cron schedule for automatic rotation.

mazevault_certificate

Manages a certificate issued by or tracked in MazeVault. The private key is computed (generated by MazeVault) and exposed as a sensitive Terraform output.

resource "mazevault_certificate" "tls" {
  common_name               = "api.example.com"
  ttl                       = "8760h"    # 1 year
  key_size                  = 4096
  organization_ca_account_id = var.ca_account_id
}

output "tls_cert_pem" {
  value     = mazevault_certificate.tls.certificate_pem
  sensitive = false
}

output "tls_key_pem" {
  value     = mazevault_certificate.tls.private_key_pem
  sensitive = true
}
Attribute Type Required Description
id string Computed Certificate UUID.
common_name string Yes Certificate CN (e.g. api.example.com).
ttl string No Validity duration (Go duration string: 8760h, 365d).
key_size number No RSA key size in bits (default: 2048).
organization_ca_account_id string No CA account for automatic issuance and rotation.
serial_number string Computed Certificate serial number.
certificate_pem string Computed PEM-encoded certificate.
private_key_pem string Computed PEM-encoded private key. Sensitive.
status string Computed pending, issued, expired, revoked.
expires_at string Computed Expiry timestamp.

mazevault_certificate_template

Defines a reusable certificate issuance policy: key usage, extended key usage, SANs, validity, and CA account binding.

resource "mazevault_certificate_template" "web_tls" {
  project_id = mazevault_project.backend.id
  name       = "Web TLS 1Y"
  ca_account_id = var.ca_account_id
  ttl_hours  = 8760
  key_type   = "RSA"
  key_size   = 2048
}
Attribute Type Required Description
id string Computed Template UUID.
project_id string Yes Owning project.
name string Yes Template name.
ca_account_id string No Bound CA account ID.
ttl_hours number No Default certificate validity in hours.
key_type string No RSA or EC.
key_size number No Key size (bits for RSA, curve size for EC).

mazevault_ca

Registers a CA account (DigiCert, Venafi, ADCS, ACME, Vault PKI, etc.) within a project.

resource "mazevault_ca" "digicert" {
  project_id = mazevault_project.backend.id
  name       = "DigiCert Production"
  provider_type = "digicert"
  config = {
    api_key        = var.digicert_api_key
    organization_id = "12345"
  }
}
Attribute Type Required Description
id string Computed CA account UUID.
project_id string Yes Owning project.
name string Yes Descriptive name.
provider_type string Yes digicert, venafi, adcs, acme, vault, step, est, psd2.
config map(string) No Provider-specific configuration (API keys, URLs). Sensitive.

mazevault_integration

Connects MazeVault to an external secrets store or deployment target (Azure Key Vault, AWS Secrets Manager, Kubernetes, GCP Secret Manager, etc.).

resource "mazevault_integration" "azure_kv" {
  project_id = mazevault_project.backend.id
  name       = "Production Azure Key Vault"
  type       = "azure_key_vault"
  config = {
    vault_url    = "https://prod-vault.vault.azure.net"
    tenant_id    = var.tenant_id
    client_id    = var.client_id
    use_managed_identity = "true"
  }
}
Attribute Type Required Description
id string Computed Integration UUID.
project_id string Yes Owning project.
name string Yes Integration name.
type string Yes azure_key_vault, aws_secrets_manager, kubernetes, gcp_secret_manager, hashicorp_vault.
config map(string) No Provider-specific configuration.

mazevault_integration_group

Groups multiple integrations mapped to different environments. Useful for multi-region or multi-KeyVault scenarios where the same logical secret must be written to different backends depending on environment.

resource "mazevault_integration_group" "multi_env_kv" {
  project_id  = mazevault_project.backend.id
  name        = "Multi-Region Key Vaults"
  description = "Routes secrets to the correct regional Azure Key Vault"

  mappings {
    integration_id = mazevault_integration.azure_kv_eu.id
    environment    = "production-eu"
    priority       = 1
  }

  mappings {
    integration_id = mazevault_integration.azure_kv_us.id
    environment    = "production-us"
    priority       = 1
  }
}
Attribute Type Required Description
id string Computed Group UUID.
project_id string Yes Owning project.
name string Yes Group name.
description string No Optional description.

mappings block

Attribute Type Required Description
integration_id string Yes Integration to assign to this environment slot.
environment string Yes Environment label (dev, staging, production-eu, …).
priority number No Priority for failover. Lower = higher priority.

mazevault_consistency_group

Validates that a set of secret keys exist with matching values across multiple environments. MazeVault continuously monitors the group and raises alerts when inconsistencies are detected.

resource "mazevault_consistency_group" "db_creds" {
  project_id   = mazevault_project.backend.id
  name         = "Database Credentials Parity"
  description  = "Ensure DB creds are consistent across staging and production"
  secret_keys  = ["DB_HOST", "DB_PORT", "DB_NAME"]
  environments = ["staging", "production"]
}
Attribute Type Required Description
id string Computed Group UUID.
project_id string Yes Owning project.
name string Yes Group name.
description string No Description.
secret_keys list(string) Yes Secret keys to monitor for consistency.
environments list(string) Yes Environments to compare.

mazevault_role

Creates a custom RBAC role with a specific permission set.

resource "mazevault_role" "deploy_bot" {
  name        = "deploy-bot"
  description = "Read-only access for deployment pipelines"
  permissions = ["secrets:read", "certificates:read", "projects:read"]
}
Attribute Type Required Description
id string Computed Role UUID.
name string Yes Role name (unique within organization).
description string No Description.
permissions list(string) Yes Permission strings (e.g. secrets:read, certificates:write).

mazevault_group_mapping

Maps an external identity provider group (Entra ID, LDAP, SCIM) to a MazeVault RBAC role.

resource "mazevault_group_mapping" "ops_team" {
  external_group_id = "sg-ops-production"
  role_id           = mazevault_role.deploy_bot.id
  provider_type     = "entra"
}
Attribute Type Required Description
id string Computed Mapping UUID.
external_group_id string Yes External group identifier (Entra object ID, LDAP DN, SCIM group name).
role_id string Yes Target MazeVault role.
provider_type string No entra, ldap, scim.

mazevault_service_identity

Creates a service account (machine identity) with its own client_id and client_secret for non-human CI/CD access.

resource "mazevault_service_identity" "ci_pipeline" {
  display_name = "GitHub Actions CI"
  description  = "Read-only service account for deployment pipeline"
  owner_email  = "platform-team@example.com"
}

output "ci_client_id" {
  value = mazevault_service_identity.ci_pipeline.client_id
}

output "ci_client_secret" {
  value     = mazevault_service_identity.ci_pipeline.client_secret
  sensitive = true
}
Attribute Type Required Description
id string Computed Service identity UUID.
display_name string Yes Human-readable name.
description string No Description.
owner_email string Yes Contact email for the owning team.
client_id string Computed OAuth2 client ID.
client_secret string Computed OAuth2 client secret. Sensitive.

mazevault_api_token

Creates a personal or service API token with granular scope.

resource "mazevault_api_token" "automation" {
  name   = "terraform-automation"
  scopes = ["secrets:read", "certificates:read", "rotation:write"]
}
Attribute Type Required Description
id string Computed Token UUID.
name string Yes Token name.
scopes list(string) Yes Permission scopes.
token string Computed The raw token value. Sensitive. Only available at creation.

Data Sources

mazevault_consistency_status

Reads the current consistency status of a project's consistency groups.

data "mazevault_consistency_status" "check" {
  project_id = mazevault_project.backend.id
}

output "consistency_ok" {
  value = data.mazevault_consistency_status.check.status == "healthy"
}
Attribute Type Description
project_id string Project to query.
status string healthy, warning, or error.
missing_count number Number of missing secrets detected.
issues list(string) Human-readable list of consistency issues.

mazevault_project_certificates

Lists all certificates in a project.

data "mazevault_project_certificates" "all" {
  project_id = mazevault_project.backend.id
}
Attribute Type Description
project_id string Project to query.
certificates list(object) List of certificate summaries (id, common_name, status, expires_at).

mazevault_project_cas

Lists CA accounts registered in a project.

data "mazevault_project_cas" "available" {
  project_id = mazevault_project.backend.id
}

mazevault_project_certificate_templates

Lists certificate templates available in a project.

data "mazevault_project_certificate_templates" "templates" {
  project_id = mazevault_project.backend.id
}

mazevault_project_csrs

Lists pending Certificate Signing Requests in a project.

data "mazevault_project_csrs" "pending" {
  project_id = mazevault_project.backend.id
}

Complete Example

The following example provisions a fully automated secret rotation pipeline for a PostgreSQL password in production.

terraform {
  required_providers {
    mazevault = {
      source  = "MazeVault/mazevault"
      version = "~> 1.0"
    }
  }
}

provider "mazevault" {
  server_url = var.mazevault_url
  api_token  = var.mazevault_token
}

resource "mazevault_organization" "acme" {
  name = "Acme Corp"
}

resource "mazevault_project" "backend" {
  organization_id = mazevault_organization.acme.id
  name            = "Backend Services"
  environment     = "production"
}

resource "mazevault_integration" "azure_kv" {
  project_id = mazevault_project.backend.id
  name       = "Production Key Vault"
  type       = "azure_key_vault"
  config = {
    vault_url            = var.keyvault_url
    use_managed_identity = "true"
  }
}

resource "mazevault_secret" "db_password" {
  project_id  = mazevault_project.backend.id
  key         = "POSTGRES_PASSWORD"
  value       = var.initial_db_password
  environment = "production"

  rotation {
    enabled       = true
    interval_days = 30
    notification_emails = ["dba@example.com"]
  }
}

resource "mazevault_secret_link" "db_link" {
  secret_id      = mazevault_secret.db_password.id
  integration_id = mazevault_integration.azure_kv.id
  link_type      = "database"
  metadata = {
    db_user = "app_user"
    db_host = "db.prod.example.com"
    db_name = "appdb"
  }
}

resource "mazevault_rotation_config" "db" {
  secret_id             = mazevault_secret.db_password.id
  environment           = "production"
  ttl_hours             = 720
  rotation_strategy     = "rolling"
  grace_period_minutes  = 60
  workflow_steps_json   = jsonencode([
    {
      type   = "connection_validation"
      config = { integration_id = mazevault_integration.azure_kv.id }
    },
    {
      type   = "postgres_rotation"
      config = {
        host     = "db.prod.example.com"
        port     = 5432
        database = "appdb"
        username = "app_user"
      }
    }
  ])
}

resource "mazevault_consistency_group" "prod_creds" {
  project_id   = mazevault_project.backend.id
  name         = "Production DB Credentials"
  secret_keys  = ["POSTGRES_PASSWORD", "POSTGRES_HOST", "POSTGRES_PORT"]
  environments = ["staging", "production"]
}

Importing Existing Resources

Use terraform import to bring existing MazeVault resources under Terraform management:

# Import a secret
terraform import mazevault_secret.db_password <secret-uuid>

# Import a project
terraform import mazevault_project.backend <project-uuid>

# Import a certificate
terraform import mazevault_certificate.tls <certificate-uuid>

# Import an integration group
terraform import mazevault_integration_group.multi_env_kv <group-uuid>

Resource UUIDs are visible in the MazeVault UI (URL path) or via the REST API (GET /api/v1/...).


Best Practices

  • Store state remotely — use Terraform Cloud, Azure Blob Storage, or AWS S3 with state locking enabled.
  • Mark sensitive outputs — always add sensitive = true on any output that exposes secret values or private keys.
  • Use variables for credentials — inject api_token, client_secret, and CA credentials via TF_VAR_ environment variables or a CI/CD secrets store, never in .tfvars files committed to source control.
  • Pin provider versions — use ~> 1.0 to allow patch updates while preventing unexpected major-version changes.
  • Use consistency groups for drift detection — after provisioning, add a mazevault_consistency_group to catch environment drift before it becomes an incident.
  • Rotation grace periods — always set grace_period_minutes > 0 for database rotations to allow in-flight connections to finish before the old credential is invalidated.
  • Separate workspaces per environment — use Terraform workspaces or separate state files per environment (dev/staging/production) to prevent accidental cross-environment resource writes.