Skip to content

Terraform / OpenTofu provider for Cosmian KMS #885

@Manuthor

Description

@Manuthor

Summary

Publish a Terraform / OpenTofu provider for Cosmian KMS so that DevOps and platform engineering teams can manage KMS resources (keys, key pairs, certificates, access rights) as infrastructure-as-code, with full GitOps support.

Impact

  • Without a Terraform provider, KMS resources must be created manually or via custom scripts, leading to configuration drift and audit gaps
  • DevOps-first organizations evaluate KMS products based on IaC support before any other criterion
  • No Terraform provider prevents GitOps workflows for key lifecycle management
  • Blocks adoption in environments where all infrastructure is declared in version-controlled Terraform code

Deliverable

New external Go repository cosmian/terraform-provider-kms (Terraform Plugin Framework v2 + Go 1.22+). Published to the Terraform Registry under the cosmian namespace.

Implementation plan

Authentication

The provider authenticates to the KMS server using one of:

  • API keyAuthorization: Bearer <token> header (configured via api_key or COSMIAN_KMS_API_KEY env var)
  • mTLS client certificatetls_cert_file + tls_key_file provider arguments
provider "cosmian-kms" {
  server_url = "https://kms.example.com:9998"
  api_key    = var.kms_api_key     # or use COSMIAN_KMS_API_KEY env var
  # tls_cert_file = "/etc/kms/client.crt"
  # tls_key_file  = "/etc/kms/client.key"
  # ca_cert_file  = "/etc/kms/ca.pem"
}

The provider constructs standard KMIP-over-HTTP requests — the same JSON API that cosmian_kms_client uses.

Resources

cosmian_kms_symmetric_key

Maps to KMIP Create (create) / GetAttributes (read) / Destroy (delete). Rotation triggers a new Create with matching attributes and updates the Terraform state ID to the new UID.

resource "cosmian_kms_symmetric_key" "data_key" {
  algorithm       = "AES"
  key_length_bits = 256
  name            = "database-encryption-key"
  tags            = ["env=prod", "team=data"]
}

cosmian_kms_key_pair

Maps to KMIP CreateKeyPair (create) / GetAttributes (read) / Destroy for both private and public key UIDs.

resource "cosmian_kms_key_pair" "signing_pair" {
  algorithm       = "RSA"
  key_length_bits = 4096
  name            = "code-signing"
}
output "public_key_uid" { value = cosmian_kms_key_pair.signing_pair.public_key_uid }

cosmian_kms_certificate

Maps to KMIP Import + Certify (create) / Get (read) / Destroy (delete).

resource "cosmian_kms_certificate" "internal_ca" {
  subject_name   = "CN=Internal CA,O=Example,C=FR"
  key_pair_uid   = cosmian_kms_key_pair.ca_pair.private_key_uid
  is_ca          = true
  validity_days  = 3650
}

cosmian_kms_access_right

Maps to the KMS access-right grant/revoke REST endpoint (POST /access/grant / DELETE /access/revoke).

resource "cosmian_kms_access_right" "alice_can_decrypt" {
  object_uid  = cosmian_kms_symmetric_key.data_key.id
  user_id     = "alice@example.com"
  operations  = ["Decrypt", "Get"]
}

Data sources

Each resource has a corresponding data source for importing pre-existing objects:

data "cosmian_kms_symmetric_key" "existing" {
  unique_identifier = "550e8400-e29b-41d4-a716-446655440000"
}

Import support

terraform import cosmian_kms_symmetric_key.data_key 550e8400-e29b-41d4-a716-446655440000
terraform import cosmian_kms_key_pair.signing_pair private_uid:public_uid

State management

The Terraform resource ID is the KMS object UID returned by the Create/CreateKeyPair/Import response. On terraform destroy, the provider calls Destroy on the UID. On terraform refresh, it calls GetAttributes and compares key attributes.

Acceptance tests

The provider's acceptance test suite starts a local KMS server (SQLite, no auth), then:

  • Creates each resource type, verifies attributes via GetAttributes
  • Verifies destroy removes the object (server returns ItemNotFound)
  • Verifies import works for all resource types
  • Tests access right grant and revoke

GitHub Actions CI matrix: fips + non-fips KMS server variants.

Repository structure

cosmian/terraform-provider-kms/
  internal/
    provider/   ← provider config, authentication client
    resources/  ← one file per resource type
    datasources/
  examples/     ← usage examples
  docs/         ← generated from schema using tfplugindocs
  GNUmakefile
  .github/workflows/
    test.yml    ← acceptance tests
    release.yml ← GoReleaser + registry publish

Acceptance criteria

  • terraform apply with all four resource types succeeds against a local KMS server.
  • terraform destroy removes all created objects.
  • terraform import successfully brings an existing KMS object into Terraform state.
  • Provider is published to registry.terraform.io under cosmian/kms.
  • API key and mTLS authentication both work.

Effort: Medium (4–6 weeks, new repo) | No prerequisites

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions