go get github.com/nats-io/nats-server
curl -L https://raw.githubusercontent.com/nats-io/nsc/master/install.py | python
$ nsc add operator -n AcmeOperator
Generated operator key - private key stored "~/.nkeys/AcmeOperator/AcmeOperator.nk"
Success! - added operator "AcmeOperator"
Save the generated NKEY (*.nk file) someplace very safe.
You'll need to reference the operator's JWT, so save that someplace accessible by the nats-account-server.
This is all you need! Reference the operator JWT, and the resolver. In this case, we'll use the directory store, which is mutable, so operators can add and remove users and accounts.
operator: $HOME/.nsc/nats/AcmeOperator/AcmeOperator.jwt
resolver: URL(http://localhost:9090/jwt/v1/accounts/)
http: {
host: "localhost",
port: 9090,
readtimeout: 5000,
writetimeout: 5000,
}
# Reference the operator JWT.
OperatorJWTPath: /Users/colinsullivan/.nsc/nats/AcmeOperator/AcmeOperator.jwt
# This is the location of the store, where public account JWTs will be
# uploaded.
store: {
dir: /Users/colinsullivan/setup-jwt-security/jwts
}
This would be done by the operator, or administrator.
$ nsc add account -n Acme
Generated account key - private key stored "~/.nkeys/AcmeOperator/accounts/Acme/Acme.nk"
Success! - added account "Acme"
$ nsc describe jwt -W -f ~/.nsc/nats/AcmeOperator/accounts/Acme/Acme.jwt | grep "Account ID"
│ Account ID │ AAHC5D6GVMRI753MOVEIEV2LVR3C7GUCYLAOHQH5DL5V7M6CXSYGWZRK │
You must use curl to upload the JWT to the account server. You could copy the JWT
and rename it <Public NKEY>.jwt
, but might not take advantage of sharding if
configured.
$ curl -i -X POST localhost:9090/jwt/v1/accounts/AAHC5D6GVMRI753MOVEIEV2LVR3C7GUCYLAOHQH5DL5V7M6CXSYGWZRK --data-binary @/Users/colinsullivan/.nsc/nats/AcmeOperator/accounts/Acme/Acme.jwt -H "Content-Type: text/text"
HTTP/1.1 200 OK
Vary: Origin
Date: Mon, 13 May 2019 20:54:22 GMT
Content-Length: 0
$ nsc add user -n Colin
Generated user key - private key stored "~/.nkeys/AcmeOperator/accounts/Acme/users/Colin.nk"
Generated user creds file "~/.nkeys/AcmeOperator/accounts/Acme/users/Colin.creds"
Success! - added user "Colin" to "Acme"
Test the user:
$ nats-pub -creds ~/.nkeys/AcmeOperator/accounts/Acme/users/Colin.creds foo bar
Published [foo] : 'bar'
To enable NATS alerts, create a user to connect to NATS and publish alerts. In this
case, we've created a user account-user
.
Setup NATS connectivity in the NATS account server by adding the following stanza:
nats: {
Servers: ["localhost:4222"],
ConnectTimeout: 5000,
MaxReconnects: 5,
ReconnectWait: 5000,
UserCredentials: /Users/colinsullivan/.nkeys/AcmeOperator/accounts/Acme/users/account-server.creds
}
The account server will connect to the NATS server to publish account related events. You'll see statements like this:
2019/05/13 17:39:31.905301 [ERR] failed to connect to NATS, nats: no servers available for connection
2019/05/13 17:39:31.905319 [ERR] will try to connect again in 5000 milliseconds
2019/05/13 17:39:36.908554 [INF] connecting to NATS for notifications
You can create a system account for generating alearts, usage, etc. It's simply a user you define.
$ nsc add account -n SYS
Generated account key - private key stored "~/.nkeys/AcmeOperator/accounts/SYS/SYS.nk"
Success! - added account "SYS"
$ nsc add user -n SYSU
Generated user key - private key stored "~/.nkeys/AcmeOperator/accounts/SYS/users/SYSU.nk"
Generated user creds file "~/.nkeys/AcmeOperator/accounts/SYS/users/SYSU.creds"
Success! - added user "SYSU" to "SYS"
Now upload the account. We'll need to add the system jwt, and to do that we need the public NKey. Obtain it through:
$ ngs describe jwt -W -f /Users/colinsullivan/.nsc/nats/AcmeOperator/accounts/SYS/SYS.jwt | grep "Account ID"
│ Account ID │ AALMWQBL3A3IPZUHRS22BXAMJDXI5MBOKTDNEZ4YAOFJIGSKQCZ2GOQZ │
Upload the JWT.
curl -i -X POST localhost:9090/jwt/v1/accounts/AALMWQBL3A3IPZUHRS22BXAMJDXI5MBOKTDNEZ4YAOFJIGSKQCZ2GOQZ --data-binary @/Users/colinsullivan/.nsc/nats/AcmeOperator/accounts/SYS/SYS.jwt -H "Content-Type: text/text"
TODO: is this necessary after having to upload the account? Add the system account to the NATS server and account server. In your account server configuration add:
SystemAccountJWTPath: /Users/colinsullivan/.nsc/nats/AcmeOperator/accounts/SYS/SYS.jwt
In the NATS server configuration, add:
system: AALMWQBL3A3IPZUHRS22BXAMJDXI5MBOKTDNEZ4YAOFJIGSKQCZ2GOQZ
Reload or bounce the NATS server.
At this point, you can import the sys account into other accounts, or use the system account credentials to listen:
nats-sub -creds ~/.nkeys/AcmeOperator/accounts/SYS/users/SYSU.creds ">"
Listening on [>]
[#1] Received on [$SYS.SERVER.NAMJJH7VO4ZZRP2BIVCE2MFZGXH3BH5HVUS2Y7XM55QWZMPHJ6S57BDL.STATSZ]: '{
"server": {
"host": "0.0.0.0",
"id": "NAMJJH7VO4ZZRP2BIVCE2MFZGXH3BH5HVUS2Y7XM55QWZMPHJ6S57BDL",
"ver": "2.0.0-RC12",
"seq": 13,
"time": "2019-05-13T18:58:44.729401-06:00"
},
"statsz": {
"start": "2019-05-13T18:54:14.681899-06:00",
"mem": 10383360,
"cores": 8,
"cpu": 0,
"connections": 2,
"total_connections": 2,
"active_accounts": 2,
"subscriptions": 9,
"sent": {
"msgs": 0,
"bytes": 0
},
"received": {
"msgs": 0,
"bytes": 0
},
"slow_consumers": 0
}
}'
Let's import some of the data from the SYS account into our Acme account.
First create and upload another account:
nsc create account -n PublicServices
Upload the account as you would the others with curl. Next create a user for the application.
nsc create user -n PublicServiceUser
Note that we are already working on the PublicServices account.
$ nsc add import --name "TicketService" --subject "generate.ticket" --service
Success! - added public service export "TicketService"
You've locally updated your account to have a public TicketService exposed on subject generate.ticket
. The changes are local, so now upload it with curl. First we'll need the
account ID.
$ nsc describe jwt -W -f ~/.nsc/nats/AcmeOperator/accounts/PublicServices/PublicServices.jwt | grep "Account ID"
│ Account ID │ ACOAYG5E4EWOE3VJ26RTQFD3QNOL2JA5EMEWHVM5RDKHYQAOEAIO35PS │
curl -i -X POST localhost:9090/jwt/v1/accounts/ACOAYG5E4EWOE3VJ26RTQFD3QNOL2JA5EMEWHVM5RDKHYQAOEAIO35PS --data-binary @/Users/colinsullivan/.nsc/nats/AcmeOperator/accounts/PublicService/PublicService.jwt -H "Content-Type: text/text"
Let's change the account we're working on:
$ nsc env -a Acme
$
Now we'll add an import to the account:
Get the account ID from the list the accounts:
$ nsc describe jwt -W -f ~/.nsc/nats/AcmeOperator/accounts/Acme/Acme.jwt | grep "Account ID"
│ Account ID │ AAHC5D6GVMRI753MOVEIEV2LVR3C7GUCYLAOHQH5DL5V7M6CXSYGWZRK │
Now add the import.
$ nsc add import --src-account ACOAYG5E4EWOE3VJ26RTQFD3QNOL2JA5EMEWHVM5RDKHYQAOEAIO35PS --name TicketService --remote-subject generate.ticket --service
Success! - added service import "generate.ticket"
Now upload your account changes:
curl -i -X POST localhost:9090/jwt/v1/accounts/AAHC5D6GVMRI753MOVEIEV2LVR3C7GUCYLAOHQH5DL5V7M6CXSYGWZRK --data-binary @/Users/colinsullivan/.nsc/nats/AcmeOperator/accounts/Acme/Acme.jwt -H "Content-Type: text/text"
Restart the NATS server.
$ ./nats-rply --creds ~/.nkeys/AcmeOperator/accounts/PublicServices/users/PublicServiceUser.creds "generate.ticket" "A ticket for you"
Listening on [generate.ticket]
[#1] Received on [generate.ticket]: '1234'
Make the request:
$ nats-req -creds ~/.nkeys/AcmeOperator/accounts/Acme/users/Colin.creds generate.ticket 1234
Published [generate.ticket] : '1234'
Received [_INBOX.uwUhiGebcjQeLsLg30O4oU.V0ZUziqZ] : 'A ticket for you'
Ahh that makes sense! Thank you for your answer. I follow up on the official doc articles.
NATS is awesome, appreciate your work!
Best regards,
Chris