Auth Callout is an opt-in extension for delegating client authentication and authorization to an application-defined NATS service.
The motivation for this extension is to support applications using an alternate identity and access management (IAM) backend as the source of truth for managing users/applications/machines credentials and permissions. This could be services that implement standard protocols such as LDAP, SAML, and OAuth, an ad-hoc database, or even a file on disk.
Both centralized and decentralized authentication models are supported with slightly different considerations and semantics.
There are three phases to leveraging auth callout:
service implementation
migration considerations
setup and configuration
Note, the setup and configuration is deliberately last since enabling the configuration before deploying a service could cause issues for existing systems.
Centralized Auth
Centralized auth refers to all authentication and authorization mechanisms that are server config file-based.
Service implementation
Refer to the end-to-end example to get oriented with a basic service implementation.
Language support for these structures currently exists for Go in the nats-io/jwt package.
Migration considerations
In this context, migration refers to the considerations and steps required to enable auth callout for an existing system without causing interruption.
In the centralized model, existing users defined in the config file will be ignored. The auth service will need to handle authenticating all users as well as assigning the target account and permissions. This includes the system account user(s) and an implicit "no auth" user.
As a result, prior to enabling auth callout, existing users and permissions must be ported to the target backend. Once the service is deployed, the auth_callout configuration can be enabled at which point client authentication will be delegated to the auth service. Assuming the credentials are the same, clients should not experience interruption on reconnect.
Setup and configuration
For centralized auth callout, configuration is declared in the auth_callout block under the top-level authorization block.
authorization {
auth_callout {
...
}
}
The available properties in the auth_callout block include:
Property
Description
issuer
The public key of the designated NKey used for signing authorization payloads.
auth_users
The list of user names under account that are designated auth callout users.
account
The account containing the users that are designated auth callout users. Defaults to the global account ($G).
xkey
Optional. The public key of a designated XKey (x25519) used for encrypting authorization payloads.
To generate the account issuer NKey, the nsc tool can be used.
This minimum configuration would use the implicit default account $G.
Multiple accounts
If an existing system using multiple accounts is being migrated to auth callout, then the existing accounts configuration should remain with the users property removed (since it will no longer be used after being ported).
For new setups, it is recommended to use explicit accounts, such as the following configuration having the AUTH account for auth callout, APP (could be more) for application account (instead of relying on the $G account), and SYS for the system account.
When encryption is enabled, the server will generate a one-time use XKey keypair per client connection/reconnect. The public key is included in the authorization request claims which enables the auth callout service to encrypt the authorization response payload when sending it back to the NATS server.
The one-time use keypair prevents replay attacks since the public key will be thrown away after the first response was received by the server or the timeout was reached.
Once the authorization request is prepared, it is encoded and encrypted using the configured xkey public key. Once encrypted, the message is published for the auth service to receive.
The auth service is expected to have the private key to decrypt the authorization request before using the claims data. When preparing the response, the server-provided one-time public xkey will be used to encrypt the response before sending back to the server.
Schema
Authorization request claims
The claims is a standard JWT structure with a nested object named nats containing the following top-level fields:
server_id - An object describing the NATS server, include the id field needed to be used in the authorization response.
user_nkey - A user public NKey generated by the NATS server which is used as the subject of the authorization response.
client_info - An object describing the client attempting to connect.
connect_opts - An object containing the data sent by client in the CONNECT message.
client_tls - An object containing any client certificates, if applicable.