HashiCorop Sentinelを使って特定のTerraformプロバイダーのみ利用を許可する

HashiCorop Sentinelを使って特定のTerraformプロバイダーのみ利用を許可する

2025.08.07

組織でTerraformを利用していると、信頼できるプロバイダーのみに利用を制限したいことがあります。

悪意のあるプロバイダーの利用には、セキュリティ的なリスクがあるためです。

利用者がTerraform Registryでプロバイダーの情報を確認することでリスクは下がりますが、仕組みとしてカバーしたいものです。

以下のブログでSentinelを利用して、Terraformプライベートモジュールの使用を強制する方法について紹介されていました。

Enforce private module registry usage in Terraform with Sentinel

今回はブログと同じくSentinelを使って利用できるプロバイダーを制限する方法についてを紹介します。

Sentinelファイルの用意

GitHubのpolicy-library-tfe-terraformリポジトリでよく使われるSentinelファイルが公開されています。

providers-allowlist.sentinelを利用します。以下のファイルを用意します。

tfe/files/providers-allowlist.sentinel
# This policy blocks Terraform Apply when a provider not listed in the `allowed_providers` parameter is detected in the configuration.
# NOTE: this policy should not be considered as full mitigation against threats from potentially malicious providers, due to the fact that provider code is executed during the plan phase. This policy is intended to provide a basic level of protection against accidental use of disallowed providers.

import "tfconfig/v2" as tfconfig

param allowed_providers default ["registry.terraform.io/hashicorp/aws"]

violating_providers = filter tfconfig.providers as _, p {
	p.full_name not in allowed_providers
}

if length(violating_providers) > 0 {
	print("These providers are not allowed:")
	for violating_providers as _, p {
		print(" - " + _ + " (" + p.full_name + ")")
	}
}

main = rule {
	length(violating_providers) == 0
}

tfconfig/v2でプロバイダーの情報を取得しています。

tfconfig.providers.full_nameでプロバイダー名を取得できます。(例: registry.terraform.io/hashicorp/aws)

Sentinelのfilter関数で、許可されていないプロバイダーをviolating_providers変数に入れています。

violating_providersを使って、許可されていないプロバイダーを出力しています。

mainはSentinelポリシーのエントリーポイントになっていて、ここがtrueになればポリシーはパスとなります。

mainruleで定義する必要があり、rule内ではviolating_providersが空の場合にtrueを返すように設定しています。(= 許可されていないプロバイダーの数が0)

tfconfig/v2 Sentinel import | Terraform | HashiCorp Developer

Writing Sentinel Policy | Sentinel | HashiCorp Developer

SentinelポリシーをHCP Terraformにデプロイする

tfe providerを使って、HCP TerraformにPolicyとPolicy Setをデプロイします。

今回はawsとtfe providerの利用を許可するように、ポリシーにパラメータを設定しています。

同時に動作確認用のWorkspaceも用意します。

以下のファイルを用意します。<HCP Terraform Organization名><HCP Terraform Project名>はそれぞれの環境にあわせて置き換えてください。

tfe/main.tf

terraform {
  required_providers {
    tfe = {
      source  = "hashicorp/tfe"
      version = "0.68.2"
    }
  }
  cloud {
    organization = "<HCP Terraform Organization名>"
    workspaces {
      name    = "providers-allowlist-sentinel"
      project = "<HCP Terraform Project名>"
    }
  }
}

provider "tfe" {}

variable "organization_name" {
  type = string
}

variable "project_name" {
  type = string
}

data "tfe_project" "this" {
  name         = var.project_name
  organization = var.organization_name
}

resource "tfe_policy" "this" {
  enforce_mode = "hard-mandatory"
  kind         = "sentinel"
  name         = "providers-allowlist"
  organization = var.organization_name
  policy       = file("${path.module}/files/providers-allowlist.sentinel")
}

# ポリシー動作確認用ワークスペース
resource "tfe_workspace" "this" {
  name         = "providers-allowlist-test"
  organization = var.organization_name
  project_id   = data.tfe_project.this.id
}

