nats-server
nats-server copied to clipboard
Allow callout issuer to issue token for a different account in server mode
Feature Request
ADR-26 states: "The response to the request will be a signed user JWT that must be signed by the declared issuer in server configuration mode or an account signing key in operator mode". No rational is given for this constraint and it doesn't seem to solve a problem.
The feature request is to allow a different account signing key in server configuration mode as well.
Use Case:
To enhance security it is good practice to use a separate callout account from the application account. After all, authentication is a completely different task than that what the application performs. Constraining the JWT signing account to the callout issuing account (in server mode) would mean that when using callouts only a single account can be used.
A second use case is to use callout to issue tokens for different accounts. This allows multi-tenancy on an edge device. While rare it is a valid case.
Proposed Change:
Allow signing the user JWT by any account known to the server.
Who Benefits From The Change(s)?
Embedded systems will be able to apply best security practices by separating authn handling from the application.
Alternative Approaches
Use operator mode, but that might not be practical in an edge device.
On a related note, the difference between operator mode and server mode in callout handling is totally confusing. My concern is that this leads to a lot of questions for a long time to come. As this isn't released yet, this is a last chance to make the behavior more consistent.
A couple of pain points:
- The server AuthCallout config struct has an 'Issuer" field, which is the public account key of the JWT issuer. However, this only applies to operator mode. This isn't documented. When setting this in server mode, callout handling fails with an error. Why not allow it for server mode? :confused:
- The same callout struct also has an Account field. This expects the account name. This is required for server mode (not sure about operator mode). It is not clear this fields requires a name. Why name the public key 'issuer' and account name 'account'. Suggest a more descriptive name 'IssuerAccountPub' and 'IssuerAccountName'.
- When issuing a JWT token (jwt.NewUserClaims), in server mode the 'IssuerAccount field must not be set otherwise this causes an error. However, in operator mode this is required.
- The 'audience' field of the token expects the Account name in server mode, but account public key in operator mode. This is very confusing. See also issue 4313.
This all seems to be related to not allowing issuing JWT for a different account in server mode. Recommended solution:
- Make configuration of callout identical for server and operator mode. Same requirement and same fields. Even if one field isn't used (right now) it should be required. This allows future enhancement without the pain.
- If there has to be an account restriction for server mode, then just fail with an error during the setup check, stating that in server mode the issuer account must be the same as the callout account.
I was trying to research about this topic and found this section:
https://github.com/nats-io/nats-architecture-and-design/blob/main/adr/ADR-26.md#changing-accounts
That seems to say that it is possible to do what is requested, or am I misreading it?
Yes you can change accounts.