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

Does JetStream key-value store support authorization for each user? #3548

Closed
tomghuang opened this issue Oct 13, 2022 · 6 comments
Closed

Does JetStream key-value store support authorization for each user? #3548

tomghuang opened this issue Oct 13, 2022 · 6 comments

Comments

@tomghuang
Copy link

tomghuang commented Oct 13, 2022

NATS already supports authorization using subject-level permissions on a per-user basis. However, does NATS also support such authorization mechanism for the key-value store?

For example, can I say user A can only access key A, user B can only access key B, but admin can access all keys?

We want to use JetStream key-value store in a NATS cluster, because NATS can automatically synchronize servers and make sure the key-value store is consistent in the cluster. However, we don't know if we can configure its authorization setting, so that each user can only access some of the keys. Is there anyway to achieve this? Thanks.

@derekcollison
Copy link
Member

With direct gets by subject yes that is possible. You would need to suppress the other access methods to secure it.

@tomghuang
Copy link
Author

@derekcollison : Thanks for your suggestion and confirming that it is possible.

To prove that, I created a bucket, test_kv, and three users: admin, router001, and router002. Each router stores its settings under the dev.<id> key. The goal is that router002 should not be able to access keys belonging to router001, which is under the dev.001 key. I've successfully proved that with the following configuration:

jetstream {
   max_memory_store: 1073741824
   max_file_store: 10737418240
}

authorization: {
    users: [
        {
            user: admin, password: "admin",
            permissions: {
                subscribe: ">",
                publish: ">"
            }
        },

        {
            user: router001, password: "router001",
            permissions: {
                subscribe: ["dev.001.>", "_INBOX.>"],
                publish: [
                    "dev.001.>",
                    "$JS.API.STREAM.INFO.>",
                    "$KV.test_kv.dev.001.>",
                    "$JS.API.DIRECT.GET.KV_test_kv.$KV.test_kv.dev.001.>"
                ]
            }
        },

        {
            user: router002, password: "router002",
            permissions: {
                subscribe: "dev.002.>",
                publish: "dev.002.>"
            }
        }
    ]
}

Although I've successfully achieved what I want, I do not feel confident in what I've done. I added those subject wildcard patterns simply because the error messages told me that I didn't have permission to access them, not because I understand how to do it. I don't know if subjects like $JS.API.STREAM.INFO, $KV.test_kv.dev.001, and $JS.API.DIRECT.GET.KV_test_kv.$KV.test_kv.dev.001 are meant to be used in this way. I don't know if there is any other "official/better" way to setup the permission for the key-value store.

Can the NATS team enhance the key-value store document, so that we can understand how to properly setup key-value store permission for each user? Thanks.

@derekcollison
Copy link
Member

Those are indeed the correct permissions.

We will look into enhancing the docs, thanks.

/cc @bruth @jnmoyne

@bruth
Copy link
Member

bruth commented Oct 21, 2022

@tomghuang Thanks for calling this out. Defining JS/KV-specific permissions is definitely a bit low-level as of now. Assuming you only need to put and get values from the KV, here is a minimal example that should achieve what you need: https://nats-by-example-q877a1djf-connecteverything.vercel.app/examples/auth/perms/cli (below the code shows the output)

@tomghuang
Copy link
Author

@bruth : Really appreciate the official clearly-explained example. It helps to complete my understanding of the key-value store feature.

@bjorndm
Copy link

bjorndm commented Mar 12, 2024

I would like to define many permissions per user, so for me it is somewhat difficult to define 3 permissions per key like this:

 "\$JS.API.STREAM.INFO.KV_test_kv",
"\$KV.test_kv.dev.001.>",
"\$JS.API.DIRECT.GET.KV_test_kv.\$KV.test_kv.dev.001.>" 

I would appreciate it if there was a more user-friendly way of defining key-value permissions and object store read and write.

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

No branches or pull requests

4 participants