セキュリティ対策

サインイン、権限、シークレット、接続の保護方法

  1. 実行場所
  2. サインイン
  3. 権限
  4. 保存されたシークレット
  5. 監査証跡
  6. ブラウザー側
  7. サーバー側
  8. 接続
    1. 外部への接続
  9. コンテナー

実行場所

AnsibleForms はセルフホスト型で、お客様のインフラストラクチャ上で動作し、データはお客様が運用するデータベースに保存されます。

  • AnsibleForms のクラウドサービスやライセンスサーバーはなく、テレメトリや更新チェックもありません。
  • インターフェイスはアプリケーション自体が提供し、ほかのサイトから何も読み込みません。
  • アプリケーションが接続するのは、管理者が設定したシステムだけです。一覧は 外部への接続 にあります。

構成要素と、それぞれが保持するもの:

構成要素 役割 保持するもの
アプリケーション Web インターフェイス、REST API、スケジューラー 独自のデータはありません。すべてデータベースにあります
MySQL または MariaDB アプリケーションのデータベース ユーザー、グループ、認証情報 (暗号化済み)、extravars と出力を含むジョブ、監査ログ
ランタイム環境 (RTE) 専用のコンテナーで playbook を実行します 実行するジョブのファイルと、そのジョブの実行中だけ保持するシークレット
永続フォルダー 設定、フォーム、playbook、アップロード フォームと playbook が使うファイル

全体像は 動作のしくみ を、ランタイム環境については RTE を参照してください。


サインイン

データを読み取ったり変更したりするページと API 呼び出しには、すべてサインインしたユーザーが必要です。サインインなしで利用できる数少ないエンドポイントは、 サインイン自体、バージョン、インスタンスの名前とロゴ、API ドキュメント、初回起動時のデータベースセットアップを提供するもので、 最後のものは ALLOW_SCHEMA_CREATION=0 で閉じられます。

方式 しくみ
ローカルアカウント パスワードは bcrypt でハッシュ化され、 最小の長さ があり、公開されている既定の管理者パスワードは初回サインイン時に変更する必要があります
LDAP / Active Directory ディレクトリがパスワードをチェックし、そのグループがロールに対応付けられます。 LDAP を参照してください
OpenID Connect、Entra ID ID プロバイダーを通じたシングルサインオンで、プロバイダー独自の多要素認証も利用できます。 認証 を参照してください
  • サインインに失敗すると アカウントがロック され、サインインにはレート制限があります。
  • サインインすると、30 分間有効な署名付きアクセストークンと、24 時間有効なリフレッシュトークンが返されます。
  • トークンは有効期限前に終了させられます。サインアウト、パスワードの変更、ユーザーのブロック、API トークンの取り消しによって、 すべてのノードで同時に終了します。 トークン を参照してください。
  • AnsibleForms には独自の多要素認証はありません。必要な場合はシングルサインオンを使用してください。

権限

ユーザーができることは所属グループのロールで決まり、サーバーがリクエストごとにチェックします。

  • ロールは config.yaml で定義します。ユーザーに表示されるフォームと、デザイナー、設定ページ、 ほかのユーザーのジョブなど、ユーザーが持つオプションを決めます。
  • サーバーは、REST API を通じた起動も含め、すべての起動をフォームのルール (フィールド、その値、ユーザーのアクセス権) に照らしてチェックします。 起動時の検証 を参照してください。
  • 管理者ロールは、設計上どの playbook でも実行できます。ほかのロールには付与されたものだけが与えられます。複数のロールを持つユーザーは、 どのロールもそのオプションを拒否していない場合にだけ、そのオプションを得ます。そのため、制限的なロールが 1 つあれば、そのオプションを差し止められます。

保存されたシークレット

