mirror of
https://github.com/taigrr/nats.docs
synced 2025-01-18 04:03:23 -08:00
GitBook: [master] 61 pages modified
This commit is contained in:
committed by
gitbook-bot
parent
ed6c1ba06d
commit
de933e912d
@@ -1,12 +1,10 @@
|
||||
# Decentralized JWT Authentication and Authorization
|
||||
# Decentralized JWT Authentication/Authorization
|
||||
|
||||
With other authentication mechanisms, configuration for identifying a user and [Account](../accounts.md), is in the server configuration file. JWT authentication leverages [JSON Web Tokens \(JWT\)](https://jwt.io/) to describe the various entities supported. When a client connects, servers verify the authenticity of the request using [NKeys](../auth_intro/nkey_auth.md), download account information and validate a trust chain. Users are not directly tracked by the server, but rather verified as and belonging to an [Account](../accounts.md). This enables the management of users, without requiring server configuration updates.
|
||||
|
||||
Effectively, JWTs improve accounts and provide for a **distributed configuration paradigm**. Previously each user \(or client\) needed to be known and authorized a priori in the server’s configuration requiring an administrator to modify and update server configurations. These chores are eliminated. User creation can can even be performed by different entities altogether.
|
||||
Effectively, JWTs improve accounts and provide for a **distributed configuration paradigm**. Previously each user \(or client\) needed to be known and authorized a priori in the server’s configuration requiring an administrator to modify and update server configurations. These chores are eliminated. User creation can can even be performed by different entities altogether.
|
||||
|
||||
> Note: This scheme improves [accounts](../accounts.md). Functionalities like [isolation](../accounts.md) or defining [exports/imports](../accounts.md#exporting-and-importing) between accounts remain!
|
||||
> It moves configuration of accounts, exports/imports or users and their permissions away from the server into several trusted [JSON Web Token \(JWT\)](https://jwt.io/) that are managed separately, therefore removing the need to configure these entities in each and every server.
|
||||
> It furthermore adds functionalities like expiration and revocation fore decentralized account management
|
||||
> Note: This scheme improves [accounts](../accounts.md). Functionalities like [isolation](../accounts.md) or defining [exports/imports](../accounts.md#exporting-and-importing) between accounts remain! It moves configuration of accounts, exports/imports or users and their permissions away from the server into several trusted [JSON Web Token \(JWT\)](https://jwt.io/) that are managed separately, therefore removing the need to configure these entities in each and every server. It furthermore adds functionalities like expiration and revocation fore decentralized account management
|
||||
|
||||
## JSON Web Tokens
|
||||
|
||||
@@ -56,23 +54,13 @@ Lastly, all NATS JWTs \(Operators, Accounts, Users and others\) are expected to
|
||||
|
||||
## Decentralized Authentication and Authorization - Configuration
|
||||
|
||||
Configuration is broken up into separate steps.
|
||||
Depending on organizational needs these are performed by the same or different entities.
|
||||
Configuration is broken up into separate steps. Depending on organizational needs these are performed by the same or different entities.
|
||||
|
||||
JWT configuration is done using the [`nsc` tool](../../../../nats-tools/nsc/README.md).
|
||||
It can be set up to issue [NKeys](../auth_intro/nkey_auth.md) and corresponding JWTs for all [nkey roles](#nkey-roles): Operator/Account/User \([Example usage](../../../../nats-tools/nsc/nsc.md#creating-an-operator-account-and-user)\).
|
||||
Despite Account and User creation not happening in server configuration, this model is a centralized authentication and authorization setup.
|
||||
JWT configuration is done using the [`nsc` tool](../../../../nats-tools/nsc/). It can be set up to issue [NKeys](../auth_intro/nkey_auth.md) and corresponding JWTs for all [nkey roles](./#nkey-roles): Operator/Account/User \([Example usage](../../../../nats-tools/nsc/nsc.md#creating-an-operator-account-and-user)\). Despite Account and User creation not happening in server configuration, this model is a centralized authentication and authorization setup.
|
||||
|
||||
Provided institutional trust, it is also possible to use nsc to import account or user public [NKeys](../auth_intro/nkey_auth.md) and issue corresponding JWTs.
|
||||
This way an operator can issue account JWTs and a separate entity can issue JWTs for user associated with it's account.
|
||||
Neither entity has to be aware of the other's private Nkey.
|
||||
This not only allows users to be configured some place other than servers, but also by different organizations altogether.
|
||||
Say administrators of a NATS installation controlling operators, issuing account JWTs to individual prod/dev teams managing their own user.
|
||||
This is a fully decentralized authorization setup!
|
||||
Provided institutional trust, it is also possible to use nsc to import account or user public [NKeys](../auth_intro/nkey_auth.md) and issue corresponding JWTs. This way an operator can issue account JWTs and a separate entity can issue JWTs for user associated with it's account. Neither entity has to be aware of the other's private Nkey. This not only allows users to be configured some place other than servers, but also by different organizations altogether. Say administrators of a NATS installation controlling operators, issuing account JWTs to individual prod/dev teams managing their own user. This is a fully decentralized authorization setup!
|
||||
|
||||
With an Operator JWT in place, the server needs to be configured to trust it by specifying `operator`.
|
||||
Furthermore the server needs a way to obtain account JWTs.
|
||||
This done by either defaulting to the resolver specified in the operator jwt or by manually specifying the [resolver](resolver.md).
|
||||
Depending on your configuration an [account server](../../../../nats-tools/nsc/nsc.md#account-server-configuration) needs to be in place
|
||||
With an Operator JWT in place, the server needs to be configured to trust it by specifying `operator`. Furthermore the server needs a way to obtain account JWTs. This done by either defaulting to the resolver specified in the operator jwt or by manually specifying the [resolver](resolver.md). Depending on your configuration an [account server](../../../../nats-tools/nsc/nsc.md#account-server-configuration) needs to be in place
|
||||
|
||||
> It is possible to [mix](jwt_nkey_auth.md) JWT and [NKEY](../auth_intro/nkey_auth.md)/[Account](../accounts.md) based Authentication/Authorization.
|
||||
|
||||
> It is possible to [mix](jwt_nkey_auth.md) JWT and [NKEY](../auth_intro/nkey_auth.md)/[Account](../accounts.md) based Authentication/Authorization.
|
||||
@@ -1,16 +1,12 @@
|
||||
# Mixing NKEYS and Decentralized JWT Authentication/Authorization setup
|
||||
# Mixed Authentication/Authorization Setup
|
||||
|
||||
Mixing both [nkeys](../auth_intro/nkey_auth.md) static config and [decentralized JWT Authenticatin/Authorization](README.md)
|
||||
is possible but needs some preparation in order to be able to do it.
|
||||
Mixing both [nkeys](../auth_intro/nkey_auth.md) static config and [decentralized JWT Authenticatin/Authorization](./) is possible but needs some preparation in order to be able to do it.
|
||||
|
||||
The way this can be done is by **first** preparing a basic trusted operator setup
|
||||
that could be used in the future, and then base from that configuration to create the
|
||||
NKEYS static config using the same shared public nkeys for the accounts and then use
|
||||
clustering routes to bridge the two different auth setups during the transition.
|
||||
The way this can be done is by **first** preparing a basic trusted operator setup that could be used in the future, and then base from that configuration to create the NKEYS static config using the same shared public nkeys for the accounts and then use clustering routes to bridge the two different auth setups during the transition.
|
||||
|
||||
For example, creating the following initial setup using [NSC](../../../../nats-tools/nsc/README.md):
|
||||
For example, creating the following initial setup using [NSC](../../../../nats-tools/nsc/):
|
||||
|
||||
```sh
|
||||
```bash
|
||||
nsc add account --name SYS
|
||||
nsc add user --name sys
|
||||
nsc add account --name A
|
||||
@@ -21,7 +17,7 @@ For example, creating the following initial setup using [NSC](../../../../nats-t
|
||||
|
||||
This will then generate something like the following:
|
||||
|
||||
```sh
|
||||
```bash
|
||||
nsc list accounts
|
||||
╭─────────────────────────────────────────────────────────────────╮
|
||||
│ Accounts │
|
||||
@@ -43,15 +39,14 @@ This will then generate something like the following:
|
||||
╰──────┴──────────────────────────────────────────────────────────╯
|
||||
```
|
||||
|
||||
We could use this configuration as the initial starting configuration for an nkeys config now,
|
||||
where all the NKEYS users public nkeys are explicitly listed (centralized auth model).
|
||||
We could use this configuration as the initial starting configuration for an nkeys config now, where all the NKEYS users public nkeys are explicitly listed \(centralized auth model\).
|
||||
|
||||
```hcl
|
||||
```text
|
||||
port = 4222
|
||||
|
||||
cluster {
|
||||
port = 6222
|
||||
|
||||
|
||||
# We will bridge two different servers with different auth models via routes
|
||||
# routes [ nats://127.0.0.1:6223 ]
|
||||
}
|
||||
@@ -77,16 +72,15 @@ accounts {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
By using `nsc` it is possible to create a mem based resolver for the trusted operator setup:
|
||||
|
||||
```
|
||||
```text
|
||||
nsc generate config --mem-resolver --sys-account SYS
|
||||
```
|
||||
|
||||
An example configuration from the second node with the trusted operator setup could then be:
|
||||
|
||||
```hcl
|
||||
```text
|
||||
port = 4223
|
||||
|
||||
cluster {
|
||||
@@ -116,11 +110,11 @@ resolver_preload = {
|
||||
}
|
||||
```
|
||||
|
||||
Even though they have different authorization mechanisms, these two servers are able to route account messages because they share the same NKEY.
|
||||
Even though they have different authorization mechanisms, these two servers are able to route account messages because they share the same NKEY.
|
||||
|
||||
We have created at least one user, in this case with creds:
|
||||
|
||||
```conf
|
||||
```text
|
||||
-----BEGIN NATS USER JWT-----
|
||||
eyJ0eXAiOiJqd3QiLCJhbGciOiJlZDI1NTE5In0.eyJqdGkiOiJNRkM3V1E1N0hKUE9aWUVOTEhVRTZTWFVQTDVKTURWSkxIQzJRTkpYNUVJS0RGR1U1REhRIiwiaWF0IjoxNTc0Mzc1OTE2LCJpc3MiOiJBREZCMkpYWVRYT0pFTDZMTkFYRFJFVUdSWDM1Qk9MWkkzQjRQRkZBQzdJUlBSM09BNFFOS0JOMiIsIm5hbWUiOiJ0ZXN0Iiwic3ViIjoiVUFQT0syUDdFTjNVRkJMN1NCSlBRSzNNM0pNTEFMWVJZS1g1WFdTVk1WWUs2M1pNQkhUT0hWSlIiLCJ0eXBlIjoidXNlciIsIm5hdHMiOnsicHViIjp7ImFsbG93IjpbIl9JTkJPWC5cdTAwM2UiLCJfUl8iLCJfUl8uXHUwMDNlIiwidGVzdCIsInRlc3QuXHUwMDNlIl19LCJzdWIiOnsiYWxsb3ciOlsiX0lOQk9YLlx1MDAzZSIsIl9SXyIsIl9SXy5cdTAwM2UiLCJsYXRlbmN5Lm9uLnRlc3QiLCJ0ZXN0IiwidGVzdC5cdTAwM2UiXX19fQ.MSU2aUIBK1iUsg7h52lLrfEfTwVMF_wB3HDq75ECskxSyyDDMtk9_3957UtQF-3yoGCIhKOkWjzX8C-WXnLADw
|
||||
------END NATS USER JWT------
|
||||
@@ -133,7 +127,7 @@ SUANVBWRHHFMGHNIT6UJHPN2TGVBVIILE7VPVNEQ7DGCJ26ZD2V3KAHT4M
|
||||
*************************************************************
|
||||
```
|
||||
|
||||
And this same user is able to connect to either one of the servers (bound to 4222 and 4223 respectively):
|
||||
And this same user is able to connect to either one of the servers \(bound to 4222 and 4223 respectively\):
|
||||
|
||||
Subscriber Service:
|
||||
|
||||
@@ -141,34 +135,34 @@ Subscriber Service:
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"log"
|
||||
|
||||
"github.com/nats-io/nats.go"
|
||||
"github.com/nats-io/nats.go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
opts := make([]nats.Option, 0)
|
||||
opts := make([]nats.Option, 0)
|
||||
|
||||
// Extract public nkey from seed
|
||||
//
|
||||
// Public: UAPOK2P7EN3UFBL7SBJPQK3M3JMLALYRYKX5XWSVMVYK63ZMBHTOHVJR
|
||||
// Private: SUANVBWRHHFMGHNIT6UJHPN2TGVBVIILE7VPVNEQ7DGCJ26ZD2V3KAHT4M
|
||||
//
|
||||
nkey, err := nats.NkeyOptionFromSeed("path/to/seed.nkey")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
opts = append(opts, nkey)
|
||||
nc, err := nats.Connect("127.0.0.1:4222", opts...)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
nc.Subscribe("test", func(m *nats.Msg){
|
||||
log.Printf("[Received] %q, replying... \n", string(m.Data))
|
||||
m.Respond([]byte("pong from nkeys based server"))
|
||||
})
|
||||
// Extract public nkey from seed
|
||||
//
|
||||
// Public: UAPOK2P7EN3UFBL7SBJPQK3M3JMLALYRYKX5XWSVMVYK63ZMBHTOHVJR
|
||||
// Private: SUANVBWRHHFMGHNIT6UJHPN2TGVBVIILE7VPVNEQ7DGCJ26ZD2V3KAHT4M
|
||||
//
|
||||
nkey, err := nats.NkeyOptionFromSeed("path/to/seed.nkey")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
opts = append(opts, nkey)
|
||||
nc, err := nats.Connect("127.0.0.1:4222", opts...)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
nc.Subscribe("test", func(m *nats.Msg){
|
||||
log.Printf("[Received] %q, replying... \n", string(m.Data))
|
||||
m.Respond([]byte("pong from nkeys based server"))
|
||||
})
|
||||
|
||||
select {}
|
||||
select {}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -178,25 +172,26 @@ Requestor:
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/nats.go"
|
||||
"github.com/nats-io/nats.go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
nc, err := nats.Connect("127.0.0.1:4223", nats.UserCredentials("path/to/user.creds"))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
nc, err := nats.Connect("127.0.0.1:4223", nats.UserCredentials("path/to/user.creds"))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for range time.NewTicker(1 * time.Second).C {
|
||||
resp, err := nc.Request("test", []byte("test"), 1*time.Second)
|
||||
if err != nil {
|
||||
log.Println("[Error]", err)
|
||||
continue
|
||||
}
|
||||
log.Println("[Received]", string(resp.Data))
|
||||
}
|
||||
for range time.NewTicker(1 * time.Second).C {
|
||||
resp, err := nc.Request("test", []byte("test"), 1*time.Second)
|
||||
if err != nil {
|
||||
log.Println("[Error]", err)
|
||||
continue
|
||||
}
|
||||
log.Println("[Received]", string(resp.Data))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Memory Resolver
|
||||
# Memory Resolver Tutorial
|
||||
|
||||
The `MEMORY` resolver is a server built-in resolver for account JWTs. If there are a small number of accounts, or they do not change too often this can be a simpler configuration that does not require an external account resolver. Server configuration reload is supported, meaning the preloads can be updated in the server configuration and reloaded without a server restart.
|
||||
|
||||
@@ -60,7 +60,7 @@ Success!! - generated "/tmp/server.conf"
|
||||
generated "/tmp/memory.jwt"
|
||||
```
|
||||
|
||||
If you require additional settings, you may want to consider using [`include`](../../nats-server/configuration/#include-directive) in your main configuration, to reference the generated files. Otherwise, you can start a server and reference the generated configuration:
|
||||
If you require additional settings, you may want to consider using [`include`](../../#include-directive) in your main configuration, to reference the generated files. Otherwise, you can start a server and reference the generated configuration:
|
||||
|
||||
```text
|
||||
> nats-server -c /tmp/server.conf
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
# resolver
|
||||
# Account lookup using Resolver
|
||||
|
||||
The `resolver` configuration option is used in conjunction with [NATS JWT Authentication](README.md) and [nsc](../../nats-tools/nsc/nsc). The `resolver` option specifies a URL where the nats-server can retrieve an account JWT. There are two built-in resolver implementations:
|
||||
The `resolver` configuration option is used in conjunction with [NATS JWT Authentication](./) and [nsc](https://github.com/nats-io/nats.docs/tree/aecb86faf9be946a413d1c6200fc0ff5d1b0baef/nats-server/configuration/nats-tools/nsc/nsc/README.md). The `resolver` option specifies a URL where the nats-server can retrieve an account JWT. There are two built-in resolver implementations:
|
||||
|
||||
* `URL`
|
||||
* `MEMORY`
|
||||
|
||||
- `URL`
|
||||
- `MEMORY`
|
||||
|
||||
> If the operator JWT specified in `operator` contains an account resolver URL, `resolver` only needs to be specified in order to overwrite that default.
|
||||
|
||||
## URL Resolver
|
||||
|
||||
The `URL` resolver specifies a URL where the server can append an account public key to retrieve that account's JWT. Convention for [NATS Account JWT Servers](../../nats-tools/nas) is to serve JWTs at: `http://localhost:9090/jwt/v1/accounts/`. For such a configuration you would specify the resolver as follows:
|
||||
The `URL` resolver specifies a URL where the server can append an account public key to retrieve that account's JWT. Convention for [NATS Account JWT Servers](https://github.com/nats-io/nats.docs/tree/aecb86faf9be946a413d1c6200fc0ff5d1b0baef/nats-server/configuration/nats-tools/nas/README.md) is to serve JWTs at: `http://localhost:9090/jwt/v1/accounts/`. For such a configuration you would specify the resolver as follows:
|
||||
|
||||
```yaml
|
||||
resolver: URL(http://localhost:9090/jwt/v1/accounts/)
|
||||
@@ -17,8 +17,7 @@ resolver: URL(http://localhost:9090/jwt/v1/accounts/)
|
||||
|
||||
> Note that if you are not using a nats-account-server, the URL can be anything as long as by appending the public key for an account, the requested JWT is returned.
|
||||
|
||||
If the server used requires client authentication, or you want to specify which CA is trusted for the lookup of account information, specify `resolver_tls`.
|
||||
This [`tls` configuration map](securing_nats/tls.md) lets you further restrict TLS to the resolver.
|
||||
If the server used requires client authentication, or you want to specify which CA is trusted for the lookup of account information, specify `resolver_tls`. This [`tls` configuration map](https://github.com/nats-io/nats.docs/tree/aecb86faf9be946a413d1c6200fc0ff5d1b0baef/nats-server/configuration/securing_nats/jwt/securing_nats/tls.md) lets you further restrict TLS to the resolver.
|
||||
|
||||
## MEMORY
|
||||
|
||||
@@ -34,3 +33,4 @@ ACSU3Q6LTLBVLGAQUONAGXJHVNWGSKKAUA7IY5TB4Z7PLEKSR5O6JTGR: eyJ0eXAiOiJqd3QiLCJhbG
|
||||
The `MEMORY` resolver is recommended when the server has a small number of accounts that don't change very often.
|
||||
|
||||
For more information on how to configure a memory resolver, see [this tutorial](mem_resolver.md).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user