Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/charbonnierg/caddy-nats
https://github.com/charbonnierg/caddy-nats
Last synced: about 2 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/charbonnierg/caddy-nats
- Owner: charbonnierg
- Created: 2023-09-17T07:01:40.000Z (over 1 year ago)
- Default Branch: rewrite
- Last Pushed: 2023-11-20T13:36:22.000Z (about 1 year ago)
- Last Synced: 2023-11-21T13:33:37.608Z (about 1 year ago)
- Language: Go
- Size: 2.17 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# caddy-nats (EXPERIMENTAL)
> Run `nats-server` as a [caddy app](https://caddyserver.com/docs/extending-caddy#app-modules) with experimental oauth2 authentication.
## Introduction
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 reference for Auth Callout is in the [ADR-26: NATS Authorization Callouts](https://github.com/nats-io/nats-architecture-and-design/blob/main/adr/ADR-26.md)
As stated in the ADR, Authorization Callout aims to enable an external NATS service to generate NATS authorization and credentials by authenticating connection requests.
[The documentation](https://docs.nats.io/running-a-nats-service/configuration/securing_nats/auth_callout) helps understanding the usecases:
> 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.
Since this feature is quite new, there isn't much documentation aside from the two links above ([ADR-26](https://github.com/nats-io/nats-architecture-and-design/blob/main/adr/ADR-26.md) and [NATS docs](https://github.com/nats-io/nats-architecture-and-design/blob/main/adr/ADR-26.md)), but we can at least draw a few things:
- Authorization callout addresses the need for external authentication/authorization
- Authorization callout is performed by a service which connects to the NATS server (not the NATS server itself)
- Auth callout service receives an authorization request and must return either an error or a signed authorization responseAssuming that a project wants OAuth2 authenticated web users to connect to NATS using authorization callout, the following components are required:
- a NATS server configured to use authorization callout
- an HTTP server to serve the web application
- an OAuth2 middleware to ensure that HTTP sessions are authenticated and authorized
- an auth callout NATS service connected to the NATS server and verifying session state before issuing user claimsThe goal of this repository is to provide a single executable binary, which will act as:
- a NATS server
- a NATS authorization callout service
- an HTTP server
- an Oauth2 middlewareIt means that no additional software or components should be required in order to authenticate, authorize and allow users to connect to NATS.
## Introduction to caddy
[Caddy](https://caddyserver.com/) is ...
## Introduction to oauth2-proxy
OAuth2 is not trivial to implement (even though lots of libraries exist to help developers integrate OAuth2 authorization into their applications). In order to avoid writing an OAuth2 middleware, I decided to reuse the existing project [oauth2-proxy](https://github.com/oauth2-proxy/oauth2-proxy). This project is used by many companies or other open sources projects, has more than 300 contributors, and approximately 7600 stars on GitHub. Because this project is a **server** component, it cannot be integrated directly into an existing Go application. I had to [make a fork to use oauth2-proxy](https://github.com/oauth2-proxy/oauth2-proxy/compare/master...charbonnierg:oauth2-proxy:library_usage) in order to easily create a [caddy module](https://github.com/charbonnierg/caddy-nats/blob/rewrite/oauthproxy/app.go). This caddy module is an HTTP middleware which can be used before other caddy modules to authenticate and authorize an HTTP session.
## Example usage
- First build the project:
```bash
go build ./cmd/caddy
```- Allow caddy to bind to port 80 and 443:
```bash
sudo setcap cap_net_bind_service=+ep ./caddy
```- Update the `apps.oauth2` section of the example config. Configuration supports almost all oauth2-proxy options (check the file ./oauthproxy/json_options.go)
⚠ example config won't run without change, because it uses Azure Provider with fake data.
Start the example:
```bash
./caddy run -c example.json
```- Visit `https://localhost`. You should be redirected to configured OAuth2 provider to authenticate. Once authentication is succesfull, you should be redirected back to `https://localhost` and see metrics displayed in the page.
- Open Developer Tools and connect to NATS using oauth2 auth callout:
```javascript
const nats = await import("https://cdn.jsdelivr.net/npm/[email protected]/esm/nats.js")nc = await nats.connect(
{"servers": "wss://localhost:10443", "user": "APP", "pass": document.cookie}
)await nc.publish("test")
```- Checkout server logs to see that user was authorized by auth callout module and message was successfully published under account `APP`
- Now open a terminal and try to connect using NATS cli:
```bash
nats pub foo bar
```An authorization error should be returned, because no username is provided.
- Let's try to connect using SYS account:
```bash
nats server ls --username SYS --password "not used"
```> Note: password option is provided because NATS CLI does not send username if no password is provided. However, code using SDK from supported languages can send a connect request with username only.
The command should succeed, because the matcher for SYS username is configured to handle auth request with `always_allow` handler.
### Caddyfile
No support for caddyfile at the moment.
### JSON file
Checkout the file [example.json](./example.json) to see how to configure an NATS server with TLS certificates managed by caddy and auth callout service running as caddy module.
## Next steps
- Use replacers to avoid writing signing key in config
- Add tests
- Add Caddyfile support
- Add auth callout modules (maybe a module validating ID tokens provided by users in connect options ❔)