Skip to content
This repository has been archived by the owner on Mar 26, 2020. It is now read-only.

glustercli ReST auth should not use the GD2 secret directly #1030

Closed
kshlm opened this issue Jul 18, 2018 · 6 comments
Closed

glustercli ReST auth should not use the GD2 secret directly #1030

kshlm opened this issue Jul 18, 2018 · 6 comments

Comments

@kshlm
Copy link
Member

kshlm commented Jul 18, 2018

glustercli at the moment uses the GD2 secret directly to generate a JWT auth token. This is not secure. Clients to GD2 are not supposed to be accessing GD2's auth secret directly. They should instead be provided a token from GD2, which they need to pass on when making their ReST calls.

Currently, GD2 creates a secret file with a random secret when starting, which used for JWT token validation. I propose that in addition to this secret file, an additional token file be generated which would contain the token to be used by glustercli.

glustercli should use this default token file, and provide ways to specify an explicit token (env-variable/CLI options).

I only came upon the issue when reviewing #1021. Refer my comment for more context.

@aravindavk
Copy link
Member

glustercli at the moment uses the GD2 secret directly to generate a JWT auth token. This is not secure. Clients to GD2 are not supposed to be accessing GD2's auth secret directly. They should instead be provided a token from GD2, which they need to pass on when making their ReST calls.

You are talking about shared token approach which is not secure without https enabled. We discussed about this approach and we choose shared secret approach earlier. If on the wire token is compromised, then the same token can be used forever unless secret at server node is reset.

In case of shared secret approach, each token on the wire will have short expiry time. Even if a token is compromised it can't be used for making further API calls.

glustercli will have access to this secret file only in the server nodes. Outside the cluster, separate user management is required.

Currently, GD2 creates a secret file with a random secret when starting, which used for JWT token validation. I propose that in addition to this secret file, an additional token file be generated which would contain the token to be used by glustercli.

Only applicable if we choose shared token approach again.

@aravindavk
Copy link
Member

@kshlm
Copy link
Member Author

kshlm commented Jul 19, 2018

You are talking about shared token approach which is not secure without https enabled. We discussed about this approach and we choose shared secret approach earlier. If on the wire token is compromised, then the same token can be used forever unless secret at server node is reset.

About https, I'd prefer if we do https by default at least for encryption, if not for full TLS authentication. Which should be doable. @prashanthpai has filed #984 for GD2 to do the same for internal peer-peer connections, we should extend that to cover the ReST connections as well.

About token being compromised, I sure there are ways for servers to revoke bad tokens, without changing the secret. This requires that we implement some form of token management which includes revokation.

In case of shared secret approach, each token on the wire will have short expiry time. Even if a token is compromised it can't be used for making further API calls.

glustercli will have access to this secret file only in the server nodes. Outside the cluster, separate user management is required.

We need to implement a way to properly generate and manage tokens or users, and document that as the right way to get authenticated with GD2. We should not document the insecure way.

I have one other reason to support tokens over secrets. Sometime later, we will need to support authorization in addition to the authentication (in whatever limited form) we do now. The allowed apis and roles a client can be embedded in the claims of a JWT, which can be used to authorize clients for specific APIs. If we were to head down this way to do authorization, we cannot have clients generating their own tokens.

@aravindavk
Copy link
Member

Feeling very sad about having this discussion again. (REST authentication feature was added in Nov 2017 and patch is approved by you #401)

About https, I'd prefer if we do https by default at least for encryption, if not for full TLS authentication. Which should be doable. @prashanthpai has filed #984 for GD2 to do the same for internal peer-peer connections, we should extend that to cover the ReST connections as well.

https is not the only reason against token based approach.

  • If you use common secret to generate tokens for multiple users and one user's token is compromised. If you change the secret, then it will affect all the other users as well.
  • When token is generated, if you set long expiry then there is separate mechanism required to renew the token. Clients has to keep track of expiry time and renew the token before the expiry.

Shared token approach is more suitable for website logins where in case of session expiry it can redirect to login page.

We need to implement a way to properly generate and manage tokens or users, and document that as the right way to get authenticated with GD2. We should not document the insecure way.

I agree, as I commented in #1021 I will remove external clients section till user management is implemented.

I have one other reason to support tokens over secrets. Sometime later, we will need to support authorization in addition to the authentication (in whatever limited form) we do now. The allowed apis and roles a client can be embedded in the claims of a JWT, which can be used to authorize clients for specific APIs. If we were to head down this way to do authorization, we cannot have clients generating their own tokens.

That should be possible with shared secret approach as well. May be we need a lookup to decide role or url access.

@kshlm
Copy link
Member Author

kshlm commented Jul 19, 2018

Feeling very sad about having this discussion again. (REST authentication feature was added in Nov 2017 and patch is approved by you #401)

Sorry about that. I didn't realize the full extent about this then (I was probably more looking out for implementation details).

I was looking at casbin as a way to do authorization. It supports what we need, user/role based access and support for ReST.

Using it we could come up with way to solve our issue here about token/secret revocation. We would go about it as follows.

  • Casbin would be setup as a authorization (authz) middleware below the jwt authentication (authn) middleware

  • When we need to generate a new token,

    • create a new user with a random id and assign access methods or roles for the user in casbin
    • now create a jwt token with the user-id as a claim, and sign it with our secret.
    • give this token out to the client
  • The client passes this token when making requests

    • The jwt authn middleware will ensure that the token is genuine, and something we generated
    • The casbin authz middleware, would fetch the user-id from the token and verify the the user is authorized
  • If a token is stolen, we just remove the user-id for the token from casbin. If someone tries to use the stolen token, it would pass through the authn middleware but the authz middleware would reject the request.

@aravindavk
Copy link
Member

Closing this issue since Gd2 implements shared secret JWT authentication. CLI only gets access to default secret if CLI is running on the same node. Secret needs to be passed or set via env variable if CLI needs be run from external nodes. Please re-open this issue if this still needs discussion

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

No branches or pull requests

2 participants