Skip to content
This repository has been archived by the owner on Jan 21, 2025. It is now read-only.

Commit

Permalink
feat: account and user issues fixing themselves
Browse files Browse the repository at this point in the history
Account and User issues fixing themselves in case either the nkey or the JWT is missing
  • Loading branch information
siredmar committed Mar 25, 2024
1 parent 1babd1c commit d2c6848
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 14 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ build: generate
CGO_ENABLED=0 GOOS=$(OS) GOARCH="$(GOARCH)" go build -o build/vault/plugins/vault-plugin-secrets-nats -gcflags "all=-N -l" -ldflags '-extldflags "-static"' cmd/vault-plugin-secrets-nats/main.go

docker: build
docker build -t $(DOCKER_REGISTRY)/vault-plugin-secrets-nats:$(VERSION) -f build/vault/Dockerfile .
docker build -t $(DOCKER_REGISTRY)/vault-with-nats-secrets:$(VERSION) -f build/vault/Dockerfile .

push: docker
docker push $(DOCKER_REGISTRY)/vault-plugin-secrets-nats:$(VERSION)
docker push $(DOCKER_REGISTRY)/vault-with-nats-secrets:$(VERSION)

start:
vault server -dev -dev-root-token-id=root -dev-plugin-dir=./build/vault/plugins -log-level=trace -dev-listen-address=127.0.0.1:8200
Expand Down
109 changes: 106 additions & 3 deletions backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,11 +211,15 @@ func (b *NatsBackend) periodicFunc(ctx context.Context, sys *logical.Request) er
Operator: operator,
Account: account,
})
if err != nil {

if err = b.periodicRefreshAccountIssues(ctx, sys.Storage, operator); err != nil {
return err
}
err = refreshAccountResolver(ctx, sys.Storage, accountIssue, "push")
if err != nil {
if err = b.periodicRefreshUserIssues(ctx, sys.Storage, operator, account); err != nil {
return err
}

if err = refreshAccountResolver(ctx, sys.Storage, accountIssue, AccountResolverActionPush); err != nil {
return err
}
_, err = storeAccountIssueUpdate(ctx, sys.Storage, accountIssue)
Expand All @@ -227,3 +231,102 @@ func (b *NatsBackend) periodicFunc(ctx context.Context, sys *logical.Request) er
}
return nil
}

func (b *NatsBackend) periodicRefreshUserIssues(ctx context.Context, storage logical.Storage, operator string, account string) error {
issuesList, err := listUserIssues(ctx, storage, IssueUserParameters{
Operator: operator,
Account: account,
})
if err != nil {
return err
}
for _, issueName := range issuesList {
issue, err := readUserIssue(ctx, storage, IssueUserParameters{
Operator: operator,
Account: account,
User: issueName,
})
if err != nil {
return err
}

jwtMissing := false
nkeyMissing := false
jwt, err := readUserJWT(ctx, storage, JWTParameters{
Operator: operator,
Account: account,
User: issueName,
})
if err != nil {
return err
}
if !issue.Status.User.JWT || jwt == nil {
jwtMissing = true
}

nkey, err := readUserNkey(ctx, storage, NkeyParameters{
Operator: operator,
Account: account,
User: issueName,
})
if err != nil {
return err
}
if !issue.Status.User.Nkey || nkey == nil {
nkeyMissing = true
}

if jwtMissing || nkeyMissing {
if err := refreshUser(ctx, storage, issue); err != nil {
return err
}
}
}
return nil
}

func (b *NatsBackend) periodicRefreshAccountIssues(ctx context.Context, storage logical.Storage, operator string) error {
issuesList, err := listAccountIssues(ctx, storage, operator)
if err != nil {
return err
}
for _, issueName := range issuesList {
issue, err := readAccountIssue(ctx, storage, IssueAccountParameters{
Operator: operator,
Account: issueName,
})
if err != nil {
return err
}
jwtMissing := false
nkeyMissing := false
jwt, err := readAccountJWT(ctx, storage, JWTParameters{
Operator: operator,
Account: issueName,
})
if err != nil {
return err
}
if !issue.Status.Account.JWT || jwt == nil {
jwtMissing = true
}

nkey, err := readAccountNkey(ctx, storage, NkeyParameters{
Operator: operator,
Account: issueName,
})
if err != nil {
return err
}
if !issue.Status.Account.Nkey || nkey == nil {
nkeyMissing = true
}

if jwtMissing || nkeyMissing {
if err := refreshAccount(ctx, storage, issue); err != nil {
return err
}
}
}
return nil
}
6 changes: 3 additions & 3 deletions example/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ BGREEN='\033[1;32m'
NC='\033[0m' # No Color

