前書き
現在、Amazon Fraud Detector (AFD) を活用した不正検知システムを開発しています。
本記事では、Ruby on Rails
の SDK を使用してAFD
のスコアリング結果を取得する方法について、備忘録も兼ねてまとめます。
Amazon Fraud Detector (AFD)の概要
- 機械学習を活用して不正行為をリアルタイムで検出するAWSのサービス
- 開発者は、過去の不正データを基にカスタムモデルを作成し、不正取引やアカウント乗っ取りなどを検出できる
- 高度な不正検知システムを簡単に導入できる
主な特徴
- 自動機械学習(AutoML):コード不要で不正検知モデルの構築が可能
- リアルタイムで不正リスクを判定:ユーザーのアクションごとにAIが即座に不正リスクをスコア化
- カスタムルールで自動対応:事前に設定したルールを基に、不正の疑いがある場合にアラートやブロックを実行
- 他のAWSサービスとの連携:
Amazon S3
、AWS Lambda
、Amazon SNS
等と連携可能
活用例
- 決済詐欺の防止
- 偽アカウントの検出
- プロモーション不正の抑制
前提条件
- Ruby on Railsの環境が構築済み
- AFD上で、モデルとディテクターが構築済み
構築手順
注意
- 本記事では、AFDに送信するデータを「メールアドレス」と「IPアドレス」のみに限定し、それらの情報を基にスコアリングを算出する構成としている
- その他の属性は送信せず、本記事の範囲外とする
設定関連
Gemfile
-
Gemfile
に下記のGemを追加した後、bundle exex install
を行う
# aws-sdk
gem 'aws-sdk-frauddetector'
マイグレーション
- AFDの結果を保存する為、マイグレーションファイルを作成する
rails generate migration CreatAfdScores
- マイグレーションファイルを修正した後、マイグレーションを実行する
20250321000000_create_afd_scores.rb
class CreatAfdScores < ActiveRecord::Migration[8.0]
def change
create_table :afd_scores do |t|
t.integer :score, null: false
t.string :judgment_result, null: false
t.timestamps
end
end
end
- マイグレーションの実行コマンド
rails db:migrate
環境変数(credentials.yml.enc)
-
credentials.yml.enc
に、以下の設定を追加する
credentials.yml.enc
afd_aws:
region: AFDが使用できるリージョン
access_key_id: A******************7
secret_access_key: I**************************************S
構築関連
コントローラーの設定
- 以下の処理を任意のコントローラーの
new
orcreate
メソッド内に記載する
(通常、新規データの作成時にスコアリングを行う為、new
やcreate
での実装が推奨される)
任意のcontroller.rb
# AfdClientのインスタンスを作成
afd_client = AfdClient.new
result = afd_client.get_score(
email: base.email,
ip_address: base.ip
)
# afd_socersテーブルにデータを保存する
AfdScore.create!(
score: result[:score],
judgment_result: result[:judgment_result]
)
サービスレイヤーの設定
-
app/services/
に afd_client.rb ファイルを作成する - 以下のコードを
afd_client.rb
に記載する
afd_client.rb
require 'aws-sdk-frauddetector'
class AfdClient
# RailsとAFDの相互通信を行う為の認証処理。
def initialize
@client = Aws::FraudDetector::Client.new(
# credentials.yml.encからAWSの認証情報を取得
region: Rails.application.credentials.afd_aws[:region],
credentials: Aws::Credentials.new(
Rails.application.credentials.afd_aws[:access_key_id],
Rails.application.credentials.afd_aws[:secret_access_key]
),
http_open_timeout: 10, # 接続開始までのタイムアウトを設定
http_read_timeout: 10 # データ読み取りのタイムアウトを設定
)
end
def get_score(email:, ip_address:)
begin
# AFDに通信して、結果を取得
response = @client.get_event_prediction(
detector_id: "構築したdetector_idを記載",
event_id: SecureRandom.uuid,
event_type_name: "構築したイベントの名前を記載",
event_timestamp: Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
entities: [
{
entity_type: "AFDで構築したエンティティタイプ名を記載",
entity_id: "エンティティタイプ名_#{Digest::SHA256.hexdigest(email)}"
}
],
event_variables: {
"email" => email,
"ip_address" => ip_address
}
)
rescue Aws::FraudDetector::Errors::ServiceError, Net::OpenTimeout, Net::ReadTimeout => e
Rails.logger.error(e.message, email, ip_address)
return { score: 0, judgment_result: "error" }
end
score = response.model_scores.first&.scores.values.first || 0
result = response.rule_results.first&.outcomes&.first || "unknown"
return {
score: score,
judgment_result: result
}
rescue => e
Rails.logger.error("AFD Error: #{e.message}")
{ score: 0, judgment_result: "error" }
end
end
get_event_predictionメソッドで設定するパラメータと説明
パラメータ | 説明 |
---|---|
detector_id 型 : String |
AFDに設定したDetector ID。どの不正検知モデルを使用するかを指定する 入力例 "my_fraud_detector_v1"
|
event_id 型 : String |
各リクエストごとに一意のIDを割り当てる為の識別子。通常、SecureRandom.uuid を使用する入力例 "123e4567-e89b-12d3-a456-426614174000"
|
event_type_name 型 : String |
AFDに設定したイベントの種類。どのイベント定義を使用するかを指定する 入力例 "transaction_event"
|
event_timestamp 型 : String |
イベントが発生した時刻 入力例 "2025-03-13T12:34:56Z"
|
entities 型 : Array(Hash化) |
不正検知の対象となる ユーザーや取引(エンティティ) を識別する為の情報を設定する 入力例 [ { entity_type: "customer", entity_id: "customer_abcdefg" } ]
|
event_variables 型 : Hash |
不正リスクを判定する為に、取引やアクセス情報(イベント変数)をAFDに送信する 入力例 { "email" => "test@example.com", "ip_address" => "192.168.1.1" }
|
補足
app/services/
の用途
- モデル (
app/models/
) に直接書くべきでない複雑な処理を分ける - MVCの「サービス層」として利用し、コードの再利用性と可読性を向上させる
- Fat Controller(肥大化したコントローラ)やFat Modelを防ぐ為に使用する
参考資料
- [AWS公式] Amazon Fraud Detector
- [AWS公式] Class: Aws::FraudDetector::Client
- [AWS公式]get_event_prediction-instance_method
- [GitHub 公式] aws-sdk-ruby
感想
今回は、AFDを活用した Railsの処理を構築しました。
特に、例外処理の実装が難しく、試行錯誤を重ねました。
また、本記事では触れていませんが、RSpecのテスト実装に最も苦戦しました。
RSpecについては、今後も引き続き学習し、理解を深めていきたいと思います。