Genyleap/Docs
OpenProof / 開発

標準 OAuth/OIDC を使って、あらゆるアプリケーションを接続できます。

OpenProof はプロトコル境界でプログラミング言語に依存しません。付属 SDK が役立つ場合は利用し、そうでなければ HTTPS と OAuth 2.0/OpenID Connect を扱える任意の言語から統合できます。

統合モデル

フローAuthorization Code + PKCE
Your app
   ↓ redirect
OpenProof /oauth/authorize
   ↓
authentication / provider / passkey / wallet
   ↓
your callback?code=...&state=...&iss=...
   ↓ code + verifier
OpenProof /oauth/token
   ↓
access_token + id_token + optional refresh_token

製品統合には OAuth/OIDC token を使用してください。安全な OpenProof session cookie は OpenProof の account/admin origin に属するため、製品ドメインへコピーしないでください。

Discovery から始める

URLauth.example.com を置き換える
https://auth.example.com/.well-known/openid-configuration
https://auth.example.com/.well-known/jwks.json

再利用可能な client が authorization、token、UserInfo、introspection などのプロトコル endpoint を取得するには Discovery が推奨されます。

製品を登録する

IAL2 の有効な owner は次を利用できます: /admin/console または administration API。

application を作成

curlowner session が必要
curl --fail-with-body -b owner.cookies \
  https://auth.example.com/admin/applications \
  -H 'Content-Type: application/json' \
  -d '{
    "identifier":"example-web",
    "name":"Example Web",
    "environment":"production"
  }'

client を作成

curlweb client
curl --fail-with-body -b owner.cookies \
  https://auth.example.com/admin/clients \
  -H 'Content-Type: application/json' \
  -d '{
    "application_id":"APPLICATION_ID",
    "name":"Example Web",
    "kind":"web",
    "redirect_uris":["https://app.example.com/oauth/callback"],
    "scopes":["openid","profile","offline_access"]
  }'
種類代表的な clientSecret
browserSPA / ブラウザのみなし
nativeiOS / Android / desktopなし
webServer-rendered / backend Web アプリ1 回だけ返却・backend のみ
serviceMachine-to-machine1 回だけ返却

Authorization Code + PKCE S256

ランダムな verifier を生成し、S256 challenge を導出し、さらにランダムな state and nonce. を生成します。verifier/state/nonce はそのログイントランザクションの存続期間だけ保持してください。

authorization リクエスト概念例
GET /oauth/authorize?
  response_type=code
  &client_id=CLIENT_ID
  &redirect_uri=https://app.example.com/oauth/callback
  &scope=openid profile offline_access
  &code_challenge=PKCE_CHALLENGE
  &code_challenge_method=S256
  &state=STATE
  &nonce=NONCE

callback では、返された state and iss が token exchange の前にトランザクションまたは設定済み issuer と一致することを必須にしてください。

Token 交換

curlapplication/x-www-form-urlencoded
curl --fail-with-body https://auth.example.com/oauth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=authorization_code' \
  --data-urlencode 'client_id=CLIENT_ID' \
  --data-urlencode 'code=AUTHORIZATION_CODE' \
  --data-urlencode 'redirect_uri=https://app.example.com/oauth/callback' \
  --data-urlencode 'code_verifier=PKCE_VERIFIER'

ID token 検証

RS256 署名を issuer の JWKS で検証します。少なくとも次を検証してください: iss, aud, exp, iat および元の nonce。また、 nbf, azp and at_hash が存在する場合は検証してください。

JavaScript / ブラウザ

repository にはブラウザ向け SDK package として @openproof/identity. が含まれています。PKCE/state/nonce の生成、callback の state/issuer 検証、JWKS による RS256 ID token 検証を行います。

javascriptpublic browser client
import { OpenProofIdentity } from "@openproof/identity";

const identity = new OpenProofIdentity({
  issuer: "https://auth.example.com",
  clientId: "CLIENT_ID",
  redirectUri: "https://app.example.com/oauth/callback",
  scopes: ["openid", "profile", "offline_access"]
});

await identity.login();
javascriptcallback
const tokens = await identity.handleCallback();

console.log(tokens.id_token_claims.sub);

const profile =
  await identity.userInfo(tokens.access_token);
ブラウザ client に client secret はありません。

機密の web or service client secret をユーザーへ配信する JavaScript に埋め込まないでください。

Node.js

framework に対応する成熟した OIDC client を使うか、文書化されたプロトコルに対して native fetch() を使用してください。機密 credential はサーバー環境または secret store に保存します。

javascriptserver-side token exchange
const body = new URLSearchParams({
  grant_type: "authorization_code",
  client_id: process.env.OPENPROOF_CLIENT_ID,
  code,
  redirect_uri: "https://app.example.com/oauth/callback",
  code_verifier: verifier
});

const response = await fetch(
  "https://auth.example.com/oauth/token",
  {
    method: "POST",
    headers: {
      "content-type":
        "application/x-www-form-urlencoded"
    },
    body
  }
);

if (!response.ok) {
  throw new Error(
    `OpenProof token exchange failed: ${response.status}`
  );
}

const tokens = await response.json();

JWKS cache、署名検証、claim validation には OIDC/JWT library を使い、暗号学的検証を独自実装しないでください。

PHP