echo -e "${BGREEN}> Creating NATS resources (operator and sysaccount)${NC}"
vault write nats-secrets/issue/operator/myop @operator/operator.json
vault write nats-secrets/issue/operator/myop/account/sys @sysaccount/sysaccount.json
vault write nats-secrets/issue/operator/myop/account/sys/user/default-push @sysaccount/default-push.json
vault write nats-secrets/issue/operator/myop/account/sys @sysaccount/sysaccount.json
vault write nats-secrets/issue/operator/myop @operator/operator.json

echo -e "${BGREEN}> Generate NATS server config with preloaded operator and sys account settings${NC}"
OPERATOR_JWT=$(vault read -format=json nats-secrets/jwt/operator/myop | jq -r .data.jwt)
Expand Down Expand Up @@ -41,4 +41,4 @@ docker run --rm -it --name nats-box --network nats -v $(pwd)/creds:/creds natsio
echo -e "${BGREEN}> Cleaning up...${NC}"
docker kill nats
docker network rm nats
echo -e "${BGREEN}> done.${NC}"
echo -e "${BGREEN}> done.${NC}"
19 changes: 13 additions & 6 deletions paths_issue_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ func issueAccountJWT(ctx context.Context, storage logical.Storage, issue IssueAc
issue.Claims.ClaimsData.Subject = accountPublicKey
issue.Claims.ClaimsData.Issuer = signingPublicKey
issue.Claims.ClaimsData.IssuedAt = time.Now().Unix()
// TODO: dont know how to handle scopes of signing keys
// TODO: dont know how to handle scopes of signing keys
issue.Claims.Account.SigningKeys = signingPublicKeys
natsJwt, err := v1alpha1.Convert(&issue.Claims)
if err != nil {
Expand Down Expand Up @@ -605,15 +605,22 @@ func updateUserIssues(ctx context.Context, storage logical.Storage, issue IssueA
return nil
}

type AccountResolverAction string

const (
AccountResolverActionPush AccountResolverAction = "push"
AccountResolverActionDelete AccountResolverAction = "delete"
)

func refreshAccountResolverPush(ctx context.Context, storage logical.Storage, issue *IssueAccountStorage) error {
return refreshAccountResolver(ctx, storage, issue, "push")
return refreshAccountResolver(ctx, storage, issue, AccountResolverActionPush)
}

func refreshAccountResolverDelete(ctx context.Context, storage logical.Storage, issue *IssueAccountStorage) error {
return refreshAccountResolver(ctx, storage, issue, "delete")
return refreshAccountResolver(ctx, storage, issue, AccountResolverActionDelete)
}

func refreshAccountResolver(ctx context.Context, storage logical.Storage, issue *IssueAccountStorage, action string) error {
func refreshAccountResolver(ctx context.Context, storage logical.Storage, issue *IssueAccountStorage, action AccountResolverAction) error {
// read operator issue
op, err := readOperatorIssue(ctx, storage, IssueOperatorParameters{
Operator: issue.Operator,
Expand Down Expand Up @@ -696,7 +703,7 @@ func refreshAccountResolver(ctx context.Context, storage logical.Storage, issue
defer resolver.CloseConnection()

switch {
case action == "push":
case action == AccountResolverActionPush:
err = resolver.PushAccount(issue.Account, []byte(accJWT.JWT))
if err != nil {
log.Error().Str("operator", issue.Operator).
Expand All @@ -706,7 +713,7 @@ func refreshAccountResolver(ctx context.Context, storage logical.Storage, issue
resolver.CloseConnection()
return nil
}
case action == "delete":
case action == AccountResolverActionDelete:
operatorNkey, err := readOperatorNkey(ctx, storage, NkeyParameters{
Operator: issue.Operator,
})
Expand Down

0 comments on commit d2c6848

Please sign in to comment.