DOCS

OAuth 2.0 authentication

OAuth 2.0認証

非対称キー暗号化を使用し、共有シークレットを使用せずに、Zonos でバックエンド サービスを認証します。

Zonos は、OAuth 2.0 JWT Bearer Token Grant (RFC 7523) を介したマシン間認証をサポートします。サービスは、RSA 秘密キーを使用して有効期間の短い JWT に署名します。 Zonos は、登録された公開キーを使用してそれを検証し、組織をスコープとするベアラー トークンを返します。

フローの概要:

  1. RSA キー ペアを生成し、公開キーを Zonos に登録します。
  2. 実行時に、秘密キーを使用して JWT アサーションに署名し、それをトークン エンドポイントに POST します。
  3. Zonos は、有効期間が短い アクセス トークンを返します。
  4. すべての API リクエストにアクセス トークンを Authorization: Bearer <token> として含めます。

4096 ビット RSA キー ペアを生成し、公開キーを Zonos と共有します。これはオンボーディング中に 1 回実行されます。

キーペアを生成する

1# Generate private key
2openssl genrsa -out private_key.pem 4096
3 
4# Extract public key
5openssl rsa -in private_key.pem -pubout -out public_key.pem

public_key.pem を Zonos と共有します。 private_key.pem は専用のシークレット マネージャー (AWS Secrets Manager、HashiCorp Vault など) に保存します。ソース管理や環境変数には決して保存しないでください。

Zonos はキーを登録し、組織 ID を返します。これは、すべての JWT アサーションの iss クレームになります。

秘密キーを使用して RS256 で JWT に署名します。アサーションは 1 回のトークン交換に対して有効です。有効期限を短く (60 ~ 300 秒) してください。

必須のクレーム

請求価値
issZonos 組織 ID (例: "org_abc123")
sub呼び出し側サービスを識別します (例: "checkout-service")
aud正確に "zonos-auth" である必要があります
expUnix タイムスタンプ。 iat から 60 ~ 300 秒
iat発行時のUnixタイムスタンプ
jtiアサーションごとに一意の UUID (リプレイ検出を有効にする)

JWT ヘッダーでは "alg": "RS256" および "typ": "JWT" を指定する必要があります。

コード例

1import jwt, uuid, time
2 
3with open("private_key.pem") as f:
4 private_key = f.read()
5 
6now = int(time.time())
7assertion = jwt.encode(
8 {
9 "iss": "org_abc123",
10 "sub": "checkout-service",
11 "aud": "zonos-auth",
12 "iat": now,
13 "exp": now + 300,
14 "jti": str(uuid.uuid4()),
15 },
16 private_key,
17 algorithm="RS256",
18)

署名された 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 (コンパクトなシリアル化)

リクエストとレスポンス

1{
2 "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
3 "assertion": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
4}
応答フィールド説明
access_token後続のすべての API リクエストのベアラー トークン
token_type常に"Bearer"
expires_in有効期限が切れるまでの秒数 (デフォルト: 300)
scopeこのトークンに付与されるスペース区切りのアクセス許可

完全なコード例

1import requests
2 
3response = requests.post(
4 "https://auth.zonos.com/oauth/token",
5 json={
6 : ,
7 : assertion,
8 },
9)
10data = response.json()
11access_token = data[]
12expires_in = data[]

すべての Zonos API リクエストの Authorization ヘッダーに、アクセス トークンを Bearer トークンとして含めます。

リクエストの例

1curl -X POST https://api.zonos.com/graphql \
2 -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
3 -H "Content-Type: application/json" \
4 -d '{ "query": "{ ... }" }'

トークンのライフサイクルとキャッシュ 

アクセス トークンは、デフォルトでは 5 分で期限切れになります。トークンをキャッシュし、プロアクティブに更新します。API 呼び出しごとに新しいトークンを要求しないでください。各更新には、新しく署名された JWT アサーションが必要です。

1import time, requests
2 
3_cache = {"access_token": None, "expires_at": 0}
4 
5def get_access_token():
6 if time.time() < _cache["expires_at"] - 30:
7 return _cache["access_token"]
8 
9 assertion = build_jwt_assertion()
10 data = requests.post(
11 "https://auth.zonos.com/oauth/token",
12 json={
13 "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
14 "assertion": assertion,
15 },
16 ).json()
17 
18 _cache["access_token"] = data["access_token"]
19 _cache["expires_at"] = time.time() + data["expires_in"]
20 return _cache["access_token"]

エラー参照 

すべてのエラーは、OAuth 2.0 エラー応答形式 (RFC 6749 §5.2) に従います。

1{
2 "error": "invalid_grant",
3 "error_description": "JWT assertion has expired"
4}
HTTPステータスerror原因
400unsupported_grant_typegrant_typeurn:ietf:params:oauth:grant-type:jwt-bearer ではありませんでした
400invalid_requestフィールドが欠落しているか不正な形式である
401invalid_grant無効な署名、期限切れのアサーション、不明な組織、または未登録のキー
500server_error内部エラー - 解決しない場合は、Zonos サポートにお問い合わせください

一般的な invalid_grant の原因:

  • exp は過去のものです - システム クロックが NTP 同期されていることを確認してください
  • aud は正確には "zonos-auth" ではありません
  • iss が登録された組織 ID と一致しません
  • 公開鍵はローテーションされましたが、まだ Zonos で更新されていません

セキュリティのベスト プラクティス 

  • 秘密キーを保護します。 秘密キーを専用のシークレット マネージャーに保存します。ソース管理、環境変数、ログには決して保存しないでください。
  • アサーションの有効期間は短くしてください。 60 ~ 300 秒が標準です。長いものを発行する理由はありません。
  • jti を含めます。 アサーションごとに一意の値により、サーバー側のリプレイ検出が可能になります。
  • キー ペアを定期的にローテーションします。 ダウンタイムを回避するために、古い公開キーを取り消す前に、新しい公開キーを Zonos に登録します。
  • access_token または assertion の値をログに記録しないでください。 両方を資格情報として扱います。

このページは役に立ちましたか?