terraform-provider-misp

command module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 24, 2026 License: MPL-2.0 Imports: 6 Imported by: 0

README

Terraform Provider for MISP

Tests Go Reference Go version

Manage a MISP instance — the open-source threat intelligence and sharing platform — as code.

  • 14 resources covering organisations, users, roles, tags, taxonomies, sharing groups (with org and server membership), feeds, sync servers, warninglists, noticelists, global settings, and custom galaxy clusters.
  • 12 data sources for reading existing configuration.
  • Built on terraform-plugin-framework (protocol v6).
  • Tested against MISP 2.5.x.

Scope. This provider manages MISP configuration — the long-lived administrative state that an operator maintains in git. Events, attributes, sightings, analyst notes, correlations, and other operational data are deliberately out of scope and will not be added. Use PyMISP or the MISP UI for analyst workflows. See CLAUDE.md for the full scope rationale.

Requirements

  • Terraform ≥ 1.6
  • A running MISP instance (2.5.x tested) and an API key with admin scope
  • Go ≥ 1.24 only if building from source

Quick start

terraform {
  required_providers {
    misp = {
      source  = "Scriptception/misp"
      version = "~> 0.1"
    }
  }
}

provider "misp" {
  url     = "https://misp.example.com"
  api_key = var.misp_api_key   # or set MISP_API_KEY
  # insecure = true            # for self-signed certs; or set MISP_INSECURE=true
}

Provider settings also accept environment variables: MISP_URL, MISP_API_KEY, MISP_INSECURE.

Walkthrough

A realistic slice of what you might declare for a small threat-sharing setup: a local org, a partner org, a custom tag, a sharing group joining the two, a user, and a CIRCL OSINT feed subscription.

# 1. Your own organisation (the "local" one — owns events created on this instance).
resource "misp_organisation" "acme" {
  name        = "ACME"
  description = "ACME Corp threat intel team"
  type        = "CSIRT"
  nationality = "AU"
  local       = true
}

# 2. A partner org you share with (remote = local=false).
resource "misp_organisation" "partner" {
  name        = "Partner Inc"
  description = "External threat-sharing partner"
  local       = false
}

# 3. A custom tag for marking internally-sourced indicators.
resource "misp_tag" "internal" {
  name       = "source:internal"
  colour     = "#1f77b4"
  exportable = false
}

# 4. A sharing group that includes both orgs.
resource "misp_sharing_group" "partner_network" {
  name          = "ACME ↔ Partner"
  description   = "Bilateral sharing with Partner Inc"
  releasability = "Amber — partners only"
  org_id        = misp_organisation.acme.id
}

resource "misp_sharing_group_member" "acme_in_sg" {
  sharing_group_id = misp_sharing_group.partner_network.id
  organisation_id  = misp_organisation.acme.id
}

resource "misp_sharing_group_member" "partner_in_sg" {
  sharing_group_id = misp_sharing_group.partner_network.id
  organisation_id  = misp_organisation.partner.id
}

# 5. A human analyst account.
resource "misp_user" "alice" {
  email   = "alice@acme.example"
  org_id  = misp_organisation.acme.id
  role_id = "3"   # "User" — standard analyst role shipped by MISP
}

# 6. Subscribe to the CIRCL OSINT feed.
resource "misp_feed" "circl_osint" {
  name          = "CIRCL OSINT feed"
  provider_name = "CIRCL"
  url           = "https://www.circl.lu/doc/misp/feed-osint"
  source_format = "misp"
  enabled       = true
  caching_enabled = true
}

Apply that against a fresh MISP and you have a working cross-org sharing setup entirely in source control.

See examples/modules/bootstrap/ for a larger, runnable end-to-end module that you can use as a starting point for a new MISP instance.

Resources and data sources

Full reference docs live under docs/ and on the Terraform Registry once published. Quick index:

Resource What it manages
misp_organisation Orgs — the primary unit of ownership and access control.
misp_user User accounts (admin, org admin, sync user, analysts).
misp_role Custom permission roles.
misp_tag Tag catalog entries.
misp_taxonomy Enable/disable bundled taxonomies by namespace.
misp_warninglist Enable/disable bundled warninglists by name.
misp_noticelist Enable/disable bundled noticelists by name.
misp_sharing_group Sharing group definitions.
misp_sharing_group_member Organisation-in-sharing-group junction.
misp_sharing_group_server Server-in-sharing-group junction.
misp_feed Feed subscriptions.
misp_server Sync server peers.
misp_setting Global instance settings (MISP.baseurl, Security.*, …).
misp_galaxy_cluster Custom galaxy clusters (bundled clusters are read-only).

Every resource except misp_sharing_group_member and misp_sharing_group_server also exposes a matching data source (data.misp_<name>) for referencing existing records.

Authentication & secret handling

Create an API key in MISP: Administration → List Auth Keys → Add authentication key. Give it admin scope (required for most resources). Export it as MISP_API_KEY or pass it via the api_key attribute.

All secret-shaped attributes are marked Sensitive in the provider schema (provider.api_key, misp_server.authkey), so Terraform never prints them in plan/apply output. Don't hardcode them in .tf files — supply via:

  • environment variables (TF_VAR_peer_authkey=…, MISP_API_KEY=…)
  • terraform apply -var "..."
  • *.tfvars files kept out of git
  • a secrets backend such as HashiCorp Vault, SOPS, Doppler, or 1Password

Resource examples in examples/resources/ use variable "..." { sensitive = true } to demonstrate the right pattern.

Development

make build      # compile
make install    # go install to $GOBIN (for dev_overrides)
make test       # unit tests — fast, no network
make testacc    # acceptance tests — requires a live MISP instance (set MISP_URL / MISP_API_KEY / TF_ACC=1)
make generate   # regenerate docs/ from schema + examples/
make lint       # golangci-lint
make fmt        # gofmt

See CLAUDE.md for architecture notes, MISP API quirks, and conventions for adding a new resource.

Contributing

Issues and PRs welcome. If you're adding a new resource, please probe the MISP endpoints directly (curl or PyMISP) before coding — the OpenAPI spec is occasionally wrong, and envelope shapes vary between /add, /edit, and /view. CLAUDE.md documents the quirks worth knowing.

Follow the existing conventions: one file per resource, acceptance test covering create → update-in-place → import → destroy, matching data source, and example Terraform under examples/resources/<name>/.

License

Mozilla Public License 2.0.

Documentation

Overview

Command terraform-provider-misp is the Terraform provider for MISP.

Run with -debug to attach a debugger (e.g. delve). Run with -version to print build info and exit. Normally the provider is invoked by Terraform itself, not directly.

Directories

Path Synopsis
internal
client
Package client is a minimal HTTP client for the MISP REST API.
Package client is a minimal HTTP client for the MISP REST API.
provider
Package provider implements the MISP Terraform provider.
Package provider implements the MISP Terraform provider.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL