IntegrAuth Academy
Identity, security and practical AI — free, from zero. Byte-sized lessons, real diagrams, hands-on labs, zero fluff. Two programs, each with its own exam and certificate.
English is hard? Your browser can translate this page into Tamil, Telugu, Kannada, Malayalam or Hindi. Tech words stay in English so you learn the real names.
How?
- Chrome on phone: ⋮ menu → Translate
- Chrome on computer: right-click → Translate to …
- Edge: the translate icon in the address bar
Machine login — client credentials
It is 2 a.m. Bot A must download last night's invoices. No person is awake to click "yes". So the bot logs in as itself. Your goal: explain machine login and pick a safe way for a bot to prove who it is.
- Client credentials is a login for software with no person involved.
- The token is about the bot, so there is no consent screen.
- Bots usually get no refresh token. They just ask again.
- Prefer a signed key or certificate over a shared secret.
- Give the bot the smallest scope for its one job.
No person to ask
Other logins send a person through a browser. A background job has no browser and no human. So it uses a different door.
That door is the client credentials grant. It is part of OAuth 2.0 (RFC 6749). The software proves who it is and gets a token for itself, such as "This is Bot A, allowed to read invoices". No user is involved, so the client is the subject.
That is why there is no consent screen. A consent screen asks a human, "Do you allow this app to act for you?" Here nobody can be asked. Bot A is one of the non-human identities from the NHI lesson.
Why there is usually no refresh token
A person often gets a long-lived refresh token, so they need not sign in again every few minutes. A bot does not need that. When its access token ends, it repeats the request and gets a new one. A long-lived refresh token is one more strong secret to lose.
Three ways to prove you are the machine
There are three common ways, and they are not equal. Think of a ladder. Each higher rung keeps the real secret farther from the network.
a bank counter. A shared secret is a PIN you say out loud each time. Anyone who hears it can use it. A private_key_jwt is your signature on a cheque. The bank keeps only a specimen copy to compare. A copy of the specimen does not let anyone sign for you.
🔑 Shared secret
A long password the bot sends on every call. It is easy to set up. But the secret itself travels, and anyone who copies it can pose as the bot. Fine to start, but climb off it.
✍️ private_key_jwt
The bot signs a tiny message with a private key and sends only the signature. This is a client assertion (RFC 7523). The IdP checks it with the public key. The private key never leaves the bot. See private_key_jwt.
📜 mTLS certificate
mTLS (RFC 8705) moves the proof into the connection. The bot shows a client certificate, and its private key stays on the machine. Without the right key, the handshake fails.
Scope it to one job
Bot A reads invoices, so give its token the narrowest scope. Use invoices:read, not invoices:read invoices:write admin. If the token leaks, the damage is small. API keys vs OAuth helps you choose between this and a plain API key.
Machine credentials are more often pasted than hacked. A secret lands in a public repo or a build log. A leaked shared secret is game over until you replace it everywhere. A leaked config that only points to a key in a vault or HSM (hardware security module) exposes nothing that can sign. Keep secrets in a vault. Rotate them on a schedule.
Go deeper: more on machine login
The OAuth 2.1 draft keeps client credentials. A request using private_key_jwt sends client_assertion_type and client_assertion in the body. The assertion is signed, so no reusable secret crosses the network.
A long-lived refresh token for a bot adds risk and no benefit. Skipping the proof of identity would be a weakness, not a gain.
Now play it. The lab follows Bot A's 2 a.m. login step by step. Then you break it, and at the end you leak the credential to see what survives.
🧪 Interactive lab — enable JavaScript to play with this one.
Build and check a private_key_jwt assertion with Client Assertion Check. Grade the certificate behind an mTLS client with Cert Lint.