resource "tfe_policy_set" "this" {
  name          = "providers-allowlist"
  organization  = var.organization_name
  kind          = "sentinel"
  agent_enabled = "true"
  policy_ids    = [tfe_policy.this.id]
  workspace_ids = [tfe_workspace.this.id]
}

# tfeとawsプロバイダーを許可
resource "tfe_policy_set_parameter" "this" {
  key           = "allowed_providers"
  value         = "[registry.terraform.io/hashicorp/aws, registry.terraform.io/hashicorp/tfe]"
  policy_set_id = tfe_policy_set.this.id
}

以下のファイルを用意して、値を環境に合わせて修正します。

terraform.tfvars
organization_name = "<HCP Terraform Organizations名>"
project_name      = "<HCP Terraform Project名>"

Terraformを実行してリソースを作成します。

terraform init
terraform plan
terraform apply

HCP Terraformのコンソール上でも、ポリシーセット等が作成されていることを確認できます。

providers-allowlist___Policy_Set___classmethod-sandbox___HCP_Terraform.png

動作確認

動作確認用にポリシーがアタッチされたWorkspaceでTerraformを実行します。

以下のファイルを準備します。

aws/main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "6.7.0"
    }
    tfe = {
      source  = "hashicorp/tfe"
      version = "0.68.2"
    }
    local = {
      source  = "hashicorp/local"
      version = "2.5.3"
    }
  }
  cloud {
    organization = "<HCP Terraform Organization名>"
    workspaces {
      name    = "providers-allowlist-test"
      project = "<HCP Terraform Project名>"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

resource "aws_vpc" "this" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = {
    Name = "providers-allowlist-test"
  }
}

今回providerを3つ指定しています。

  • aws: 許可している
  • tfe: 許可している
  • local: 許可していない

ポリシーで許可していないlocalproviderも含んでいます。

Terraformを実行します。

terraform init
terraform plan

ポリシーで許可されていないproviderが含まれているためplanが失敗します。

terraform planの出力
→ Policy set 3: providers-allowlist (1)
  ↳ Policy name: providers-allowlist-tf.sentinel
     | × Failed
     | This policy blocks Terraform Apply when a provider not listed in the `allowed_providers` parameter is detected in the configuration.
NOTE: this policy should not be considered as full mitigation against threats from potentially malicious providers, due to the fact that provider code is executed during the plan phase. This policy is intended to provide a basic level of protection against accidental use of disallowed providers.
╷
│ Error: Task Stage failed.

run-7AttbCBZ41kUtLPi___Runs___classmethod-sandbox___HCP_Terraform.png

aws/main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "6.7.0"
    }
    tfe = {
      source  = "hashicorp/tfe"
      version = "0.68.2"
    }
-    local = {
-      source  = "hashicorp/local"
-      version = "2.5.3"
-    }
  }
  ...
}

local プロバイダーを削除して再度planを実行します。

terraform plan

許可されたプロバイダー以外が含まれていないため、ポリシーがパスになりました。

出力例
→ Policy set 3: providers-allowlist (1)
  ↳ Policy name: providers-allowlist.sentinel
     | ✓ Passed

run-y1v2KHRnHLvimuS5___Runs___classmethod-sandbox___HCP_Terraform.png

Tips: 悪意のあるプロバイダーの動作を完全に防ぐのは難しい

SentinelはPlanの後に実行されます。

そのため、悪意のあるプロバイダーがPlanフェーズ中に動作するようなものであった場合、この動作を防ぐことはできません。

コードレビューやPlanの権限を最小化する等、他の対策も合わせて検討していきたいところです。

おわりに

Sentinelを利用して利用可能なTerraformプロバイダーを制限する方法でした。

シンプルな設定で許可されていないプロバイダーの利用を防ぐことができます。

GitHubのプロバイダーだけでも検索すると以下のようにたくさん出てきます。

Search__terraform-provider-github___Terraform_Registry_と_2ut78DGw07lJ7ALNkKz4VG_md_—_devio.png

慣れていないと適切なプロバイダーを選ぶのは難しいかもしれません。

ポリシーを適用することで、組織として不適切なプロバイダーの利用を制限できます。

この記事をシェアする

facebookのロゴhatenaのロゴtwitterのロゴ

© Classmethod, Inc. All rights reserved.