ステップ 1 — 公開キーを登録する (1 回限りのセットアップ)
4096 ビット RSA キー ペアを生成し、公開キーを Zonos と共有します。これはオンボーディング中に 1 回実行されます。
キーペアを生成する
# Generate private keyopenssl genrsa -out private_key.pem 4096 # Extract public keyopenssl rsa -in private_key.pem -pubout -out public_key.pempublic_key.pem を Zonos と共有します。 private_key.pem は専用のシークレット マネージャー (AWS Secrets Manager、HashiCorp Vault など) に保存します。ソース管理や環境変数には決して保存しないでください。
Zonos はキーを登録し、組織 ID を返します。これは、すべての JWT アサーションの iss クレームになります。
ステップ 2 — JWT アサーションを構築する
秘密キーを使用して RS256 で JWT に署名します。アサーションは 1 回のトークン交換に対して有効です。有効期限を短く (60 ~ 300 秒) してください。
必須のクレーム
| 請求↕ | 価値↕ |
|---|---|
iss | Zonos 組織 ID (例: "org_abc123") |
sub | 呼び出し側サービスを識別します (例: "checkout-service") |
aud | 正確に "zonos-auth" である必要があります |
exp | Unix タイムスタンプ。 iat から 60 ~ 300 秒 |
iat | 発行時のUnixタイムスタンプ |
jti | アサーションごとに一意の UUID (リプレイ検出を有効にする) |
JWT ヘッダーでは "alg": "RS256" および "typ": "JWT" を指定する必要があります。
コード例
import jwt, uuid, time with open("private_key.pem") as f: private_key = f.read() now = int(time.time())assertion = jwt.encode( { "iss": "org_abc123", "sub": "checkout-service", "aud": "zonos-auth", "iat": now, "exp": now + 300, "jti": str(uuid.uuid4()), }, private_key, algorithm="RS256",)ステップ 3 — アサーションをアクセス トークンと交換する
署名された JWT を Zonos トークン エンドポイントに送信して、有効期間の短いベアラー トークンを受け取ります。
エンドポイント
POST https://auth.zonos.com/oauth/token
Content-Type: application/json
application/x-www-form-urlencodedも受け付けます。
リクエストフィールド
| 分野↕ | 必須↕ | 価値↕ |
|---|---|---|
grant_type | はい | "urn:ietf:params:oauth:grant-type:jwt-bearer" |
assertion | はい | 署名された JWT (コンパクトなシリアル化) |
リクエストとレスポンス
{ "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."}| 応答フィールド↕ | 説明↕ |
|---|---|
access_token | 後続のすべての API リクエストのベアラー トークン |
token_type | 常に"Bearer" |
expires_in | 有効期限が切れるまでの秒数 (デフォルト: 300) |
scope | このトークンに付与されるスペース区切りのアクセス許可 |
完全なコード例
import requests response = requests.post( "https://auth.zonos.com/oauth/token", json={ : , : assertion, },)data = response.json()access_token = data[]expires_in = data[]ステップ 4 — アクセス トークンを使用して Zonos APIs を呼び出します
すべての Zonos API リクエストの Authorization ヘッダーに、アクセス トークンを Bearer トークンとして含めます。
リクエストの例
curl -X POST https://api.zonos.com/graphql \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \ -H "Content-Type: application/json" \ -d '{ "query": "{ ... }" }'トークンのライフサイクルとキャッシュ
アクセス トークンは、デフォルトでは 5 分で期限切れになります。トークンをキャッシュし、プロアクティブに更新します。API 呼び出しごとに新しいトークンを要求しないでください。各更新には、新しく署名された JWT アサーションが必要です。
import time, requests _cache = {"access_token": None, "expires_at": 0} def get_access_token(): if time.time() < _cache["expires_at"] - 30: return _cache["access_token"] assertion = build_jwt_assertion() data = requests.post( "https://auth.zonos.com/oauth/token", json={ "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion": assertion, }, ).json() _cache["access_token"] = data["access_token"] _cache["expires_at"] = time.time() + data["expires_in"] return _cache["access_token"]エラー参照
すべてのエラーは、OAuth 2.0 エラー応答形式 (RFC 6749 §5.2) に従います。
{ "error": "invalid_grant", "error_description": "JWT assertion has expired"}| HTTPステータス↕ | error↕ | 原因↕ |
|---|---|---|
400 | unsupported_grant_type | grant_type は urn:ietf:params:oauth:grant-type:jwt-bearer ではありませんでした |
400 | invalid_request | フィールドが欠落しているか不正な形式である |
401 | invalid_grant | 無効な署名、期限切れのアサーション、不明な組織、または未登録のキー |
500 | server_error | 内部エラー - 解決しない場合は、Zonos サポートにお問い合わせください |
一般的な invalid_grant の原因:
expは過去のものです - システム クロックが NTP 同期されていることを確認してくださいaudは正確には"zonos-auth"ではありませんissが登録された組織 ID と一致しません- 公開鍵はローテーションされましたが、まだ Zonos で更新されていません
セキュリティのベスト プラクティス
- 秘密キーを保護します。 秘密キーを専用のシークレット マネージャーに保存します。ソース管理、環境変数、ログには決して保存しないでください。
- アサーションの有効期間は短くしてください。 60 ~ 300 秒が標準です。長いものを発行する理由はありません。
jtiを含めます。 アサーションごとに一意の値により、サーバー側のリプレイ検出が可能になります。- キー ペアを定期的にローテーションします。 ダウンタイムを回避するために、古い公開キーを取り消す前に、新しい公開キーを Zonos に登録します。
access_tokenまたはassertionの値をログに記録しないでください。 両方を資格情報として扱います。
OAuth 2.0認証
非対称キー暗号化を使用し、共有シークレットを使用せずに、Zonos でバックエンド サービスを認証します。
Zonos は、OAuth 2.0 JWT Bearer Token Grant (RFC 7523) を介したマシン間認証をサポートします。サービスは、RSA 秘密キーを使用して有効期間の短い JWT に署名します。 Zonos は、登録された公開キーを使用してそれを検証し、組織をスコープとするベアラー トークンを返します。
フローの概要:
Authorization: Bearer <token>として含めます。