Skip to content

Commit

Permalink
Enhance operator reissue command with key support
Browse files Browse the repository at this point in the history
Add support for using a private key during operator reissue, enabling identity updates directly from operator seeds. Updated error handling for key loading and added corresponding tests to validate functionality and ensure accounts are correctly re-signed.

Signed-off-by: Alberto Ricart <alberto@synadia.com>
  • Loading branch information
aricart committed Dec 12, 2024
1 parent ce4b054 commit fa2b79a
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 2 deletions.
25 changes: 23 additions & 2 deletions cmd/reissueoperator.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package cmd

import (
"fmt"
"strings"

"github.com/nats-io/nkeys"
"github.com/nats-io/nsc/v2/cmd/store"
Expand All @@ -26,8 +27,12 @@ import (
func createReIssueOperatorCmd() *cobra.Command {
var params reIssueOperator
cmd := &cobra.Command{
Use: "operator",
Short: "Re-issues the operator with a new identity and re-signs affected accounts",
Use: "operator",
Short: "Re-issues the operator with a new identity and re-signs affected accounts.\n" +
"\tWhen `--private-key` flag is provided with an operator seed, the identity\n" +
"\tspecified will be used for the operator and as the issuer for the accounts.\n" +
"\tNote use of this command could create a disruption. Please backup your server\n" +
"\tand nsc environment prior to use.",
Example: `nsc reissue operator`,
Args: MaxArgs(0),
SilenceUsage: false,
Expand Down Expand Up @@ -116,6 +121,22 @@ func (p *reIssueOperator) Run(ctx ActionCtx) (store.Status, error) {
r.AddError("failed to generate new operator identity: %v", err)
return r, err
}
if KeyPathFlag != "" {
if strings.HasPrefix(KeyPathFlag, "O") {
KeyPathFlag, err = ctx.StoreCtx().KeyStore.GetSeed(KeyPathFlag)
if err != nil {
r.AddError("failed to find operator key: %v", err)
return r, err
}
}
if strings.HasPrefix(KeyPathFlag, "SO") {
opKp, err = nkeys.FromSeed([]byte(KeyPathFlag))
if err != nil {
r.AddError("failed to load operator key from seed: %v", err)
return r, err
}
}
}
accountSigningKey := opKp
if op.StrictSigningKeyUsage && !p.turnIntoSigningKey {
sp := SignerParams{kind: []nkeys.PrefixByte{nkeys.PrefixByteOperator}}
Expand Down
34 changes: 34 additions & 0 deletions cmd/reissueoperator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,40 @@ func Test_ReIssue(t *testing.T) {
require.True(t, op4.DidSign(ac))
}

func Test_ReIssueWithKey(t *testing.T) {
ts := NewTestStore(t, "O")
defer ts.Done(t)
op1, err := ts.Store.ReadOperatorClaim()
require.NoError(t, err)
// add testing account
ts.AddAccount(t, "A")
ac1, err := ts.Store.ReadAccountClaim("A")
require.NoError(t, err)
require.True(t, op1.DidSign(ac1))

seed, pub, _ := CreateOperatorKey(t)

cmd := createReIssueOperatorCmd()
HoistRootFlags(cmd)
_, stderr, err := ExecuteCmd(cmd, "-K", string(seed))
require.NoError(t, err)
op2, err := ts.Store.ReadOperatorClaim()
require.NoError(t, err)
require.NotEqual(t, op1.Subject, op2.Subject)
require.Equal(t, pub, op2.Subject)
require.Equal(
t,
stderr,
"[ OK ] operator \"O\" successfully changed identity to: "+pub+"\n"+
"[ OK ] account \"A\" re-signed\n"+
"all jobs succeeded\n",
)

ac, err := ts.Store.ReadAccountClaim("A")
require.NoError(t, err)
require.True(t, op2.DidSign(ac))
}

func Test_ReIssueStrict(t *testing.T) {
ts := NewTestStore(t, "O")
defer ts.Done(t)
Expand Down

0 comments on commit fa2b79a

Please sign in to comment.