When a user upgrades from InfluxDB 1.x to InfluxDB 2.x, we would like to avoid requiring the operator to update the configuration of their clients. Therefore, it is a requirement that InfluxDB 2.x can authenticate v1 requests using BASIC auth with existing username and password tokens. The 1.x to 2.x upgrade dictates that users will be migrated to a single admin user and will be issued tokens with fine-grained permissions. Importantly, these V2 tokens must be derived from username and password.
To summarize,
username and password credentials via an Authorization header using the BASIC schema or via the u (username) and p (password) query parameters; and username and password credentials specified as an Authorization header or via the u and p query parameters.username and password as username:password and passed the value through a 1-way cryptographically secure hash functionusername:passwordHTTP API:
/authorizations APIinflux v1 auth commandCreate an v1 auth subcommand to create, list and delete V1 authorization tokens using the private HTTP API
For the 1.x -> 2.x upgrade, the authentication token key will be formatted as username:password with a description set to the username.
/write or /query will provide a username and password via a BASIC authorization header or the u and p query parametersusername:password will be passed through the matching cryptographically secure hash function, such as SHA256Seems ok, but I'd like to have other people take a look to see if they find any issue with the approach. I'm not close enough to this code to be able to validate it.
👍 The primary goal of this proposal is to
By hashing the passwords with sha256 do you mean salt + hash the passwords? A sha256 by itself is a message digest and needs to be used in combination with other mathematical operations for sensitive data storage. Without salting, all hashes of the same password will result in the same output. I also seem to recall that sha hashes are not good for passwords because they are considered fast hashes? For passwords you want something slow so that it takes more time to crack if someone gets the string. I am not sure if this is still the standard but the recommendation a few years ago was bcrypt. Here is an example with go https://medium.com/@jcox250/password-hash-salt-using-golang-b041dc94cb72. OWASP recommendations for secure password storage https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html.
saltedBytes := []byte(s)
hashedBytes, err := bcrypt.GenerateFromPassword(saltedBytes, bcrypt.DefaultCost)
I recommend against sha256 for password hashing, PBKDF2, bcrypt or scrypt should be used with a salt. The password library in influxdb1.x or kapacitor does this properly
@derektamsen and @docmerlin – I am absolutely in agreement that _passwords_ should not be SHA256 hashed; my previous implementations also use bcrypt. One can argue that authorization tokens are also passwords (and I agree, they are), but in most cases they should have limited permissions, particularly for this use case.
It may not be clear in the original issue, but this is a nuanced problem and these are not passwords stored in a User object users with full permissions.
This proposal is to be able to generate authorization tokens with a predetermined key. The primary use case will be creating tokens for 1.x users against the operator account with limited access to specific buckets in a 2.0 instance.
Specifically, this expands the existing authorizations system with a new, one-way token, which stores the tokens keyed only by their SHA256 hash and therefore they are not recoverable except by brute force. Two users using the same password will also not hash to the same value, as effectively the username: is a form of salt. If users are using strong passwords, these should be no less secure that generating tokens using cryptographically random bytes, except now we are only storing the hash.
Most helpful comment
Seems ok, but I'd like to have other people take a look to see if they find any issue with the approach. I'm not close enough to this code to be able to validate it.