ポリシー

Sentinel Policies

Vault EnterpriseのPolicy as Code機能
最終更新: 2026/4/13

Sentinel Policies

Enterprise版の機能Sentinel Policiesは、Vault Enterprise版でのみ利用可能な機能です。本機能の詳細やライセンスについては、IBMの営業担当者にお問い合わせください。

Sentinel Policiesとは

Sentinel Policiesは、HashiCorpのポリシーアズコード(Policy as Code)フレームワークであるSentinelを使用した、高度なポリシー制御機能です。通常のVaultポリシー(ACLポリシー)よりも柔軟で強力なルールを定義できます。

通常のポリシーとの違い

特徴ACLポリシーSentinel Policies
言語HCLSentinel言語
制御パスベース条件ベース
複雑な条件限定的高度な条件分岐
時間制御
外部データ
エンフォースメントレベルなし3段階

Sentinelの基本概念

エンフォースメントレベル

Sentinel Policiesには3つのエンフォースメントレベルがあります。

1. advisory(助言)

  • ポリシー違反時に警告を表示
  • 操作は許可される
  • 監査目的に使用

2. soft-mandatory(ソフト必須)

  • ポリシー違反時に操作を拒否
  • 上位権限者はオーバーライド可能
  • 承認ワークフローと組み合わせて使用

3. hard-mandatory(ハード必須)

  • ポリシー違反時に操作を拒否
  • オーバーライド不可
  • 最も厳格な制御

Sentinel言語の基本

Sentinel言語は、ポリシーを記述するための専用言語です。

# 基本的な構文
import "time"
import "strings"

# ルールの定義
main = rule {
    time.now.weekday not in ["saturday", "sunday"]
}

Sentinel Policiesの作成

例1: 営業時間外のアクセス制限

営業時間外(平日18時以降、土日)のシークレットアクセスを制限します。

business-hours.sentinel:

import "time"

# 営業時間の定義
business_start = 9
business_end = 18

# 現在時刻の取得
hour = time.now.hour
weekday = time.now.weekday

# 営業時間内かチェック
is_business_hours = rule {
    weekday not in ["saturday", "sunday"] and
    hour >= business_start and
    hour < business_end
}

# メインルール
main = rule {
    is_business_hours
}

例2: 本番環境への書き込み制限

本番環境のシークレットへの書き込みを特定のユーザーのみに制限します。

prod-write-restriction.sentinel:

import "strings"

# リクエストパスの取得
request_path = request.path

# 本番環境のパスかチェック
is_prod_path = rule {
    strings.has_prefix(request_path, "secret/data/prod/")
}

# 許可されたユーザー
allowed_users = [
    "admin",
    "prod-deployer",
]

# ユーザーチェック
is_allowed_user = rule {
    request.entity.name in allowed_users
}

# メインルール: 本番環境の場合は許可ユーザーのみ
main = rule when is_prod_path {
    is_allowed_user
}

例3: シークレットの有効期限制限

動的シークレットのTTLを制限します。

ttl-limit.sentinel:

import "strings"

# リクエストデータの取得
ttl = request.data.ttl else 0

# 最大TTL(秒)
max_ttl = 3600  # 1時間

# TTLチェック
main = rule {
    ttl <= max_ttl
}

例4: MFA必須化

特定のパスへのアクセスにMFAを必須化します。

mfa-required.sentinel:

import "strings"

# リクエストパスの取得
request_path = request.path

# 機密パスの定義
sensitive_paths = [
    "secret/data/prod/",
    "secret/data/finance/",
]

# 機密パスかチェック
is_sensitive = rule {
    any sensitive_paths as path {
        strings.has_prefix(request_path, path)
    }
}

# MFAが使用されているかチェック
has_mfa = rule {
    length(request.mfa_credentials) > 0
}

# メインルール: 機密パスの場合はMFA必須
main = rule when is_sensitive {
    has_mfa
}

Sentinel Policiesの適用

ポリシーのアップロード

# Sentinelポリシーの作成
vault write sys/policies/egp/business-hours \
    policy=@business-hours.sentinel \
    enforcement_level="soft-mandatory" \
    paths="secret/data/*"

パラメータ

  • policy: Sentinelポリシーの内容
  • enforcement_level: エンフォースメントレベル(advisory/soft-mandatory/hard-mandatory)
  • paths: ポリシーを適用するパス(ワイルドカード使用可能)

ポリシーの一覧表示

# EGP(Endpoint Governing Policies)の一覧
vault list sys/policies/egp

# 特定ポリシーの詳細
vault read sys/policies/egp/business-hours

ポリシーの更新

# ポリシーの更新
vault write sys/policies/egp/business-hours \
    policy=@business-hours-updated.sentinel \
    enforcement_level="hard-mandatory" \
    paths="secret/data/*"

ポリシーの削除

# ポリシーの削除
vault delete sys/policies/egp/business-hours

高度な使用例

例5: 複数条件の組み合わせ

複数の条件を組み合わせた複雑なポリシーです。

advanced-policy.sentinel:

import "time"
import "strings"

# 現在時刻
hour = time.now.hour
weekday = time.now.weekday

