I got this question in an interview:
If the authentication service generates a JWT, how do all the other microservices know that the JWT is valid?
It sounds like a question about JWT syntax. It is really a question about trust.
Imagine a shopping application with three microservices. The auth service handles login. The order service returns a user's orders. The billing service handles payments. Each service is a separate backend program, and each can receive requests directly.
The user logs in through the auth service and gets a JWT. A few seconds later, the user's browser sends that JWT to the order service. The order service never saw the password and did not create the token. Why should it believe anything inside it?
The order service has to judge data supplied by a client using a token created somewhere else.
What the order service needs to prove
A JWT usually has three parts:
header.payload.signatureThe header describes the token. The payload contains claims such as the user ID and role. The signature protects those values from being changed without detection.
The payload is not encrypted. Anyone holding the token can decode and read it. That is why passwords, card details, and other secrets do not belong there.
Suppose the payload says:
{
"sub": "user_42",
"role": "user"
}The client could change "user" to "admin", but it cannot produce the correct signature for the edited payload without the signing key. The order service checks the signature before trusting the role. If the payload changed, the check fails.
So "Is this JWT valid?" starts with two smaller questions:
- Was this token signed by an issuer I trust?
- Has anyone changed it since it was signed?
Verifying the signature with a key the order service already trusts answers both. Think of the signature as a tamper-evident seal, not a lock. The order service verifies the seal; it does not decrypt the token.
Symmetric and asymmetric signing
Before comparing HS256 and RS256, it helps to separate the two key models behind them.
Symmetric signing uses one shared secret. The same secret signs a token and verifies it. Anyone who can do one job can do the other.
Asymmetric signing uses a key pair. The private key signs tokens, while the public key verifies them. The keys are mathematically related, but the public key cannot be used to recreate the private key or produce a valid signature.
HS256 and RS256 are JWT algorithm identifiers:
- HS256 means HMAC using SHA-256. It is symmetric and uses one shared secret.
- RS256 means an RSA signature using SHA-256. It is asymmetric and uses a private-public key pair.
The 256 in both names refers to SHA-256. It does not mean the algorithms use the same kind of key.
| Key model | JWT algorithm | Signing | Verification |
|---|---|---|---|
| Symmetric | HS256 | Shared secret | The same shared secret |
| Asymmetric | RS256 | Private key | Public key |
This difference decides which services are capable of creating tokens, not just which cryptographic function runs.
Why symmetric HS256 works neatly on one backend
Start with a single backend that handles login and orders.
The backend creates a JWT after login. When the client returns with that token, the same backend verifies it. HS256 is a natural fit here because one secret performs both operations.
Only the backend knows the secret. The browser never receives it. If someone edits the token, the signature no longer matches.
Nothing is wrong with this design.
The symmetric problem appears when the secret is copied
Now split that backend into an auth service, an order service, and a billing service.
The auth service still needs the HS256 secret to sign tokens. The order service and billing service also need that secret if they are going to verify those tokens locally.
Here is the catch: HS256 uses the same secret for signing and verification. A service that can verify a token can also create one.
The order service was supposed to check tokens, not issue them. Copying the secret gives it both powers anyway.
That expands the damage from a compromised service. Suppose an attacker gets into the order service and reads its environment variables. They steal the shared secret, create a JWT that says "role": "admin", and sign it themselves.
Then they send that token to the billing service.
The billing service accepts the token because its verification is working correctly. The signature really is valid. HS256 cannot tell whether the auth service or the attacker created it because both used the same secret.
This is the point worth remembering: HS256 itself did not become weak. Sharing its secret changed the security boundary. Compromising any service that holds the secret now compromises every service that trusts it.
Asymmetric RS256 separates signing from verification
The order service needs a way to verify tokens without gaining the ability to create them. That requires two different keys with two different powers.
The auth service generates an RSA key pair. It keeps the private key secret and distributes the public key to the services that need to verify JWTs. This setup happens before requests begin flowing.
When a user logs in, the auth service signs the JWT with its private key. Later, the order service receives the JWT and checks its signature with the public key. If the check passes, the order service knows that the matching private key signed the token and that its contents have not changed.
The two keys have separate jobs:
- A private key signs tokens.
- A public key verifies signatures.
The auth service keeps the private key. It is the only service allowed to sign JWTs. The order service and billing service receive the public key, which they use to verify tokens locally.
The order service does not call the auth service during this request. Signature verification happens inside the order service using the public key it already has.
The public key can confirm that the matching private key produced a signature. It cannot produce a new valid signature. An attacker who compromises the order service may steal its public key, but that key was never secret and cannot be used to forge a token.
The division of responsibility now matches the architecture:
| Service | Key it holds | What it can do |
|---|---|---|
| Auth service | Private key | Sign tokens |
| Order service | Public key | Verify tokens |
| Billing service | Public key | Verify tokens |
The auth service issues the token. The other services check it without inheriting the auth service's signing power.
Calling the auth service on every request
The order service could send every token back to the auth service and ask, "Did you issue this?"
That design is sometimes useful when permissions must be checked centrally and revoked immediately. But it also adds a network call to every request. If the auth service is slow or unavailable, the order service is slow or unavailable too.
Local JWT verification avoids that dependency. The order service can verify the signature using key material it already has. This is one reason signed tokens work well across independently deployed services.
The tradeoff is that a signed token remains valid until it expires. If a user's access changes, an already issued token does not learn about that change by itself. Short-lived access tokens limit that window.
Choosing between HS256 and RS256
The useful rule is about trust boundaries, not the number of boxes in an architecture diagram.
- If one trusted application both signs and verifies its own tokens, HS256 can be enough.
- If several services need to verify tokens but only the auth service should issue them, use an asymmetric algorithm such as RS256.
Do not reduce this to "HS256 is bad." HMAC is strong cryptography. The problem is handing a signing secret to services that should have verification-only access.
A valid signature is only the first check
Once the signature passes, a service still checks whether the token has expired, whether it came from the expected issuer, and whether it was intended for that service.
Those checks answer a different question: "Should I accept this correctly signed token here and now?" The public-key design answers the question at the center of this article: "Who was capable of signing it?"
The answer I would give in an interview
Here is the short version:
The auth service signs the JWT, and the other microservices verify its signature locally. HS256 is symmetric, so signing and verification use the same shared secret. Every service that can verify can also create valid tokens. RS256 is asymmetric, so the auth service keeps the private signing key while the other services receive only the public verification key. They can confirm that the auth service issued the token without calling it and without gaining the ability to forge one.
If the interviewer asks why the signature is enough, add this:
The signature covers the JWT header and payload. If someone changes a claim, such as the user's role, the signature check fails. After that check passes, the service still validates claims such as expiration and issuer.
Many services can verify the token. Only the auth service can sign one.







