AgentHouse HumanProof
HTMLフォームのボット・スパム対策に。Cookie・フィンガープリント・第三者CAPTCHAウィジェットは不要。1つのJavaScriptとサーバー側検証。証明はバックグラウンドで静かに実行されます。
CAPTCHAの現代的な代替
従来のCAPTCHAは手間とアクセシビリティ負荷が大きく、追跡的な第三者スクリプトを引き込みがちです。HumanProofは短命の署名付きチャレンジと軽量PoWをブラウザで行います。パズル・画像・余計なウィジェットはありません。
- ウィジェット網によるフィンガープリントやクロスサイト追跡プロファイルはありません。
- ページにGoogleや外部CAPTCHAプロバイダは不要です。
- 秘密はサーバー側に。ブラウザが検証用キーを持つことはありません。
仕組み
チャレンジから検証済み送信まで4ステップ。
- SDKが公開サイトキーとフォームIDで署名付きチャレンジを要求します。
- ブラウザが小さなPoWを解きます(可能ならメインスレッド外)。
- 通常の送信時に隠しフィールドとして証明を付与します。
- サーバーが秘密鍵で検証APIを呼び、accept / quarantine / fake-successの指針を受け取ります。
プライバシー優先サイト向け
GDPR意識の高いチームやEU優先ホスティング向け。攻撃面が小さく、フォームに広告系スクリプトはありません。
- ウィジェットにCookieは不要。
- 通信は自サイトのオリジンとAgentHouse APIの間だけ。広告ネットワークのスクリプトはありません。
- 検証側のログは最小限かつ保持方針に配慮。
- 各結果の扱い(受理・隔離・fake-success)は自前のバックエンドで決められます。
JavaScriptは1ファイルだけ
npm・バンドラ・フレームワーク不要。AgentHouse APIのスクリプトを1つ読み込み、フォームにdata属性を付けるだけ。1本のスクリプトで同一ページの複数フォームを保護できます。任意の「Powered by AgentHouse」表記はデフォルトで含まれます。
開発者に優しい統合
フロントはスクリプト1つ。バックエンドは検証用のJSON POST 1回。Node.js、PHP、Python、HTTPSを呼べる環境なら何でも対応。
スクリプト/APIのURLは設定に従います(本番はapi.agenthouse.org、開発はsecretsのpublicSdkBase)。
送信時にチャレンジ取得とPoWが必要な場合、SDKは window で CustomEvent の humanproof.securingForm を発火します(detail に form、siteKey、formId)。進捗表示に利用できます。失敗時はフォームで humanproof-error。
window.addEventListener('humanproof.securingForm', function (e) { /* e.detail.form, siteKey, formId */ });
PoWはサーバーのチャレンジ取得後にのみ可能です。任意で、scriptにdata-prefetch-challenge-delay-ms(読み込み後のミリ秒)を指定するとバックグラウンドで取得・計算し、送信時にまだ有効なら再利用します。data-prefetch-expiry-margin-msは再利用前に必要な残りTTL(時刻ずれ対策)です。フォーム単位はdata-humanproof-prefetch-challenge-delay-msとdata-humanproof-prefetch-expiry-margin-ms。
<form id="contact-form" data-humanproof="YOUR_FORM_ID">
<label>Email <input type="email" name="email" required></label>
<button type="submit">Send</button>
</form>
<script
src="https://api.agenthouse.org/humanproof/humanproof.js"
data-site-key="YOUR_PUBLIC_SITE_KEY"
data-powered-by="true"
data-endpoint="https://api.agenthouse.org/humanproof"
data-prefetch-challenge-delay-ms="2500"
data-prefetch-expiry-margin-ms="15000"
></script><form id="a" data-humanproof="form-a">...</form>
<form id="b" data-humanproof="form-b">...</form>
<script
src="https://api.agenthouse.org/humanproof/humanproof.js"
data-site-key="YOUR_PUBLIC_SITE_KEY"
data-powered-by="true"
data-endpoint="https://api.agenthouse.org/humanproof"
data-prefetch-challenge-delay-ms="2500"
data-prefetch-expiry-margin-ms="15000"
></script>// POST https://api.agenthouse.org/humanproof/verify — JSON body (Node 18+ fetch)
const verifyUrl = 'https://api.agenthouse.org/humanproof/verify';
const secretKey = ''; // set from your secrets store before use
const payload = JSON.parse(formFields.humanproof);
const body = {
secretKey,
siteKey: payload.siteKey,
formId: payload.formId,
challengeId: payload.challengeId,
challenge: payload.challenge,
nonce: payload.nonce,
signature: payload.signature,
algorithm: payload.algorithm,
salt: payload.salt,
expiresAt: payload.expiresAt,
difficulty: payload.difficulty,
boundHost: payload.boundHost,
boundAction: payload.boundAction,
submitDurationMs: payload.submitDurationMs
};
const res = await fetch(verifyUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
});
const result = await res.json();
// result.status: 'ok' | 'suspicious' | 'reject'
// result.suggestedAction: 'accept' | 'quarantine' | 'fake-success' | 'reject'<?php
$url = 'https://api.agenthouse.org/humanproof/verify';
$secret = ''; // set from your server secret store before use
$payload = json_decode($_POST['humanproof'], true);
$body = array_merge(['secretKey' => $secret], $payload);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($body),
CURLOPT_RETURNTRANSFER => true,
]);
$out = curl_exec($ch);
$result = json_decode($out, true);
?>import json
import urllib.request
VERIFY_URL = "https://api.agenthouse.org/humanproof/verify"
def verify_humanproof(secret_key: str, payload: dict) -> dict:
body = {"secretKey": secret_key, **payload}
req = urllib.request.Request(
VERIFY_URL,
data=json.dumps(body).encode("utf-8"),
headers={"Content-Type": "application/json"},
method="POST",
)
with urllib.request.urlopen(req, timeout=30) as resp:
return json.load(resp)ブランディング
HumanProofは既定で短い「Powered by AgentHouse」表記を表示します。シンプルな月額で非表示にできます。製品とプライバシー上の保証は同じです。
- 無料枠では短い「Powered by」表記が含まれます。
- 有料プランで表記を非表示に。挙動と検証は同じです。
- ライセンスのご相談はお問い合わせください。
チームがHumanProofを選ぶ理由
プロダクトとコンプライアンスの両方に効くメリット。
- 画像やパズル型CAPTCHAより割り込みが少なく、新たにクリックさせるステップはありません。
- アクセシビリティに配慮。視覚的なチャレンジ画面はなく、キーボード操作の流れと相性が良いです。
- プライバシー面が明確。フォーム上に第三者CAPTCHAや広告ウィジェットはありません。
- 導入が速い。スクリプト1本、検証API1つ、主要バックエンド向けの例付き。
- 方針はあなた次第。フォームごとの難易度と、疑わしい送信の扱いを決められます。
ライブで試す
下のフォームを送信すると、バックグラウンドでPoWが走り、デモがサーバーへPOSTします(保存はしません)。