Repository: nats-io/nsc
Pull request #364 (2021-03-01 23:54:21)

[added] system account user generation when no user is specified
also [added] ability to specify system account on pull

Signed-off-by: Matthias Hanel <mh@synadia.com>

his shows config and makes sure we have no jwt accessible.
Then starts a server and:
pushes when no keys are present and user name is specified -> failure expected
pushes when keys are present and user name is specified -> no failure expected
finally pushes with keys present and no user specified -> no failure expected
```
> cat s.cfg
listen: localhost:4222
operator: "./store/OP/OP.jwt"
resolver: {
    type: full
    dir: "./cache"
    interval: "2m"
}
resolver_preload: {
ACBPMXUKQ5PTUPWPEVOEFBFSDAGYJ6F5W2342UQH5L2YDPSFZAJNCAP2:eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJWQkFHTjRYWTZOTUw2U1E1SE9TR1dDQVhMQURMRlBaSUNDQ09LQjZQSlVWMlE1Q01CNTZBIiwiaWF0IjoxNjEzMDY1NDk0LCJpc3MiOiJPRFBXSUJRSlZJUTQyNDYyUUFGSTJSS0pDNFJaSENRU0lWUFJEREhXRkNKQVA1Mk5SWks2WjJZQyIsIm5hbWUiOiJTWVMiLCJzdWIiOiJBQ0JQTVhVS1E1UFRVUFdQRVZPRUZCRlNEQUdZSjZGNVcyMzQyVVFINUwyWURQU0ZaQUpOQ0FQMiIsIm5hdHMiOnsibGltaXRzIjp7InN1YnMiOi0xLCJkYXRhIjotMSwicGF5bG9hZCI6LTEsImltcG9ydHMiOi0xLCJleHBvcnRzIjotMSwid2lsZGNhcmRzIjp0cnVlLCJjb25uIjotMSwibGVhZiI6LTF9LCJzaWduaW5nX2tleXMiOlsiQUJMRElJWVBFR1RPUTc1TjQ2R0hDM0pXVE4zRkRNV1VLRjVSMk8yNUVKMklHNkoyWTI3TjNNVDMiXSwiZGVmYXVsdF9wZXJtaXNzaW9ucyI6eyJwdWIiOnt9LCJzdWIiOnt9fSwidHlwZSI6ImFjY291bnQiLCJ2ZXJzaW9uIjoyfX0.pYiPZ_rMUUR5fyaam7-gsbxyX3r5oirUjTKk9lfFUTlU55JBxHdVRW-89yQ_e38LZVyIFCEglXSZF85liyasAA
}
> rm cache/*
zsh: sure you want to delete all 8 files in /Users/matthiashanel/test/sbux-demo/cache [yn]? y
> nats-server -c s.cfg &
[1] 78492
[78492] 2021/03/01 18:22:06.464691 [INF] Starting nats-server
[78492] 2021/03/01 18:22:06.464770 [INF]   Version:  2.2.0-beta.92
[78492] 2021/03/01 18:22:06.464773 [INF]   Git:      [not set]
[78492] 2021/03/01 18:22:06.464778 [INF]   Name:     NDF32COOCZ2JOFRBXAOXVIB3NTV4ZP6Q4PLZAO6SCVOPSINDZ5HMS5BP
[78492] 2021/03/01 18:22:06.464781 [INF]   ID:       NDF32COOCZ2JOFRBXAOXVIB3NTV4ZP6Q4PLZAO6SCVOPSINDZ5HMS5BP
[78492] 2021/03/01 18:22:06.464785 [INF] Using configuration file: s.cfg
[78492] 2021/03/01 18:22:06.464787 [INF] Trusted Operators
[78492] 2021/03/01 18:22:06.464790 [INF]   System  : ""
[78492] 2021/03/01 18:22:06.464794 [INF]   Operator: "OP"
[78492] 2021/03/01 18:22:06.464813 [INF]   Issued  : 2021-02-12 16:38:11 -0500 EST
[78492] 2021/03/01 18:22:06.464816 [INF]   Expires : 1969-12-31 19:00:00 -0500 EST
[78492] 2021/03/01 18:22:06.465446 [INF] Managing all jwt in exclusive directory /Users/matthiashanel/test/sbux-demo/cache
[78492] 2021/03/01 18:22:06.466378 [INF] Listening for client connections on localhost:4222
[78492] 2021/03/01 18:22:06.466394 [INF] Server is ready

> nsc list keys --all
+----------------------------------------------------------------------------------------------+
|                                             Keys                                             |
+------------+----------------------------------------------------------+-------------+--------+
| Entity     | Key                                                      | Signing Key | Stored |
+------------+----------------------------------------------------------+-------------+--------+
| OP         | ODPWIBQJVIQ42462QAFI2RKJC4RZHCQSIVPRDDHWFCJAP52NRZK6Z2YC |             |        |
| OP         | OA2ZMNM5QYSYKROCPIR2WGKGC5U2EPIB7PHCPS5GYQV25HBQM2V7VYMX | *           |        |
|  EXP       | AB4HFDH3XFHJHFA254VZMV5OBM7LWLKDB73NGLN6MAKIPUT2MMFMO2PE |             |        |
|   exp      | UDGHBNMUVNNEC5BU55EJZ7QKL5F4MSMRUD24RCD2R2FPS2YFF5LT3KLR |             |        |
|  EXP-CONS  | ABW3BSRE7HCMRQUFNIKKKSDHYXRITXGTRCZJH2NQ3R4Q4DEZOIQAWDYV |             |        |
|   exp-cons | UDZP6DOMZYEVQKNRHGRTBSMA4FY2WS3Z4W7MBGT3XOHEDCHZTVMDHUNB |             |        |
|  IMP       | ACN5NK4VG25BQK3AO7A2PH7QOPNCHUBUMZB5I5QGRWP54KZKTSPDLL5V |             |        |
|   imp      | UDU7L74YQDUW37JKX4FXBYIRNNLQCCS7CVZSPDCX4LMXRDP5WOQ7BUJR |             |        |
|  IMP-CON2  | ABWWH3BJT3ZJ2LGJBDDBU7KB7O6PUQ5EAUHLV75ISADKSKR7SKEQZ7R4 |             |        |
|  IMP-CON2  | ADLJIFQUJR72YOKTG6F62VGOOOQBXZPXUOR2OSO2YPH5CSLJIMXTZJ2H | *           |        |
|   imp-con2 | UAX46ZPWFQZEC5JMI5EROIVFUOBW5JLI6ZT5LZPLGSSRLHMMR35IJKRT |             |        |
|  IMP-CONS  | AC45WZOZI2R6BKOYZTLRGAZMDGRVFRYL36G6O757O3XGMRDCW4U6EEYT |             |        |
|   imp-cons | UCIZDXMVVZCS7HN4W2X7HFBVXUNKQT24VVSWLECO5UI42BU4DBNJV3IK |             |        |
|  SYS       | ACBPMXUKQ5PTUPWPEVOEFBFSDAGYJ6F5W2342UQH5L2YDPSFZAJNCAP2 |             |        |
|  SYS       | ABLDIIYPEGTOQ75N46GHC3JWTN3FDMWUKF5R2O25EJ2IG6J2Y27N3MT3 | *           |        |
|  SYS       | AAWRTWGWVQAVOK2MYIPE453NPX3WFFXLYFRUXA5P23RBCYFKFJ6CD2IL | *           |        |
|   sys      | UAJF7DHBTSZZI6HVKKAIQODO7EEJCGCEXGC2JNFAW5X5KAEOGOB64YVO |             |        |
|  TEST      | ACV63DGCZGOIT3P5ZA7PQT3KYJ6UDFFHZ7KETHYMDMZ4N44KYAQ2ZZ5F |             |        |
|  TEST      | AATEJXG7UX4HFJ6ZPRTP22P6OYZER36YYD3GVBOVW7QHLU32P4QFFTZJ | *           |        |
|   foo      | UBICBTHDKQRB4LIYA6BMIJ7EA2G7YS7FIWMMVKZJE6M3HS5IVCOLKDY2 |             |        |
+------------+----------------------------------------------------------+-------------+--------+

> nsc push --all --system-account SYS --system-user sys
[ERR ] error obtaining system account user: no system account user found
Error: all jobs failed
 18:43:31  ✘ 1  ~/test/sbux-demo  nsc list keys --all
+----------------------------------------------------------------------------------------------+
|                                             Keys                                             |
+------------+----------------------------------------------------------+-------------+--------+
| Entity     | Key                                                      | Signing Key | Stored |
+------------+----------------------------------------------------------+-------------+--------+
| OP         | ODPWIBQJVIQ42462QAFI2RKJC4RZHCQSIVPRDDHWFCJAP52NRZK6Z2YC |             |        |
| OP         | OA2ZMNM5QYSYKROCPIR2WGKGC5U2EPIB7PHCPS5GYQV25HBQM2V7VYMX | *           |        |
|  EXP       | AB4HFDH3XFHJHFA254VZMV5OBM7LWLKDB73NGLN6MAKIPUT2MMFMO2PE |             |        |
|   exp      | UDGHBNMUVNNEC5BU55EJZ7QKL5F4MSMRUD24RCD2R2FPS2YFF5LT3KLR |             |        |
|  EXP-CONS  | ABW3BSRE7HCMRQUFNIKKKSDHYXRITXGTRCZJH2NQ3R4Q4DEZOIQAWDYV |             |        |
|   exp-cons | UDZP6DOMZYEVQKNRHGRTBSMA4FY2WS3Z4W7MBGT3XOHEDCHZTVMDHUNB |             |        |
|  IMP       | ACN5NK4VG25BQK3AO7A2PH7QOPNCHUBUMZB5I5QGRWP54KZKTSPDLL5V |             |        |
|   imp      | UDU7L74YQDUW37JKX4FXBYIRNNLQCCS7CVZSPDCX4LMXRDP5WOQ7BUJR |             |        |
|  IMP-CON2  | ABWWH3BJT3ZJ2LGJBDDBU7KB7O6PUQ5EAUHLV75ISADKSKR7SKEQZ7R4 |             |        |
|  IMP-CON2  | ADLJIFQUJR72YOKTG6F62VGOOOQBXZPXUOR2OSO2YPH5CSLJIMXTZJ2H | *           |        |
|   imp-con2 | UAX46ZPWFQZEC5JMI5EROIVFUOBW5JLI6ZT5LZPLGSSRLHMMR35IJKRT |             |        |
|  IMP-CONS  | AC45WZOZI2R6BKOYZTLRGAZMDGRVFRYL36G6O757O3XGMRDCW4U6EEYT |             |        |
|   imp-cons | UCIZDXMVVZCS7HN4W2X7HFBVXUNKQT24VVSWLECO5UI42BU4DBNJV3IK |             |        |
|  SYS       | ACBPMXUKQ5PTUPWPEVOEFBFSDAGYJ6F5W2342UQH5L2YDPSFZAJNCAP2 |             |        |
|  SYS       | ABLDIIYPEGTOQ75N46GHC3JWTN3FDMWUKF5R2O25EJ2IG6J2Y27N3MT3 | *           |        |
|  SYS       | AAWRTWGWVQAVOK2MYIPE453NPX3WFFXLYFRUXA5P23RBCYFKFJ6CD2IL | *           |        |
|   sys      | UAJF7DHBTSZZI6HVKKAIQODO7EEJCGCEXGC2JNFAW5X5KAEOGOB64YVO |             |        |
|  TEST      | ACV63DGCZGOIT3P5ZA7PQT3KYJ6UDFFHZ7KETHYMDMZ4N44KYAQ2ZZ5F |             |        |
|  TEST      | AATEJXG7UX4HFJ6ZPRTP22P6OYZER36YYD3GVBOVW7QHLU32P4QFFTZJ | *           |        |
|   foo      | UBICBTHDKQRB4LIYA6BMIJ7EA2G7YS7FIWMMVKZJE6M3HS5IVCOLKDY2 |             |        |
+------------+----------------------------------------------------------+-------------+--------+

> export NKEYS_PATH="`pwd`/keys"
> nsc list keys --all
+----------------------------------------------------------------------------------------------+
|                                             Keys                                             |
+------------+----------------------------------------------------------+-------------+--------+
| Entity     | Key                                                      | Signing Key | Stored |
+------------+----------------------------------------------------------+-------------+--------+
| OP         | ODPWIBQJVIQ42462QAFI2RKJC4RZHCQSIVPRDDHWFCJAP52NRZK6Z2YC |             | *      |
| OP         | OA2ZMNM5QYSYKROCPIR2WGKGC5U2EPIB7PHCPS5GYQV25HBQM2V7VYMX | *           | *      |
|  EXP       | AB4HFDH3XFHJHFA254VZMV5OBM7LWLKDB73NGLN6MAKIPUT2MMFMO2PE |             | *      |
|   exp      | UDGHBNMUVNNEC5BU55EJZ7QKL5F4MSMRUD24RCD2R2FPS2YFF5LT3KLR |             | *      |
|  EXP-CONS  | ABW3BSRE7HCMRQUFNIKKKSDHYXRITXGTRCZJH2NQ3R4Q4DEZOIQAWDYV |             | *      |
|   exp-cons | UDZP6DOMZYEVQKNRHGRTBSMA4FY2WS3Z4W7MBGT3XOHEDCHZTVMDHUNB |             | *      |
|  IMP       | ACN5NK4VG25BQK3AO7A2PH7QOPNCHUBUMZB5I5QGRWP54KZKTSPDLL5V |             | *      |
|   imp      | UDU7L74YQDUW37JKX4FXBYIRNNLQCCS7CVZSPDCX4LMXRDP5WOQ7BUJR |             | *      |
|  IMP-CON2  | ABWWH3BJT3ZJ2LGJBDDBU7KB7O6PUQ5EAUHLV75ISADKSKR7SKEQZ7R4 |             | *      |
|  IMP-CON2  | ADLJIFQUJR72YOKTG6F62VGOOOQBXZPXUOR2OSO2YPH5CSLJIMXTZJ2H | *           | *      |
|   imp-con2 | UAX46ZPWFQZEC5JMI5EROIVFUOBW5JLI6ZT5LZPLGSSRLHMMR35IJKRT |             | *      |
|  IMP-CONS  | AC45WZOZI2R6BKOYZTLRGAZMDGRVFRYL36G6O757O3XGMRDCW4U6EEYT |             | *      |
|   imp-cons | UCIZDXMVVZCS7HN4W2X7HFBVXUNKQT24VVSWLECO5UI42BU4DBNJV3IK |             | *      |
|  SYS       | ACBPMXUKQ5PTUPWPEVOEFBFSDAGYJ6F5W2342UQH5L2YDPSFZAJNCAP2 |             | *      |
|  SYS       | ABLDIIYPEGTOQ75N46GHC3JWTN3FDMWUKF5R2O25EJ2IG6J2Y27N3MT3 | *           | *      |
|  SYS       | AAWRTWGWVQAVOK2MYIPE453NPX3WFFXLYFRUXA5P23RBCYFKFJ6CD2IL | *           | *      |
|   sys      | UAJF7DHBTSZZI6HVKKAIQODO7EEJCGCEXGC2JNFAW5X5KAEOGOB64YVO |             | *      |
|  TEST      | ACV63DGCZGOIT3P5ZA7PQT3KYJ6UDFFHZ7KETHYMDMZ4N44KYAQ2ZZ5F |             | *      |
|  TEST      | AATEJXG7UX4HFJ6ZPRTP22P6OYZER36YYD3GVBOVW7QHLU32P4QFFTZJ | *           | *      |
|   foo      | UBICBTHDKQRB4LIYA6BMIJ7EA2G7YS7FIWMMVKZJE6M3HS5IVCOLKDY2 |             | *      |
+------------+----------------------------------------------------------+-------------+--------+

> nsc push --all --system-account SYS --system-user sys
[ OK ] push to nats-server "nats://localhost:4222" using system account "SYS":
       [ OK ] push EXP to nats-server with nats account resolver:
              [ OK ] pushed "EXP" to nats-server NDF32COOCZ2JOFRBXAOXVIB3NTV4ZP6Q4PLZAO6SCVOPSINDZ5HMS5BP: jwt updated
              [ OK ] pushed to a total of 1 nats-server
       [ OK ] push EXP-CONS to nats-server with nats account resolver:
              [ OK ] pushed "EXP-CONS" to nats-server NDF32COOCZ2JOFRBXAOXVIB3NTV4ZP6Q4PLZAO6SCVOPSINDZ5HMS5BP: jwt updated
              [ OK ] pushed to a total of 1 nats-server
       [ OK ] push IMP to nats-server with nats account resolver:
              [ OK ] pushed "IMP" to nats-server NDF32COOCZ2JOFRBXAOXVIB3NTV4ZP6Q4PLZAO6SCVOPSINDZ5HMS5BP: jwt updated
              [ OK ] pushed to a total of 1 nats-server
       [ OK ] push IMP-CON2 to nats-server with nats account resolver:
              [ OK ] pushed "IMP-CON2" to nats-server NDF32COOCZ2JOFRBXAOXVIB3NTV4ZP6Q4PLZAO6SCVOPSINDZ5HMS5BP: jwt updated
              [ OK ] pushed to a total of 1 nats-server
       [ OK ] push IMP-CONS to nats-server with nats account resolver:
              [ OK ] pushed "IMP-CONS" to nats-server NDF32COOCZ2JOFRBXAOXVIB3NTV4ZP6Q4PLZAO6SCVOPSINDZ5HMS5BP: jwt updated
              [ OK ] pushed to a total of 1 nats-server
       [ OK ] push SYS to nats-server with nats account resolver:
              [ OK ] pushed "SYS" to nats-server NDF32COOCZ2JOFRBXAOXVIB3NTV4ZP6Q4PLZAO6SCVOPSINDZ5HMS5BP: jwt updated
              [ OK ] pushed to a total of 1 nats-server
       [ OK ] push TEST to nats-server with nats account resolver:
              [ OK ] pushed "TEST" to nats-server NDF32COOCZ2JOFRBXAOXVIB3NTV4ZP6Q4PLZAO6SCVOPSINDZ5HMS5BP: jwt updated
              [ OK ] pushed to a total of 1 nats-server
> nsc push --all
[ OK ] push to nats-server "nats://localhost:4222" using system account "SYS":
       [ OK ] push EXP to nats-server with nats account resolver:
              [ OK ] pushed "EXP" to nats-server NDF32COOCZ2JOFRBXAOXVIB3NTV4ZP6Q4PLZAO6SCVOPSINDZ5HMS5BP: jwt updated
              [ OK ] pushed to a total of 1 nats-server
       [ OK ] push EXP-CONS to nats-server with nats account resolver:
              [ OK ] pushed "EXP-CONS" to nats-server NDF32COOCZ2JOFRBXAOXVIB3NTV4ZP6Q4PLZAO6SCVOPSINDZ5HMS5BP: jwt updated
              [ OK ] pushed to a total of 1 nats-server
       [ OK ] push IMP to nats-server with nats account resolver:
              [ OK ] pushed "IMP" to nats-server NDF32COOCZ2JOFRBXAOXVIB3NTV4ZP6Q4PLZAO6SCVOPSINDZ5HMS5BP: jwt updated
              [ OK ] pushed to a total of 1 nats-server
       [ OK ] push IMP-CON2 to nats-server with nats account resolver:
              [ OK ] pushed "IMP-CON2" to nats-server NDF32COOCZ2JOFRBXAOXVIB3NTV4ZP6Q4PLZAO6SCVOPSINDZ5HMS5BP: jwt updated
              [ OK ] pushed to a total of 1 nats-server
       [ OK ] push IMP-CONS to nats-server with nats account resolver:
              [ OK ] pushed "IMP-CONS" to nats-server NDF32COOCZ2JOFRBXAOXVIB3NTV4ZP6Q4PLZAO6SCVOPSINDZ5HMS5BP: jwt updated
              [ OK ] pushed to a total of 1 nats-server
       [ OK ] push SYS to nats-server with nats account resolver:
              [ OK ] pushed "SYS" to nats-server NDF32COOCZ2JOFRBXAOXVIB3NTV4ZP6Q4PLZAO6SCVOPSINDZ5HMS5BP: jwt updated
              [ OK ] pushed to a total of 1 nats-server
       [ OK ] push TEST to nats-server with nats account resolver:
              [ OK ] pushed "TEST" to nats-server NDF32COOCZ2JOFRBXAOXVIB3NTV4ZP6Q4PLZAO6SCVOPSINDZ5HMS5BP: jwt updated
              [ OK ] pushed to a total of 1 nats-server
>
```


