Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NSC functionality #854

Open
aricart opened this issue Aug 29, 2023 · 6 comments
Open

NSC functionality #854

aricart opened this issue Aug 29, 2023 · 6 comments
Labels
proposal Enhancement idea or proposal

Comments

@aricart
Copy link
Member

aricart commented Aug 29, 2023

What motivated this proposal?

Let's figure out a way of putting in the 75% of the common nsc functionality into natscli.
I would like to make a small library that we can share between natscli and nsc so that we don't duplicate changes and updates.

What is the proposed change?

Abiltiy to CRUD:

  • Operator (and management of system account)

    • Edit/Rotate signing keys
  • Account

    • Edit/Rotate sig
    • Default permissions
    • Imports/Exports
    • Generate activations
  • User

    • Permissions
  • Generation of a mem-resolver or nats-resolver configs?

  • Tags are not used much, unless they - get a few folks that use tags as a way of possibly indexing and finding things, this possibly points to coping with large number of accounts and users

Who benefits from this change?

Common lib for doing basic CRUD operations, allow natscli to perform these operations without complexities of nsc

What alternatives have you evaluated?

No response

@aricart aricart added the proposal Enhancement idea or proposal label Aug 29, 2023
@ripienaar
Copy link
Collaborator

ripienaar commented Aug 30, 2023

Thank you @aricart. So lets mock up some UI then:

nats security operator add FOO
      --expiry 
      --generate-signing-key

nats sec op delete FOO
     --force