# リクエスト情報
request_path = request.path
user_name = request.entity.name
operation = request.operation

# 営業時間
is_business_hours = rule {
    weekday not in ["saturday", "sunday"] and
    hour >= 9 and hour < 18
}

# 本番環境
is_prod = rule {
    strings.has_prefix(request_path, "secret/data/prod/")
}

# 管理者
is_admin = rule {
    user_name in ["admin", "security-admin"]
}

# 読み取り操作
is_read = rule {
    operation == "read"
}

# ルール1: 本番環境への書き込みは営業時間内のみ
prod_write_rule = rule when is_prod and not is_read {
    is_business_hours or is_admin
}

# ルール2: 本番環境の読み取りは常に許可
prod_read_rule = rule when is_prod and is_read {
    true
}

# メインルール
main = rule {
    prod_write_rule and prod_read_rule
}

例6: 外部データの使用

HTTPリクエストで外部APIからデータを取得します。

external-validation.sentinel:

import "http"
import "json"

# 外部APIでユーザーを検証
validate_user = func(username) {
    resp = http.get("https://api.example.com/validate/" + username)
    
    if resp.status_code == 200 {
        data = json.unmarshal(resp.body)
        return data.is_valid
    }
    
    return false
}

# ユーザー名の取得
username = request.entity.name

# メインルール
main = rule {
    validate_user(username)
}

例7: カスタムメッセージ

ポリシー違反時にカスタムメッセージを表示します。

custom-message.sentinel:

import "time"

hour = time.now.hour

# 営業時間チェック
is_business_hours = rule {
    hour >= 9 and hour < 18
}

# メインルール(カスタムメッセージ付き)
main = rule {
    is_business_hours else "アクセスは営業時間内(9:00-18:00)のみ許可されています"
}

Sentinel関数とインポート

利用可能なインポート

インポート説明主な機能
time時間関連現在時刻、日付操作
strings文字列操作前方一致、後方一致、分割
httpHTTPリクエストGET、POST、認証
jsonJSON操作パース、マーシャル
decimal数値計算高精度計算

よく使う関数

# 文字列操作
strings.has_prefix(str, prefix)
strings.has_suffix(str, suffix)
strings.contains(str, substr)
strings.split(str, sep)

# リスト操作
length(list)
any list as item { condition }
all list as item { condition }

# 時間操作
time.now.hour
time.now.weekday
time.now.unix

テストとデバッグ

ポリシーのテスト

# テスト用のリクエストを送信
vault write secret/data/prod/myapp \
    data=@data.json

# ポリシー違反の場合のエラー例
Error writing data to secret/data/prod/myapp: Error making API request.

URL: PUT https://vault.example.com:8200/v1/secret/data/prod/myapp
Code: 403. Errors:

* 1 error occurred:
    * business-hours: アクセスは営業時間内(9:00-18:00)のみ許可されています

デバッグ

Sentinelポリシーにprintステートメントを追加してデバッグできます。

import "time"

hour = time.now.hour
print("Current hour:", hour)

main = rule {
    hour >= 9 and hour < 18
}

ベストプラクティス

1. 段階的な導入

最初はadvisoryレベルで導入し、影響を確認してからsoft-mandatory、hard-mandatoryに移行します。

# Phase 1: Advisory(警告のみ)
vault write sys/policies/egp/new-policy \
    policy=@policy.sentinel \
    enforcement_level="advisory" \
    paths="secret/data/*"

# Phase 2: Soft-mandatory(オーバーライド可能)
vault write sys/policies/egp/new-policy \
    enforcement_level="soft-mandatory"

# Phase 3: Hard-mandatory(オーバーライド不可)
vault write sys/policies/egp/new-policy \
    enforcement_level="hard-mandatory"

2. 明確なエラーメッセージ

ユーザーが理解しやすいエラーメッセージを提供します。

main = rule {
    condition else "具体的なエラーメッセージ: 何が問題で、どうすれば解決できるか"
}

3. パフォーマンスの考慮

外部APIへのリクエストは最小限に抑えます。

# 悪い例: 毎回APIリクエスト
main = rule {
    http.get("https://api.example.com/check").status_code == 200
}

# 良い例: 条件付きでAPIリクエスト
main = rule {
    not is_sensitive_operation or
    http.get("https://api.example.com/check").status_code == 200
}

4. ドキュメント化

ポリシーの目的と動作を明確にドキュメント化します。

# ポリシー名: 本番環境書き込み制限
# 目的: 本番環境への意図しない変更を防止
# 適用範囲: secret/data/prod/*
# エンフォースメントレベル: hard-mandatory
# 作成日: 2024-01-15
# 作成者: Security Team

import "strings"

# ... ポリシーの内容 ...

次のステップ

Sentinel Policiesの基本を理解したら、次は以下を学びましょう:

Sentinel Policiesの重要性Sentinel Policiesは、エンタープライズ環境でのガバナンスとコンプライアンスを実現する強力なツールです。適切に設計することで、セキュリティを大幅に向上させることができます。
© 2026 IBM Corporation. Licensed under CC BY 4.0.