Client Credentials M2M
Il grant OAuth2 client_credentials consente ai servizi backend, agli script automatizzati e ai job cron di ottenere access token senza interazione umana. Questi token M2M (Machine-to-Machine) vengono usati per autenticare le chiamate API da servizio a servizio.
Come Funziona
- Il servizio invia le proprie credenziali (client ID + secret) all’endpoint token di Auris
- Auris verifica le credenziali e controlla gli scope richiesti
- Auris emette un access token JWT di breve durata con gli scope concessi
- Il servizio include il token nell’header
Authorization: Bearernelle chiamate API
Non è coinvolto nessun utente — è il servizio stesso il “principal” autenticato.
Configurazione nella Console
Crea un’Applicazione M2M
Vai su Console → Applicazioni → Nuova Applicazione e seleziona Machine-to-Machine (M2M).
Assegna gli Scope
Nella scheda Permissions, assegna gli scope che questo servizio può richiedere. Usa il principio del minimo privilegio — concedi solo gli scope necessari.
Copia le Credenziali
Dalla scheda Credenziali, copia:
- Client ID
- Client Secret (mostrato una sola volta — conservalo in modo sicuro)
Implementazione
JavaScript
const AURIS_DOMAIN = 'https://auth.tuodominio.com'
const CLIENT_ID = 'il-tuo-client-id'
const CLIENT_SECRET = process.env.AURIS_CLIENT_SECRET
async function getM2MToken(scopes = []) {
const response = await fetch(`${AURIS_DOMAIN}/api/auth/token`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
scope: scopes.join(' '),
}),
})
if (!response.ok) {
throw new Error(`Token request failed: ${response.status}`)
}
return response.json()
}
// Uso
const { access_token, expires_in } = await getM2MToken(['read:users', 'write:logs'])
// Chiama un'API protetta
const users = await fetch('https://api.tuodominio.com/users', {
headers: { 'Authorization': `Bearer ${access_token}` },
}).then(r => r.json())Formato del Token M2M
I token M2M sono JWT standard con questi claim aggiuntivi:
{
"iss": "https://auth.tuodominio.com",
"sub": "il-tuo-client-id",
"aud": "https://api.tuodominio.com",
"exp": 1735689600,
"iat": 1735686000,
"scope": "read:users manage:billing",
"type": "m2m",
"tenant_id": "ten_abc123"
}Il campo type: "m2m" distingue i token M2M dai token utente. Puoi controllare questo claim nelle tue API per applicare policy diverse.
Caching dei Token
I token M2M sono validi tipicamente per 1 ora. Per evitare di richiedere un nuovo token ad ogni chiamata API, usa il caching:
Non richiedere un nuovo token M2M per ogni chiamata API. Questo sovraccarica Auris e introduce latenza inutile. Usa sempre il caching con rinnovo basato sulla scadenza, come mostrato nell’esempio Next.js sopra.
Token Binding con DPoP
Per una sicurezza maggiore, puoi legare il token M2M alla chiave del client usando DPoP (Demonstrating Proof of Possession):
import { createDpopProof } from '@auris/js/dpop'
// Genera una coppia di chiavi DPoP
const { privateKey, publicKey } = await crypto.subtle.generateKey(
{ name: 'ECDSA', namedCurve: 'P-256' },
true,
['sign', 'verify']
)
// Crea la proof DPoP
const dpopProof = await createDpopProof({
method: 'POST',
url: `${AURIS_DOMAIN}/api/auth/token`,
privateKey,
publicKey,
})
// Richiedi il token con DPoP
const response = await fetch(`${AURIS_DOMAIN}/api/auth/token`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'DPoP': dpopProof,
},
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
scope: 'read:users',
}),
})Consulta la guida DPoP per i dettagli completi.
Proteggere le Proprie API con Token M2M
Per validare i token M2M nelle tue API:
import jwt from 'jsonwebtoken'
import jwksClient from 'jwks-rsa'
const client = jwksClient({
jwksUri: 'https://auth.tuodominio.com/.well-known/jwks.json',
})
async function verifyM2MToken(token) {
const decoded = jwt.decode(token, { complete: true })
const key = await client.getSigningKey(decoded.header.kid)
const publicKey = key.getPublicKey()
const payload = jwt.verify(token, publicKey, {
issuer: 'https://auth.tuodominio.com',
audience: 'https://api.tuodominio.com',
})
// Verifica che sia un token M2M
if (payload.type !== 'm2m') {
throw new Error('Not an M2M token')
}
// Verifica gli scope richiesti
const scopes = payload.scope?.split(' ') ?? []
if (!scopes.includes('read:users')) {
throw new Error('Insufficient scope')
}
return payload
}Endpoint API
/api/auth/tokenToken endpoint. Per M2M, imposta grant_type=client_credentials con client_id, client_secret e scope. Restituisce un access token JWT.
/api/applications/{id}/scopesRequires: view:applicationsElenca gli scope disponibili per un’applicazione M2M.
/api/applications/{id}/scopesRequires: manage:applicationsAggiorna gli scope assegnati a un’applicazione M2M.
Guide Correlate
- DPoP — Token binding per sicurezza avanzata
- Login Ospitato (PKCE) — Flusso interattivo per utenti umani
- CIBA (Backchannel Auth) — Autenticazione decoupled per scenari avanzati
- Token (Concetto) — Approfondimento sul formato JWT e i claim