something like this, we take whats in nsc map it onto natscli style and show just what flags to add (for example I didnt put in --url and --sys from nsc add operator

From there we can look at details, the choice of security is just an example so lets not discuss that for now.

@ripienaar
Copy link
Collaborator

ripienaar commented Aug 30, 2023

Past this I want to think a bit about a API for this rather than just hacking about with the JWTs, so something like:

AddOperator(name, WithOperatorExpiry(d)) (Operator, error)
DeleteOperator(name) error
LoadOperator(name) (Operator, error)

operator:

op, err := LoadOperator(name)
k, err:= op.GenerateSigningKey()
account, err := op.AddAccount(AccountConfig{.....})
user,err := account.AddUser(UserConfig{....})

account2,err := op.LoadAccount(account)
user2,err:=account2.LoadUser(user)

account2.ImportService(account, "weather.v2", ImportMount("svc.weather"), ImportShare(), ImportSample(10))

etc, something useful like this thats more expressive and models the relationships between operator, account, user etc better than jwt library does

I dont really care if this library is like a generally supported thing for end users at first but I dont want to pull all this logic into the cli straight so I tend to fold it into a package like this.

As clear from teh above examples I dont really know how all this plumbs together - I think the signing keys for example should be different - but this is something you know a lot about so some guidance be great @aricart

@aricart
Copy link
Member Author

aricart commented Aug 30, 2023

Ha! I made an api, let's sync in a bit

@ripienaar
Copy link
Collaborator

@aricart can you stick the poc we did using appbuilder here please?

@aricart
Copy link
Member Author

aricart commented Nov 7, 2023

The prototype is here: https://github.com/aricart/nscfisk

@aricart
Copy link
Member Author

aricart commented Nov 7, 2023

name: nscw
description: NSC Wrapper
version: 1.0.0
author: Synadia Communications

commands:
  - name: keys
    description: Show keys
    type: exec
    flags:
      - name: secret
        description: Show secret keys
        bool: true
        default:
    script: |
      nsc list keys -A {{ if .Flags.secret }} --show-seeds {{end}}
  - name: generate
    description: Generate a memory resolver configuration for the current operator and account
    type: exec
    flags:
      - name: out
        description: destination output (stdout by default)
        default: --
    script: |
      nsc generate config --mem-resolver --force --config-file "{{ .Flags.out }}"
  - name: operator
    type: parent
    description: Operator related commands
    commands:
      - name: select
        type: exec
        description: Set the current operator
        arguments:
          - name: name
            description: The operator name
            required: true
        script: |
          nsc select operator "{{ .Arguments.name }}"
      - name: get
        type: exec
        description: Returns the operator JWT
        flags:
          - name: out
            description: Save the output to a file. If not JSON, the file will be armored.
            default:
          - name: json
            description: Print the decoded jwt as JSON (exclusive of --raw)
            bool: true
            default:
        script:  >-
          nsc describe operator
          {{if .Flags.json}} --json {{ else }} --raw {{ end }}
          {{ if .Flags.out }} --output-file "{{ .Flags.out }}" {{ end }}
      - name: list
        type: exec
        description: List all the operators
        script: |
          nsc list operators
      - name: describe
        type: exec
        description: Describe the current operator
        script: |
          nsc describe operator
      - name: add
        type: exec
        description: Adds a new operator
        arguments:
          - name: name
            description: The friendly name for this operator
            required: true
        flags:
          - name: expiry
            description: Valid until '0' is always, '2M' is two months, yyyy-mm-dd
            default: 0
        script: |
          nsc add operator --name "{{ .Arguments.name }}" --expiry "{{.Flags.expiry}}"
      - name: edit
        type: exec
        description: Edits the current operator
        flags:
          - name: expiry
            description: Valid until '0' is always, '2M' is two months, yyyy-mm-dd
            default: ""
          - name: account-jwt-server-url
            description: Sets the account server URL - set it to nats://host:port if you have configured a NATS resolver
            default:
          - name: rm-account-jwt-server-url
            description: Removes the account server URL
            bool: true
            default:
          - name: sk
            description: Signing key or keypath or the value "generate" to generate a key pair on the fly
            default:
          - name: rm-sk
            description: remove signing key
            default:
          - name: system-account
            description: Set system account by account by public key or name
            default:
          - name: service-url
            description: Set service url for the operator (nats://localhost:4222)
            default:
        script: >-
          nsc edit operator
          {{if .Flags.expiry }} --expiry "{{.Flags.expiry}}" {{end}}
          {{if index .Flags "system-account"}} --system-account "{{index .Flags "system-account"}}" {{end}}
          {{if index .Flags "rm-account-jwt-server-url"}} --rm-account-jwt-server-url {{end}}
          {{if index .Flags "account-jwt-server-url"}} --account-jwt-server-url "{{index .Flags "account-jwt-server-url"}}" {{end}}
          {{if index .Flags "service-url"}} --service-url "{{index .Flags "service-url"}}" {{end}}
          {{if .Flags.sk}} --sk "{{.Flags.sk}}" {{end}}
          {{if index .Flags "rm-sk"}} --rm-sk "{{index .Flags "rm-sk"}}" {{end}}
  - name: accounts
    type: parent
    description: Account related commands
    commands:
      - name: get
        type: exec
        description: Returns the account JWT
        flags:
          - name: out
            description: Save the output to a file. If not JSON, the file will be armored.
            default:
          - name: json
            description: Print the decoded jwt as JSON (exclusive of --raw)
            bool: true
            default:
        script: >-
          nsc describe account
          {{if .Flags.json}} --json {{ else }} --raw {{ end }}
          {{ if .Flags.out }} --output-file "{{ .Flags.out }}" {{ end }}
      - name: select
        type: exec
        description: Set the current account
        arguments:
          - name: name
            description: The account name
            required: true
        script: |
          nsc select account "{{ .Arguments.name }}"
      - name: list
        type: exec
        description: list all the accounts
        script: |
          nsc list accounts
      - name: describe
        type: exec
        description: describe the current account
        script: |
          nsc describe account
      - name: add
        type: exec
        description: Adds a new account
        arguments:
          - name: name
            description: The friendly name for this account
            required: true
        flags:
          - name: expiry
            description: Valid until '0' is always, '2M' is two months, yyyy-mm-dd
            default: 0
        script: |
          nsc add account --name "{{ .Arguments.name }}" --expiry "{{.Flags.expiry}}"
      - name: delete
        type: exec
        description: deletes the specified account
        arguments:
          - name: name
            description: The friendly name for this account
            required: true
        script: |
          nsc delete account --revoke --name "{{ .Arguments.name }}"
      - name: edit
        type: exec
        description: Edit the current account
        flags:
          - name: expiry
            description: Valid until '0' is always, '2M' is two months, yyyy-mm-dd
            default: ""
          - name: sk
            description: Signing key or keypath or the value "generate" to generate a key pair on the fly
            default:
          - name: rm-sk
            description: remove signing key
            default:
          - name: disallow-bearer
            description: reject user JWTs that have allow-bearer enabled
            enum: ["true", "false"]
            default: "true"
        script: >-
          nsc edit account
          {{if .Flags.expiry }} --expiry "{{.Flags.expiry}}" {{end}}
          {{if .Flags.sk}} --sk "{{.Flags.sk}}" {{end}}
          {{if index .Flags "rm-sk"}} --rm-sk "{{index .Flags "rm-sk"}}" {{end}}
          {{if index .Flags "disallow-bearer"}} --disallow-bearer="{{index .Flags "disallow-bearer"}}" {{end}}
  - name: users
    type: parent
    description: Users related commands
    commands:
      - name: get
        type: exec
        description: Returns the user JWT
        flags:
          - name: out
            description: Save the output to a file. If not JSON, the file will be armored.
            default:
          - name: json
            description: Print the decoded jwt as JSON (exclusive of --raw)
            bool: true
            default:
        script: >-
          nsc describe user
          {{if .Flags.json}} --json {{ else }} --raw {{ end }}
          {{ if .Flags.out }} --output-file "{{ .Flags.out }}" {{ end }}
      - name: list
        type: exec
        description: list all users in the current account
        script: |
          nsc list users
      - name: describe
        type: exec
        arguments:
          - name: name
            description: The friendly name for the user
            required: true
        description: describe the user in the current account
        script: |
          nsc describe user --name "{{ .Arguments.name }}"
      - name: add
        type: exec
        description: Adds a new user
        arguments:
          - name: name
            description: The friendly name for this account
            required: true
        flags:
          - name: expiry
            description: Valid until '0' is always, '2M' is two months, yyyy-mm-dd
            default: 0
        script: |
          nsc add user --name "{{ .Arguments.name }}" --expiry "{{.Flags.expiry}}"
      - name: delete
        type: exec
        description: deletes the specified user
        arguments:
          - name: name
            description: The friendly name for this account
            required: true
        script: |
          nsc delete user --revoke --name "{{ .Arguments.name }}"
      - name: allow-perm
        type: exec
        description: add allow permissions
        arguments:
          - name: name
            description: The friendly name for the user
            required: true
        flags:
          - name: pubsub
            description: Add a pub and subscribe permission (comma separated)
            default:
          - name: sub
            description: Add a subscribe permission (comma separated)
            default:
          - name: pub
            description: Add a publish permission (comma separated)
            default:
          - name: respond
            description: Allow responses
            placeholder: max number of responses
            default: "1"
        script: >-
          nsc edit user --name "{{ .Arguments.name }}" 
          {{ if .Flags.pubsub }} --allow-pubsub "{{ .Flags.pubsub }}" {{end}}
          {{ if .Flags.sub }} --allow-sub "{{ .Flags.sub }}" {{end}}
          {{ if .Flags.pub }} --allow-pub "{{ .Flags.pub }}" {{end}}
          {{ if .Flags.respond }} --allow-pub-response="{{.Flags.respond}}" {{end}}
      - name: deny-perm
        type: exec
        description: add deny permissions
        arguments:
          - name: name
            description: The friendly name for the user
            required: true
        flags:
          - name: pubsub
            description: Add a deny pub and subscribe permission (comma separated)
            default:
          - name: sub
            description: Add a subscribe permission (comma separated)
            default:
          - name: pub
            description: Add a publish permission (comma separated)
            default:
          - name: respond
            description: Allow responses
            placeholder: max number of responses
            default: "1"
        script: >-
          nsc edit user --name "{{ .Arguments.name }}" 
          {{ if .Flags.pubsub }} --deny-pubsub "{{ .Flags.pubsub }}" {{end}}
          {{ if .Flags.sub }} --deny-sub "{{ .Flags.sub }}" {{end}}
          {{ if .Flags.pub }} --deny-pub "{{ .Flags.pub }}" {{end}}
      - name: remove-perm
        type: exec
        description: remove allow/deny pub/sub and respond restrictions
        arguments:
          - name: name
            description: The friendly name for the user
            required: true
        flags:
          - name: rm
            description: Remove a publish and/or subscribe permission to the specified subject(s) (comma separated)
            default:
          - name: rm-respond
            description: Remove response permission
            bool: true
            default:
        script: >-
          nsc edit user --name "{{ .Arguments.name }}" 
          {{ if .Flags.rm }} --rm "{{ .Flags.rm }}" {{end}}
          {{ if index .Flags "rm-respond" }} --rm-response-perms {{end}}
      - name: creds
        type: exec
        description: generate creds for an user
        arguments:
          - name: name
            description: The friendly name for the user
            required: true
        flags:
          - name: account
            description: the users account
            default:
          - name: out
            description: Save the output to a file. If not JSON, the file will be armored.
            default:
        script: >-
          nsc generate creds
          {{ if .Flags.account }} --account "{{ .Flags.account }}" {{end}}
          --name "{{ .Arguments.name }}" 
          {{ if .Flags.out }} --output-file "{{ .Flags.out }}" {{ end }}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal Enhancement idea or proposal
Projects
None yet
Development

No branches or pull requests

2 participants