A Python library for implementing NATS Auth Callout consumers, enabling dynamic authentication and authorization for NATS clients.
Project description
nats-callout
A Python library for implementing NATS Auth Callout consumers, enabling dynamic authentication and authorization for NATS clients.
What is Auth Callout?
Auth callout is a mechanism in NATS that delegates authentication and authorization to an external service, instead of relying only on static configuration. This allows you to integrate existing identity and access systems like databases, OAuth providers, LDAP, or even simple local checks.
It’s especially valuable in dynamic environments (e.g., browser WebSocket clients) where you need to grant fine-grained and time-sensitive permissions to specific subjects, streams, or key-value stores, rather than relying on preconfigured user definitions.
How it works:
- A client connects to the NATS server using basic credentials (e.g., token, password).
- The NATS server issues an authentication request by publishing a message on the system subject:
$SYS.REQ.USER.AUTH - An external auth consumer subscribes to this subject, receives the request, and decides if the client is allowed.
- The consumer replies with an authorization response, including permissions and limitations that will be enforced for that client session.
Installation
Install with uv:
uv add nats-callout
Or with pip:
pip install nats-callout
Usage Example (FastStream Framework)
Below is an example of how to use nats-callout with FastStream to implement an Auth Callout consumer:
from faststream import FastStream, NatsBroker, Depends
from nats_callout import BaseAuthCalloutService, AdaptixEncoder, AuthError
from nats_callout.claims import AuthRequestData, UserData, PubSubPermissions
broker = NatsBroker("nats://localhost:4222")
app = FastStream(broker)
# encoder for auth callout service
# by default, we use adaptix with standard json encoding
encoder = AdaptixEncoder()
# Implement your own AuthCalloutService
class AuthCalloutService(BaseAuthCalloutService):
def __init__(
self,
nats_config: NatsConfig,
db_context: DBContext,
):
self.encoder = encoder
self.nkey_seed = nats_config.nkey_seed
self.db_context = db_context
async def _handle_auth_request_data(self, auth_request_data: AuthRequestData) -> UserData:
connect_opts = auth_request_data.connect_opts
# any checks here
token = connect_opts.auth_token
if not token:
raise AuthError("no token provided")
user = await self.db_context.get_user_by_token(token)
if not user:
raise AuthError("invalid token")
user_data = UserData(
pub=PubSubPermissions(allow=["foo"], deny=[]),
sub=PubSubPermissions(allow=["bar"], deny=[]),
version=auth_request_data.version,
tags=auth_request_data.tags,
)
return user_data
# inject your service and other dependencies to the handler conveniently (e.g., using FastStream Depends or Dishka)
@broker.subscriber("$SYS.REQ.USER.AUTH")
async def handle_auth_request(body: str, auth_callout_service: AuthCalloutService):
response = await auth_callout_service(body)
return response
if __name__ == "__main__":
app.run()
TODOs
- Add support for synchronous (sync) callout service
- Add the possibility to include custom JWT claims (e.g., nbf and others)
- Make the
adaptixan optional dependency
Reference
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nats_callout-0.1.1.tar.gz.
File metadata
- Download URL: nats_callout-0.1.1.tar.gz
- Upload date:
- Size: 19.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2123a7a5ca2e89b9164b6a48884b25d0e3b7d85a1ccfa6769e2fcc5c9bd0a4d3
|
|
| MD5 |
d1328067356235921a3611da1e2a3ed8
|
|
| BLAKE2b-256 |
358e32fd83a092ef07ee6ea67759b94ab14bc94d318c0a565d20383799713aee
|
File details
Details for the file nats_callout-0.1.1-py3-none-any.whl.
File metadata
- Download URL: nats_callout-0.1.1-py3-none-any.whl
- Upload date:
- Size: 14.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f77a01b66d7e483ef960ba3e3aa9e64087a8a93de61676f7223a0897be579d67
|
|
| MD5 |
ffbbfb5e3ce4d756ab79be2742671c08
|
|
| BLAKE2b-256 |
356699ebfb63cb0309f63142e8e24b9a5520bbc62d8d51dc217f085687078fae
|