Authentication
Obtain an Auth0 machine-to-machine token and call Pulse Context.
Pulse Context uses Auth0’s Client Credentials Flow. Protected /v1/* endpoints accept access tokens issued to machine-to-machine clients; user tokens are rejected.
What Auth0 needs
- An Auth0 API (resource server) with identifier
https://1komma5grad.com/apiandRS256signing. This shared production API already exists. - A non-interactive Auth0 client with the
client_credentialsgrant. - A client grant connecting that client to the
https://1komma5grad.com/apiaudience. Pulse Context currently checks the M2M identity, not scopes, so do not grant unrelated scopes. - The client secret stored in a secret manager and exposed only to the calling server or job. Never ship it to browser code or commit it.
Use the Customer Comm LMCP M2M client as an IaC example. It shows the non_interactive client, Secret Manager credential, client_credentials grant, and client grant for the shared audience. Create a separate least-privilege client for your workload.
The API validates the token’s Auth0 issuer, audience, expiry, RS256 signature, and M2M subject. /health, /openapi.yaml, and the docs are public. /cron/sync uses CRON_SECRET, not Auth0.
Environment
| Variable | Value |
|---|---|
PULSE_CONTEXT_AUTH0_ISSUER_URL |
Issuer URL of the Auth0 tenant that owns the M2M client |
PULSE_CONTEXT_AUTH0_CLIENT_ID |
Client ID from the Auth0 client |
PULSE_CONTEXT_AUTH0_CLIENT_SECRET |
Client secret loaded from your secret manager |
TypeScript example
Request a token, then get glossary results:
const tokenResponse = await fetch(
`${process.env.PULSE_CONTEXT_AUTH0_ISSUER_URL}/oauth/token`,
{
method: "POST",
headers: { "content-type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "client_credentials",
client_id: process.env.PULSE_CONTEXT_AUTH0_CLIENT_ID ?? "",
client_secret: process.env.PULSE_CONTEXT_AUTH0_CLIENT_SECRET ?? "",
audience: "https://1komma5grad.com/api",
}),
},
);
const token = await tokenResponse.json() as { access_token: string };
const glossaryResponse = await fetch(
"https://pulse-context.1komma5grad.com/v1/glossary/search",
{
method: "POST",
headers: {
authorization: `Bearer ${token.access_token}`,
"content-type": "application/json",
},
body: JSON.stringify({ queries: ["heartbeat"], limit: 3 }),
},
);
console.log(await glossaryResponse.json());Run it with Bun after setting the environment variables:
bun examples/pulse-context-authentication.ts
Cache and reuse the access token until shortly before expiry in long-running services. Do not request a new token for every API call.