保守されている任意の PHP OAuth/OIDC library で OpenProof を issuer として利用できます。直接プロトコルは通常の HTTPS と form-encoded OAuth です。

phptoken exchange
<?php

$payload = http_build_query([
    'grant_type' => 'authorization_code',
    'client_id' => getenv('OPENPROOF_CLIENT_ID'),
    'code' => $_GET['code'],
    'redirect_uri' =>
        'https://app.example.com/oauth/callback',
    'code_verifier' =>
        $_SESSION['openproof_pkce_verifier'],
]);

$curl = curl_init(
    'https://auth.example.com/oauth/token'
);

curl_setopt_array($curl, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $payload,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/x-www-form-urlencoded'
    ],
]);

$body = curl_exec($curl);

if ($body === false) {
    throw new RuntimeException(curl_error($curl));
}

ID token は保守されている JWT/OIDC package と issuer JWKS で検証してください。RSA/JWK 検証を ad hoc に実装しないでください。

C++

repository の C++26 SDK は次の名前で export されます: openproof.sdk. transport 非依存なので、既存の Boost.Beast、Qt Network、libcurl stack をそのまま利用できます。

c++SDK 設定
import openproof.sdk;

auto config =
    openproof::sdk::ClientConfig::create(
        "https://auth.example.com",
        "CLIENT_ID",
        "http://127.0.0.1:49152/callback",
        {"openid", "profile", "offline_access"});

openproof::sdk::IdentityClient client{
    std::move(config).value()
};

auto login = client.beginLogin();

std::cout <<
    login->authorizationUrl()
    << '\n';

SDK は login transaction の作成、authorization-code request の構築、refresh、UserInfo の helper を提供します。最小の relying-party 例は次にあります: examples/reference-client.

Python、Go、Rust、Java、C# などの言語

OpenProof 専用 SDK は必要ありません。標準準拠 OAuth/OIDC library を OpenProof issuer で設定してください。安全な最小実装は Discovery → PKCE/state/nonce → authorization redirect → callback checks → token exchange → JWKS signature/claim validation → access-token authorization です。

UserInfo と refresh

curlUserInfo
curl --fail-with-body \
  https://auth.example.com/oauth/userinfo \
  -H 'Authorization: Bearer ACCESS_TOKEN'
curlrefresh token
curl --fail-with-body \
  https://auth.example.com/oauth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=refresh_token' \
  --data-urlencode 'client_id=CLIENT_ID' \
  --data-urlencode 'refresh_token=REFRESH_TOKEN'

Refresh token はローテーションされます。新しい token を原子的に保存し、古い値を破棄してください。Replay protection により token family 全体が revoke される場合があります。

API を保護する

正確な audience と限定的な scope で resource を登録してください。

curlresource を登録
curl --fail-with-body -b owner.cookies \
  https://auth.example.com/admin/resources \
  -H 'Content-Type: application/json' \
  -d '{
    "audience":"https://api.example.com/rides",
    "name":"Ride API",
    "scopes":["rides:read","rides:request"]
  }'

backend では token の有効性、正確な audience、必要な scope、製品の business rule を確認して authorization してください。有効な token だけでは十分な authorization ではありません。

Introspection

curl機密 backend
curl --fail-with-body \
  https://auth.example.com/oauth/introspect \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'client_id=CONFIDENTIAL_CLIENT_ID' \
  --data-urlencode 'client_secret=CLIENT_SECRET' \
  --data-urlencode 'token=ACCESS_TOKEN'

OpenProof gateway

別の方法として、製品 route を OpenProof の背後に置き、backend へ proxy する前に静的 route policy で role、assurance、scope、audience を適用できます。

Service 間

次の service client を使用して許可する audience/scope を provision し、その後 access token を次で要求します: client_credentials.

curlmachine grant
curl --fail-with-body \
  https://auth.example.com/oauth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=client_credentials' \
  --data-urlencode 'client_id=CLIENT_ID' \
  --data-urlencode 'client_secret=CLIENT_SECRET' \
  --data-urlencode 'scope=rides:dispatch' \
  --data-urlencode 'resource=https://api.example.com/dispatch'

結果は access token のみです。refresh token や人間の session はありません。

Account API

account self-service と verification delivery が有効な場合、OpenProof は signup、検証済みメール/電話所有、password reset、profile、TOTP、recovery code、passkey を提供します。

目的Endpoint
登録POST /account/signup
メール検証POST /account/email/verify
パスワード再設定を開始POST /account/password/forgot
パスワード再設定を完了POST /account/password/reset
プロフィールGET/PATCH /account/profile
TOTP 登録POST /account/totp/start/complete
Passkey ログインPOST /auth/passkey/options/verify
リンク済み方式GET /account/connections
1 つの canonical identity。

製品ユーザーのキーに Google/GitHub のメールを使わないでください。ユーザーは同じ安定した OpenProof subject を維持したまま複数の sign-in method をリンクできます。

エラー処理と secret 管理

エラーには安定した code、client-safe message、request ID が含まれます。文章ではなく code/status で分岐してください。401 は認証なし/無効、403 は authority/assurance 不足、409 は state conflict、429 は backoff signal として扱います。

password、TOTP/recovery code、verification secret、authorization code、access/refresh token、機密 client secret、cookie、DPoP proof、private key をログに残さないでください。