Auth Callout
Last updated
Last updated
As of NATS v2.10.0
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 refers to all authentication and authorization mechanisms that are server config file-based.
Refer to the end-to-end example to get oriented with a basic service implementation.
There are three key data structures:
Language support for these structures currently exists for Go in the nats-io/jwt package.
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.
For centralized auth callout, configuration is declared in the auth_callout
block under the top-level authorization
block.
The available properties in the auth_callout
block include:
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.
☝️ Be sure to generate your own keypair! Don't use this in production.
This minimum configuration would use the implicit default account $G
.
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.
The xkey
property enables encrypting the request payloads. This is recommended as a security best practice, but not required.
To generate an XKey, nsc
can be used again.
☝️ Again, don't use this and be sure to generate your own and keep the seed secret!
Incorporating the xkey
, we have the following config:
Coming soon!
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.
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.
The claims is a standard JWT structure with a nested object named nats
containing the following top-level fields:
jwt
- The encoded user claims JWT which will be used by the NATS server for the duration of the client connection.
error
- An error message sent back to the NATS server if authorization failed. This will be included log output.
issuer_account
- The public Nkey of the issuing account. If set, this indicates the claim was issued by a signing key.
The claims is a standard JWT structure with a nested object named nats
containing the following, notable, top-level fields:
issuer_account
- The public Nkey of the issuing account. If set, this indicates the claim was issued by a signing key.