Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic append headers for clients messages #5407

Open
ramonberrutti opened this issue May 10, 2024 · 4 comments
Open

Dynamic append headers for clients messages #5407

ramonberrutti opened this issue May 10, 2024 · 4 comments
Labels
proposal Enhancement idea or proposal

Comments

@ramonberrutti
Copy link
Contributor

Proposed change

Background

I currently use NATS (v2.11) embedded as a leaf node, allowing clients to connect via WebSocket (nats.ws). This setup facilitates real-time communication and data exchange across distributed systems.

I'm handling authentication using CustomClientAuthentication registering the user with RegisterUser using an onlyHttp cookie inaccessible by javascript and I don't want to to expose the credentials to javascript.

Each client can call an RPC function in the main cluster (Nats Service) and subscribe to a predefined inbox.

Current Limitation

The biggest issue is identifying each user/token. As the client can't access the token, adding it as a header is impossible.

Proposed Solution

I propose a new feature that automatically includes metadata headers for each client when publishing a message. This feature will enable me to append crucial authentication and identification data without client-side exposure.

Technical Details

  • Modify the processInboundClientMsg() function to inject metadata headers
  • Metadata headers will use a designated prefix, ensuring they can be easily identified and stripped when messages are directed towards JetStream, preserving system integrity.
  • Assess the impact of these changes on performance and devise strategies to minimize overhead.
  • Define how JWT, config and RegisterUser will include the metadata headers.

Alternatively, I considered adding a Middleware for each message when using nats embedded, but I decided against it because multiple things can go wrong.

Use case

A typical use case involves a client connecting to my system via a secure WebSocket. Upon connection, the client is authenticated using a cookie inaccessible by JavaScript. NATS then handles the token internally, appending it to the message headers as it routes messages through the system.

Including metadata such as IP, client version, connection time, and TLS certificate for each message will allow the downstream service to know more about the client.

Contribution

If the proposal is accepted, I would like to implement the feature :)

I believe that this feature needs an ADR in https://github.com/nats-io/nats-architecture-and-design

@ramonberrutti ramonberrutti added the proposal Enhancement idea or proposal label May 10, 2024
@ramonberrutti
Copy link
Contributor Author

Related to: #5147

@derekcollison
Copy link
Member

Have you tried exporting the service and importing it to the same account? That will attach a header with all the client info known by the system.

@ramonberrutti
Copy link
Contributor Author

Have you tried exporting the service and importing it to the same account? That will attach a header with all the client info known by the system.

I tried:

	account := server.NewAccount("$G")
	if err := account.AddServiceExport(">", []*server.Account{account}); err != nil {
		panic(fmt.Errorf("error adding service export: %s", err))
	}

	if err := account.AddServiceImport(account, ">", ">"); err != nil {
		panic(fmt.Errorf("error adding service import: %s", err))
	}

	if err := account.SetServiceImportSharing(account, ">", true); err != nil {
		panic(fmt.Errorf("error setting service import sharing: %s", err))
	}

It works. I need to do a mapping to prevent duplicate messages.

Its works. Are there any performance implications?

@derekcollison
Copy link
Member

I would not do it blanket style like that, just for the endpoints you really need the information. Yes there is a perf impact of course.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal Enhancement idea or proposal
Projects
None yet
Development

No branches or pull requests

2 participants