パスワード、トークン、鍵は、データベースに書き込まれる前に暗号化されます。

  • 認証情報、LDAP のバインドパスワード、ランナーのトークン、シングルサインオンのクライアントシークレット、Webhook の アドレス、API キーなど、保存されるシークレットはすべて、お客様が設定した ENCRYPTION_SECRET のもとで、 値ごとにランダムな初期化ベクトルを使って AES-256 で暗号化されます。
  • 保存されたシークレットを表示する API 呼び出しや設定ページはなく、バックアップにはマスターシークレットが含まれません。
  • シークレットを自社の Vault に置いたままにできます。 HashiCorp Vault と CyberArk は、ジョブが必要とするときに読み取られます。
  • ジョブのシークレットは、そのトークンから導出した鍵を使って AES-256-GCM で封をされた状態でランタイム環境に届きます。
  • 名前がシークレットのように見える extravars はジョブの表示でマスクされ、パスワードフィールドは常にマスクされます。 ジョブのデータ を参照してください。

データベースのそれ以外の部分 (ジョブ、その extravars と出力) はそのまま保存されます。データベース自体の保存時暗号化と アクセス制御で保護してください。 データベース を参照してください。


監査証跡

すべての変更と、拒否されたすべての試行が記録されます。

  • インターフェイスまたは API を通じた作成、変更、削除は、それぞれユーザー、そのアドレス、操作、対象、結果とともに 監査ログに書き込まれます。拒否とサインインも、失敗したものを含めて記録されます。
  • シークレットのように見える値は、書き込まれる前に伏せられます。
  • ログは既定で 365 日間保持され、UDP、TCP、TLS で syslog にコピーできます。

ブラウザー側

インターフェイスは、ページに注入されたコードから保護されています。

  • Content-Security-Policy により、アプリケーション自身のスクリプトとフレームだけが許可されます。
  • すべての応答には保護用のヘッダーが付きます: nosniff、フレーム保護、HTTPS での HSTS です。
  • フォーム、ヘルプテキスト、チャットの回答の HTML はサニタイズされ、ジョブの出力はエスケープされます。

サーバー側

ユーザーの入力を扱うコードは、典型的なインジェクションを回避しています。

  • データベースクエリは、値をクエリに連結したテキストとしてではなく、常にパラメーターとして渡します。
  • git を含むコマンドは、シェルではなく引数リストから実行されるため、シェルの特殊文字は効果を持ちません。
  • サーバー式は 式のサニタイザー を通り、その REST 呼び出しはホストフィルターを通ります。
  • MCP サーバー、 チャットアシスタント、メトリクスのエンドポイントは、有効にするまでオフです。

接続

AnsibleForms との間の通信は、エンドツーエンドで暗号化できます。

  • アプリケーションは自身で HTTPS を提供するか、リバースプロキシの背後に置かれます。
  • ランタイム環境は WebSocket (HTTPS のアドレスでは wss:// ) でアプリケーションと通信し、アプリケーションは インバウンドの RTE の証明書をピン留めします。 RTE のモード を参照してください。
  • LDAP、シングルサインオン、ランナー、git、シークレットストア、式の REST 呼び出しは、接続先サーバーの証明書を チェックします。ただし、自己署名証明書を使うサーバーに対して管理者がチェックをオフにした場合は除きます。

外部への接続

AnsibleForms が接続するのは、管理者が設定したものだけです。

接続先 接続するとき
LDAP、OpenID Connect、Entra ID (Microsoft のログインと Graph) そのサインイン方式が設定されているとき
AWX / AAP / Ascender、Semaphore、Rundeck、Jenkins フォームがそのランナーで実行されるとき
Git サーバー リポジトリが設定されているとき
メールサーバー、Slack、Teams、Telegram、Webhook 通知チャネルが設定されているとき
HashiCorp Vault、CyberArk シークレットストアが設定されているとき
モデルプロバイダー (Anthropic、OpenAI など) チャットアシスタント を有効にした場合のみ (既定では無効)
フォームで指定されたホストと API フォームの式や playbook がそれらを呼び出すとき
Syslog サーバー 監査ログやログの転送が設定されているとき

コンテナー

イメージは、できるだけ少ない権限で実行されるようにビルドされています。

  • アプリケーションとランタイム環境は、root ではなく、特権を持たない node ユーザーとして実行されます。
  • ダイジェストで固定された軽量な Debian イメージをベースにビルドされています。 セキュアな開発 を参照してください。
  • アプリケーションが待ち受けるポートは 8000 の 1 つだけです。

新しいインスタンスを保護する手順については、 ハードニング に従ってください。