Patch:
diff --git a/cmd/pull.go b/cmd/pull.go
index cc9010e..902a13d 100644
--- a/cmd/pull.go
+++ b/cmd/pull.go
@@ -41,6 +41,8 @@ func createPullCmd() *cobra.Command {
 
 	cmd.Flags().BoolVarP(&params.All, "all", "A", false, "operator and all accounts under the operator")
 	cmd.Flags().BoolVarP(&params.Overwrite, "overwrite-newer", "F", false, "overwrite local JWTs that are newer than remote")
+	cmd.Flags().StringVarP(&params.sysAcc, "system-account", "", "", "System account for use with nats-resolver enabled nats-server. (Default is system account specified by operator)")
+	cmd.Flags().StringVarP(&params.sysAccUser, "system-user", "", "", "System account user for use with nats-resolver enabled nats-server. (Default to temporarily generated user)")
 	params.AccountContextParams.BindFlags(cmd)
 	return cmd
 }
@@ -51,9 +53,11 @@ func init() {
 
 type PullParams struct {
 	AccountContextParams
-	All       bool
-	Jobs      PullJobs
-	Overwrite bool
+	All        bool
+	Jobs       PullJobs
+	Overwrite  bool
+	sysAccUser string // when present use
+	sysAcc     string
 }
 
 type PullJob struct {
@@ -241,7 +245,8 @@ func (p *PullParams) Run(ctx ActionCtx) (store.Status, error) {
 	} else if url := op.AccountServerURL; IsNatsUrl(url) {
 		subR := store.NewReport(store.OK, `pull from cluster using system account`)
 		r.Add(subR)
-		_, _, opt, err := getSystemAccountUser(ctx, "", "")
+		ib := nats.NewInbox()
+		_, opt, err := getSystemAccountUser(ctx, p.sysAcc, p.sysAccUser, ib, "$SYS.REQ.CLAIMS.PACK")
 		if err != nil {
 			subR.AddError("failed to obtain system user: %v", err)
 			return r, nil
@@ -252,7 +257,7 @@ func (p *PullParams) Run(ctx ActionCtx) (store.Status, error) {
 			return r, nil
 		}
 		defer nc.Close()
-		ib := nats.NewInbox()
+
 		sub, err := nc.SubscribeSync(ib)
 		if err != nil {
 			subR.AddError("failed to subscribe to response subject: %v", err)
diff --git a/cmd/push.go b/cmd/push.go
index 7248326..fedc56c 100644
--- a/cmd/push.go
+++ b/cmd/push.go
@@ -23,6 +23,8 @@ import (
 	"strings"
 	"time"
 
+	"github.com/nats-io/nkeys"
+
 	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt/v2"
 	"github.com/nats-io/nats.go"
@@ -50,9 +52,8 @@ push -P -A (all accounts)`,
 	cmd.Flags().StringVarP(&params.ASU, "account-jwt-server-url", "u", "", "set account jwt server url for nsc sync (only http/https/nats urls supported if updating with nsc) If a nats url is provided ")
 
 	cmd.Flags().BoolVarP(&params.prune, "prune", "P", false, "prune all accounts not under the current operator (exclusive of -a). Only works with nats-resolver enabled nats-server.")
-	cmd.Flags().StringVarP(&params.sysAcc, "system-account", "", "", "System account for use with nats-resolver enabled nats-server.")
-	cmd.Flags().StringVarP(&params.sysAccUser, "system-user", "", "", "System account user for use with nats-resolver enabled nats-server.")
-
+	cmd.Flags().StringVarP(&params.sysAcc, "system-account", "", "", "System account for use with nats-resolver enabled nats-server. (Default is system account specified by operator)")
+	cmd.Flags().StringVarP(&params.sysAccUser, "system-user", "", "", "System account user for use with nats-resolver enabled nats-server. (Default to temporarily generated user)")
 	params.AccountContextParams.BindFlags(cmd)
 	return cmd
 }
@@ -63,14 +64,13 @@ func init() {
 
 type PushCmdParams struct {
 	AccountContextParams
-	ASU              string
-	sysAccUser       string // when present use
-	sysAcc           string
-	sysAccUserJwtOpt nats.Option
-	allAccounts      bool
-	force            bool
-	prune            bool
-	targeted         []string
+	ASU         string
+	sysAccUser  string // when present use
+	sysAcc      string
+	allAccounts bool
+	force       bool
+	prune       bool
+	targeted    []string
 
 	accountList []string
 }
@@ -109,43 +109,87 @@ func processResponse(report *store.Report, resp *nats.Msg) (bool, string, interf
 }
 
 // when sysAccName or sysAccUserName are "" we will try to find a suitable user
-func getSystemAccountUser(ctx ActionCtx, sysAccName string, sysAccUserName string) (string, string, nats.Option, error) {
-	if op, err := ctx.StoreCtx().Store.ReadOperatorClaim(); err != nil {
-		return "", "", nil, err
+func getSystemAccountUser(ctx ActionCtx, sysAccName, sysAccUserName, allowSub string, allowPubs ...string) (string, nats.Option, error) {
+	op, err := ctx.StoreCtx().Store.ReadOperatorClaim()
+	if err != nil {
+		return "", nil, err
 	} else if accNames, err := friendlyNames(ctx.StoreCtx().Operator.Name); err != nil {
-		return "", "", nil, err
+		return "", nil, err
 	} else if sysAccName == "" {
 		if sysAccName = accNames[op.SystemAccount]; sysAccName == "" {
-			return "", "", nil, fmt.Errorf(`system account "%s" not found`, op.SystemAccount)
+			return "", nil, fmt.Errorf(`system account "%s" not found`, op.SystemAccount)
 		}
 	}
+	getOpt := func(theJWT string, kp nkeys.KeyPair) nats.Option {
+		return nats.UserJWT(
+			func() (string, error) {
+				return theJWT, nil
+			}, func(nonce []byte) ([]byte, error) {
+				return kp.Sign(nonce)
+			})
+	}
+	// Attempt to generate temporary user credentials and
+	if sysAccUserName == "" {
+		if keys, err := ctx.StoreCtx().GetAccountKeys(sysAccName); err == nil && len(keys) > 0 {
+			key := ""
+			if op.StrictSigningKeyUsage {
+				if len(keys) > 1 {
+					key = keys[1]
+				} else {
+					key = ""
+				}
+			} else {
+				key = keys[0]
+			}
+			sysAccKp, err := ctx.StoreCtx().KeyStore.GetKeyPair(key)
+			if err == nil {
+				defer sysAccKp.Wipe()
+				tmpUsrKp, err := nkeys.CreateUser()
+				if err == nil {
+					tmpUsrPub, err := tmpUsrKp.PublicKey()
+					if err == nil {
+						tmpUsrClaim := jwt.NewUserClaims(tmpUsrPub)
+						tmpUsrClaim.Expires = time.Now().Add(2 * time.Minute).Unix()
+						tmpUsrClaim.Name = "nsc temporary push user"
+						tmpUsrClaim.Pub.Allow.Add(allowPubs...)
+						tmpUsrClaim.Sub.Allow.Add(allowSub)
+						if theJWT, err := tmpUsrClaim.Encode(sysAccKp); err == nil {
+							return sysAccName, getOpt(theJWT, tmpUsrKp), nil
+						}
+					}
+				}
+			}
+		}
+		// in case of not finding a key, default to searching for an existing user and key
+	}
 	users := []string{sysAccUserName}
 	if sysAccUserName == "" {
 		var err error
 		if users, err = ctx.StoreCtx().Store.ListEntries(store.Accounts, sysAccName, store.Users); err != nil {
-			return "", "", nil, err
+			return "", nil, err
 		} else if len(users) == 0 {
-			return "", "", nil, err
+			return "", nil, err
 		}
 	}
 	for _, sysUser := range users {
-		if claim, err := ctx.StoreCtx().Store.ReadUserClaim(sysAccName, sysUser); err != nil {
-			continue
-		} else if kp, err := ctx.StoreCtx().KeyStore.GetKeyPair(claim.Subject); err != nil {
+		claim, err := ctx.StoreCtx().Store.ReadUserClaim(sysAccName, sysUser)
+		if err != nil {
 			continue
-		} else if theJWT, err := ctx.StoreCtx().Store.ReadRawUserClaim(sysAccName, sysUser); err != nil {
+		}
+		kp, _ := ctx.StoreCtx().KeyStore.GetKeyPair(claim.Subject)
+		if kp == nil {
+			kp, _ = ctx.StoreCtx().KeyStore.GetKeyPair(claim.IssuerAccount)
+			if kp == nil {
+				continue
+			}
+		}
+		if theJWT, err := ctx.StoreCtx().Store.ReadRawUserClaim(sysAccName, sysUser); err != nil {
 			continue
 		} else {
-			jwtCb := func() (string, error) {
-				return string(theJWT), nil
-			}
-			signCb := func(nonce []byte) ([]byte, error) {
-				return kp.Sign(nonce)
-			}
-			return sysAccName, sysUser, nats.UserJWT(jwtCb, signCb), nil
+			return sysAccName, getOpt(string(theJWT), kp), nil
 		}
 	}
-	return "", "", nil, fmt.Errorf(`no system account user found`)
+	return "", nil, fmt.Errorf(`no system account user with corresponding nkey found`)
 }
 
 func (p *PushCmdParams) SetDefaults(ctx ActionCtx) error {
@@ -162,12 +206,6 @@ func (p *PushCmdParams) SetDefaults(ctx ActionCtx) error {
 			p.ASU = op.AccountServerURL
 		}
 	}
-	if IsNatsUrl(p.ASU) {
-		var err error
-		if p.sysAcc, p.sysAccUser, p.sysAccUserJwtOpt, err = getSystemAccountUser(ctx, p.sysAcc, p.sysAccUser); err != nil {
-			return err
-		}
-	}
 	c := GetConfig()
 	var err error
 	if p.accountList, err = c.ListAccounts(); err != nil {
@@ -257,7 +295,7 @@ func (p *PushCmdParams) Validate(ctx ActionCtx) error {
 	if p.ASU == "" {
 		return errors.New("no account server url or nats-server url was provided by the operator jwt")
 	}
-	if p.sysAccUser == "" && p.prune {
+	if !IsNatsUrl(p.ASU) && p.prune {
 		return errors.New("prune only works for nats based account resolver")
 	}
 
@@ -371,7 +409,9 @@ func (p *PushCmdParams) Run(ctx ActionCtx) (store.Status, error) {
 			}
 		}
 	} else {
-		sysAcc, sysAccUser, opt, err := getSystemAccountUser(ctx, p.sysAcc, p.sysAccUser)
+		nats.NewInbox()
+		sysAcc, opt, err := getSystemAccountUser(ctx, p.sysAcc, p.sysAccUser, nats.InboxPrefix+">",
+			"$SYS.REQ.CLAIMS.LIST", "$SYS.REQ.CLAIMS.UPDATE", "$SYS.REQ.CLAIMS.DELETE")
 		if err != nil {
 			r.AddError("error obtaining system account user: %v", err)
 			return r, nil
@@ -383,8 +423,8 @@ func (p *PushCmdParams) Run(ctx ActionCtx) (store.Status, error) {
 		}
 		defer nc.Close()
 		if len(p.targeted) != 0 {
-			sub := store.NewReport(store.OK, `push to nats-server "%s" using system account "%s" user "%s"`,
-				p.ASU, sysAcc, sysAccUser)
+			sub := store.NewReport(store.OK, `push to nats-server "%s" using system account "%s"`,
+				p.ASU, sysAcc)
 			r.Add(sub)
 			for _, v := range p.targeted {
 				subAcc := store.NewReport(store.OK, "push %s to nats-server with nats account resolver", v)


Test patch:
diff --git a/cmd/pull_test.go b/cmd/pull_test.go
index f465536..6f31ddd 100644
--- a/cmd/pull_test.go
+++ b/cmd/pull_test.go
@@ -183,6 +183,9 @@ func Test_SyncNewerFromNatsResolver(t *testing.T) {
 	require.NoError(t, err)
 	_, _, err = ExecuteCmd(createPullCmd(), "--all")
 	require.NoError(t, err)
+	// again, this time with system account and user specified
+	_, _, err = ExecuteCmd(createPullCmd(), "--all", "--system-account", "SYS", "--system-user", "sys")
+	require.NoError(t, err)
 	// claim now exists in nsc store
 	claim2, err := ts.Store.ReadAccountClaim("acc-name")
 	require.NoError(t, err)
diff --git a/cmd/push_test.go b/cmd/push_test.go
index 9578dcd..2b05ac7 100644
--- a/cmd/push_test.go
+++ b/cmd/push_test.go
@@ -177,7 +177,7 @@ func Test_SyncNatsResolverDelete(t *testing.T) {
 	dir, filesPre, ts := deleteSetup(t, true)
 	defer os.Remove(dir)
 	defer ts.Done(t)
-	_, _, err := ExecuteCmd(createPushCmd(), "--prune")
+	_, _, err := ExecuteCmd(createPushCmd(), "--prune", "--system-account", "SYS", "--system-user", "sys")
 	require.NoError(t, err)
 	// test to assure AC1/SYS where pushed/pruned
 	filesPost, err := filepath.Glob(dir + string(os.PathSeparator) + "/*.jwt")
@@ -261,7 +261,8 @@ func Test_SyncBadUrl(t *testing.T) {
 	_, _, err = ExecuteCmd(createEditOperatorCmd(), "--account-jwt-server-url", ports.Nats[0])
 	require.NoError(t, err)
 	// Try again, thus also testing if the server is still around
-	_, _, err = ExecuteCmd(createPushCmd(), "--all")
+	// Provide explicit system account user to connect
+	_, _, err = ExecuteCmd(createPushCmd(), "--all", "--system-account", "SYS", "--system-user", "sys")
 	require.NoError(t, err)
 	// test to assure AC1/AC2/SYS where pushed
 	filesPre, err := filepath.Glob(dir + string(os.PathSeparator) + "/*.jwt")