Open avdempsey opened 2 years ago
I'm thinking now check_password isn't such a hot idea. There isn't any caching of sessions going on right now, so each mint/bind/update request revalidates credentials. Using check_password will make this an increasingly expensive operation since Django increases the number of hashing iterations on each release.
Since we're using uuid4 as access keys a single hash iteration should be sufficient for now. Multiple hash iterations are useful when you have a more bound space of inputs (like the passw0rds!!123 humans come up with). The risk to memory institutions running arklet of brute forcing a uuid4 can be re-evaluated after quantum computers are out.
https://docs.python.org/3/library/secrets.html#secrets.compare_digest
Storing the Key.key as plaintext is a bad idea. There are implementations of token auth in Django Rest Framework, but one of the design goals for arklet is to have only standard lib and Django as production dependencies. We want it to be really inexpensive to stay with the latest versions of Python and Django.
Maybe we could use the built-in Django password functionality? https://docs.djangoproject.com/en/4.0/topics/auth/passwords/#module-django.contrib.auth.hashers
I don't want to use a User model for API authentication because it makes fleet secret management a little harder (have to coordinate password changes with the secrets getting updated across the fleet). The access key model works a little bit better for secret rotation. We can create a new access key, start distributing it, wait for everything to update, and deactivate the old key.
The Key model should not use the key UUIDField as the primary key on the table. We should add a regular integer primary key, and then create a separate charfield to hold the hash.
https://docs.djangoproject.com/en/4.0/topics/auth/passwords/#django.contrib.auth.hashers.check_password https://docs.djangoproject.com/en/4.0/topics/auth/passwords/#django.contrib.auth.hashers.make_password
check_password can be used against the authorization header make_password can be used with a UUID4 input to create the hash text to store in the Key.key field.
This would also necessitate a new view for one-time display of newly created keys.