- Signez une assertion client JWT à l’aide de votre clé privée ES256.
- Échangez-la contre un jeton d’accès à durée de vie limitée.
- Appelez un point de terminaison de métadonnées à l’aide du jeton d’accès.
private_key.pem) à côté du script. Remplacez <OAuthClientId> et <KID> avec les valeurs figurant dans votre dossier d’intégration. Consultez Demander un jeton d’accès pour connaître la fonction de chaque étape.
- TypeScript
- Python
Nécessite Node.js 18 ou une version ultérieure pour le paramètre global
fetch.npm install jsonwebtoken
npm install --save-dev typescript tsx @types/jsonwebtoken @types/node
npx tsx sample_request.ts
sample_request.ts
import { randomUUID } from 'node:crypto';
import { readFileSync } from 'node:fs';
import jwt from 'jsonwebtoken';
// ---------------------------------------------------------------------------
// Configuration — fill these in for your environment.
// ---------------------------------------------------------------------------
const OAUTH_CLIENT_ID = '<OAuthClientId>'; // Your OAuth Client Id (from your onboarding pack)
const KID = '<KID>'; // The Kid whose PRIVATE key you're using to sign below
const PRIVATE_KEY_PATH = './private_key.pem'; // Path to the PRIVATE key matching that Kid's public key
const GATEWAY_BASE_URL = 'https://gateway.creditbenchmark.com';
const TOKEN_URL = 'https://gateway.creditbenchmark.com/api/security/token';
const AUDIENCE = 'cb-gateway-m2m-blue';
// Any of the metadata endpoints below — change as needed.
const METADATA_ENDPOINT = '/beta/metadata/columns';
/** Builds and signs the RFC 7523 JWT bearer client assertion. */
function buildClientAssertion(): string {
const privateKeyPem = readFileSync(PRIVATE_KEY_PATH, 'utf8');
const now = Math.floor(Date.now() / 1000);
return jwt.sign(
{
iss: OAUTH_CLIENT_ID,
sub: OAUTH_CLIENT_ID,
aud: AUDIENCE,
jti: randomUUID(),
iat: now,
exp: now + 120,
},
privateKeyPem,
{ algorithm: 'ES256', keyid: KID }
);
}
/** Exchanges the signed client assertion for a short-lived access token. */
async function getAccessToken(): Promise<string> {
const clientAssertion = buildClientAssertion();
const body = new URLSearchParams({
grant_type: 'client_credentials',
client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
client_assertion: clientAssertion,
OAuthClientId: OAUTH_CLIENT_ID,
});
const response = await fetch(TOKEN_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body,
});
if (!response.ok) {
throw new Error(`Token request failed: ${response.status} ${await response.text()}`);
}
const data = (await response.json()) as { accessToken: string };
return data.accessToken;
}
/** Calls a metadata API using the access token. Swap 'endpoint' for any of
* the other metadata endpoints. */
async function callMetadataEndpoint(accessToken: string, endpoint: string = METADATA_ENDPOINT): Promise<unknown> {
const response = await fetch(`${GATEWAY_BASE_URL}${endpoint}`, {
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
Accept: 'application/json',
},
});
if (!response.ok) {
throw new Error(`Metadata request failed: ${response.status} ${await response.text()}`);
}
return response.json();
}
(async () => {
const token = await getAccessToken();
console.log('Access token acquired.');
const data = await callMetadataEndpoint(token);
console.log(`Response from ${METADATA_ENDPOINT}:`);
console.log(data);
})().catch((err) => {
console.error(err);
process.exitCode = 1;
});
Nécessite Python 3.8 ou une version ultérieure.
pip install "requests>=2.31.0" "PyJWT>=2.8.0" "cryptography>=41.0.0"
python sample_request.py
sample_request.py
import time
import uuid
import jwt # PyJWT
import requests
# ---------------------------------------------------------------------------
# Configuration — fill these in for your environment.
# ---------------------------------------------------------------------------
OAUTH_CLIENT_ID = "<OAuthClientId>" # Your OAuth Client Id (from your onboarding pack)
KID = "<KID>" # The Kid whose PRIVATE key you're using to sign below
PRIVATE_KEY_PATH = "private_key.pem" # Path to the PRIVATE key matching that Kid's public key
GATEWAY_BASE_URL = "https://gateway.creditbenchmark.com"
TOKEN_URL = "https://gateway.creditbenchmark.com/api/security/token"
AUDIENCE = "cb-gateway-m2m-blue"
# Any of the metadata endpoints below — change as needed.
METADATA_ENDPOINT = "/beta/metadata/columns"
def build_client_assertion() -> str:
"""Builds and signs the RFC 7523 JWT bearer client assertion."""
with open(PRIVATE_KEY_PATH, "r", encoding="utf-8") as f:
private_key_pem = f.read()
now = int(time.time())
payload = {
"iss": OAUTH_CLIENT_ID,
"sub": OAUTH_CLIENT_ID,
"aud": AUDIENCE,
"jti": str(uuid.uuid4()),
"iat": now,
"exp": now + 120,
}
headers = {"kid": KID}
return jwt.encode(payload, private_key_pem, algorithm="ES256", headers=headers)
def get_access_token() -> str:
"""Exchanges the signed client assertion for a short-lived access token."""
client_assertion = build_client_assertion()
response = requests.post(
TOKEN_URL,
data={
"grant_type": "client_credentials",
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_assertion": client_assertion,
"OAuthClientId": OAUTH_CLIENT_ID,
},
headers={"Content-Type": "application/x-www-form-urlencoded"},
timeout=30,
)
response.raise_for_status()
return response.json()["accessToken"]
def call_metadata_endpoint(access_token: str, endpoint: str = METADATA_ENDPOINT) -> dict:
"""Calls a metadata API using the access token. Swap 'endpoint' for any
of the other metadata endpoints."""
response = requests.get(
f"{GATEWAY_BASE_URL}{endpoint}",
headers={
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json",
"Accept": "application/json",
},
timeout=30,
)
response.raise_for_status()
return response.json()
if __name__ == "__main__":
token = get_access_token()
print("Access token acquired.")
data = call_metadata_endpoint(token)
print(f"Response from {METADATA_ENDPOINT}:")
print(data)
Points de terminaison des métadonnées
DéfinissezMETADATA_ENDPOINT l’une de ces valeurs. Il s’agit dans tous les cas de GET des requêtes.
| Point de terminaison | Renvoie |
|---|---|
/beta/metadata/columns | Colonnes d’entrée disponibles avec les attributs « type », « scopeable », « facetable » et « entitlement » |
/beta/metadata/available-dates | Date d’entrée en vigueur la plus récente et date d’entrée en vigueur finalisée la plus récente |
/beta/metadata/geography-schema | Hiérarchie des groupes de régions, des régions et des pays |
/beta/metadata/rating-scales | Échelles de notation prises en charge et leurs correspondances de notes |
Ne communiquez jamais votre clé privée à quiconque, y compris à Credit Benchmark. Générez une nouvelle assertion client pour chaque demande de jeton, et si une clé privée venait à être compromise, suivez la procédure décrite à l’adresse rotation des clés.

