github-education-resources / classroom

GitHub Classroom automates repository creation and access control, making it easy for teachers to distribute starter code and collect assignments on GitHub.
https://classroom.github.com
1.34k stars 566 forks source link

Encrypt tokens at rest #2485

Closed jeffrafter closed 4 years ago

jeffrafter commented 4 years ago

We'd like to encrypt the stored tokens at rest. To pursue this we'll be leveraging rbnacl with SimpleBox support. This relies on libsodium and is good. To build this we'll be building custom readers and writers for the token field to allow for versioned token generations and revocation.

https://github.com/RubyCrypto/rbnacl/wiki/SimpleBox

We'll also need to install libsodium on Travis and Heroku (via buildpack)

To deploy this we will need to pursue one of the following strategies:

New field option

  1. Create a new field crypted_token

  2. Write to both fields: token, crypted_token

  3. Run a transition to write legacy encrypted tokens

  4. Read from crypted_token

  5. Delete token

Existing field option

  1. Ensure no tokens start with GH_, make sure there are no nil tokens (confirmed!)

  2. Make a custom writer that writes the GH_ prefix and encrypted version of the password (check length constraints)

  3. Make a custom reader that checks for the GH_ prefix and if there decrypts the remaining password or returns the token as is

  4. Make sure:

    • the token_was and token_changed? functions still works (in ensure_no_token_scope_loss)
    • the uniqueness and presence validations still work (if you set it to nil does the prefix still get added?)

Given these two options, we are likely going to choose the existing field option.

cc @JessRudder @education/classroom

https://api.rubyonrails.org/classes/ActiveRecord/Base.html#class-ActiveRecord::Base-label-Overwriting+default+accessors