- Firme una aserción de cliente JWT con su clave privada ES256.
- Cámbiela por un token de acceso de corta duración.
- Realice una llamada a un punto final de metadatos con el token de acceso.
private_key.pem) junto al script. Sustituya <OAuthClientId> y <KID> con los valores de su paquete de incorporación. Consulte Solicite un token de acceso para conocer la función de cada paso.
- TypeScript
- Python
Requiere Node.js 18 o posterior para el 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;
});
Requiere Python 3.8 o posterior.
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)
Puntos finales de metadatos
EstablezcaMETADATA_ENDPOINT cualquiera de estas opciones. Todas son GET solicitudes.
| Punto de conexión | Devuelve |
|---|---|
/beta/metadata/columns | Columnas de entrada disponibles con tipo, «scopeable», «facetable» y «entitlement» |
/beta/metadata/available-dates | Fecha de entrada en vigor más reciente y fecha de entrada en vigor finalizada más reciente |
/beta/metadata/geography-schema | Jerarquía de grupos de regiones, regiones y países |
/beta/metadata/rating-scales | Escalas de calificación compatibles y sus correspondencias de grados |
Nunca comparta su clave privada con nadie, ni siquiera con Credit Benchmark. Genere una nueva aserción de cliente para cada solicitud de token y, si en algún momento se ve comprometida una clave privada, siga el procedimiento que se indica en Rotación de claves.

