Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:00,000 --> 00:00:14,800
In this episode, we're having a look at ActiveRecord encryption, which is a very important part
2
00:00:14,800 --> 00:00:16,720
of protecting your data.
3
00:00:16,720 --> 00:00:21,920
And this differs from hashing that you might see with device or other authentication methods
4
00:00:21,920 --> 00:00:27,840
where your password is hashed to the database, but it's no longer reversible to come out
5
00:00:27,840 --> 00:00:29,840
with the original password.
6
00:00:29,840 --> 00:00:35,440
Instead, when you log in, you would just compare that log in password to the hashed value
7
00:00:35,440 --> 00:00:37,440
that stored in the database.
8
00:00:37,440 --> 00:00:43,519
But with ActiveRecord encryption, instead, we are encrypting the data at rest, so in the database
9
00:00:43,519 --> 00:00:47,280
level, and it can be decrypted within our view.
10
00:00:47,280 --> 00:00:53,120
So in this example, we have our description, which is an action text, and we're going to encrypt
11
00:00:53,120 --> 00:00:56,160
that data as well as a passphrase.
12
00:00:56,160 --> 00:01:01,760
So when we create the user, it doesn't seem like anything special is happening until you look
13
00:01:01,760 --> 00:01:03,919
at the application logs.
14
00:01:03,919 --> 00:01:08,960
So if we scroll up a bit, we can see where this user has been created, and then we can see
15
00:01:08,960 --> 00:01:15,840
that the passphrase, instead of having the original data as talkosoup, it is encrypted.
16
00:01:15,840 --> 00:01:20,960
And the same for the action text that was inserted, the body is encrypted, so you can't really
17
00:01:20,960 --> 00:01:23,360
make sense of its information.
18
00:01:23,360 --> 00:01:28,320
The one important thing to note is that Rails does a good job at certain attributes that
19
00:01:28,320 --> 00:01:32,560
will automatically filter its value from the logs.
20
00:01:32,560 --> 00:01:38,080
So you can see with the passphrase, I did not do in this example application anything different
21
00:01:38,080 --> 00:01:44,080
for the passphrase, but the description you'll see that it comes over as plain text,
22
00:01:44,080 --> 00:01:48,880
and that would be a security concern if this attribute needed to be protected.
23
00:01:48,880 --> 00:01:53,440
And there's a lot of reasons why you would want to use something like active record encryption,
24
00:01:53,440 --> 00:01:57,679
and some of its highlighted benefits is if your database is ever leaked or the logs are
25
00:01:57,679 --> 00:02:02,960
ever leaked, then the actor who gained access to that information wouldn't be given privy
26
00:02:02,960 --> 00:02:04,240
information.
27
00:02:04,240 --> 00:02:09,440
But of course, with the encryption, we have the decryption layer, which is done at the application
28
00:02:09,440 --> 00:02:15,600
level, and as we use this application, we're able to then see it in plain text.
29
00:02:15,600 --> 00:02:22,000
So the first thing that we'll do is call Rails action underscore text, colon install, to install
30
00:02:22,000 --> 00:02:28,640
the migration for action text, and to get that all set up, we'll then generate a scaffold
31
00:02:28,640 --> 00:02:33,600
for a user's table, and we'll have a name, we'll have an email address, and then we'll have
32
00:02:33,600 --> 00:02:39,120
some kind of protected information that would be really important not to leak out.
33
00:02:39,120 --> 00:02:41,519
So we'll call this the passphrase.
34
00:02:41,520 --> 00:02:46,000
And so once we have this done, we can go ahead and run our migrations, and while we're in the
35
00:02:46,000 --> 00:02:52,800
terminal, we'll go ahead and run the command db, colon encryption, colon init, and then we can
36
00:02:52,800 --> 00:02:57,600
copy the output from this and add it into our credentials.
37
00:02:57,600 --> 00:03:04,880
So we can run the bin Rails credentials, colon edit, and then we can simply just paste this in here.
38
00:03:04,880 --> 00:03:08,000
And this also does work if you have multiple environments.
39
00:03:08,000 --> 00:03:12,480
So if you pass the environment flag into the credentials edit, and you specify it in an
40
00:03:12,480 --> 00:03:16,560
environment like the development, then you would be able to do the same thing.
41
00:03:16,560 --> 00:03:21,520
If I wanted to run this command again to generate a new set of credentials, we could do that,
42
00:03:21,520 --> 00:03:26,000
so we can download this into our productions and cryptic credentials.
43
00:03:26,000 --> 00:03:31,040
And so we'll go ahead and set up the description, which is using the action text.
44
00:03:31,040 --> 00:03:34,120
So in the user model, we do a has rich text.
45
00:03:34,120 --> 00:03:39,000
We'll set this for the description, and if we want to start encrypting this, all we have to
46
00:03:39,000 --> 00:03:42,680
do is set this, encrypt it, is equal to true.
47
00:03:42,680 --> 00:03:47,160
And that's all you have to do to enable the encryption for action text.
48
00:03:47,160 --> 00:03:52,120
We of course would need to come into the user's controller in the permitted parameters,
49
00:03:52,120 --> 00:03:54,640
and we would also need to add the description.
50
00:03:54,640 --> 00:03:58,160
But we're not having to do anything extra around the encryption.
51
00:03:58,160 --> 00:04:02,960
Same way for the views, in the user's form, we can come in here, I'll just reuse this
52
00:04:02,960 --> 00:04:08,160
bit of code, instead of email, we'll have the description, and then we can change this to a rich
53
00:04:08,160 --> 00:04:09,680
text area.
54
00:04:09,680 --> 00:04:15,800
And so now we have a fully functional encryption at rest, feature, for the action text.
55
00:04:15,800 --> 00:04:19,880
And the nice thing about this is that we might be using action text in many areas of our
56
00:04:19,880 --> 00:04:24,880
application, but perhaps only this description field is the one that really needs to be
57
00:04:24,880 --> 00:04:29,800
encrypted because it contains personally identifiable information.
58
00:04:29,800 --> 00:04:34,800
And so then if you've created a modern Rails application, you can come under the config
59
00:04:34,800 --> 00:04:39,040
initializers, and there should be a filter parameter logging.
60
00:04:39,040 --> 00:04:42,120
And within here, there's already some examples.
61
00:04:42,120 --> 00:04:47,120
And if we needed to add an additional one by the description, we can do that here, and
62
00:04:47,120 --> 00:04:52,840
so now whenever we save something to the database, or anything comes through our application
63
00:04:52,840 --> 00:04:58,240
from the user input, this would be filtered out, so we wouldn't see the implying text
64
00:04:58,240 --> 00:04:59,760
in the logs.
65
00:04:59,760 --> 00:05:02,599
So now we just have to deal with the passphrase.
66
00:05:02,599 --> 00:05:07,920
And for that, we can do an encrypts, we can specify our passphrase, and that's all you
67
00:05:07,920 --> 00:05:12,120
have to do, and now this attribute will be encrypted at rest.
68
00:05:12,120 --> 00:05:16,640
However, there are some additional options that we may need to be concerned about.
69
00:05:16,640 --> 00:05:21,360
For example, if you want to be able to search on this attribute, you're not going to
70
00:05:21,360 --> 00:05:23,760
be able to by default.
71
00:05:23,760 --> 00:05:28,760
Because there is a flag called deterministic that is set to false by default.
72
00:05:28,760 --> 00:05:33,200
And if you never need to query the passphrase, then it's going to be best practice to
73
00:05:33,200 --> 00:05:35,200
have this set to false.
74
00:05:35,200 --> 00:05:38,560
And that's going to be the most secure way to store the data.
75
00:05:38,560 --> 00:05:44,200
But if there is a use case where you do need to query this, then you would want to set
76
00:05:44,200 --> 00:05:46,640
the deterministic set to true.
77
00:05:46,640 --> 00:05:52,080
And so this way, you're going to be able to do something like a user that find by, you
78
00:05:52,080 --> 00:05:57,000
can specify the passphrase, and then you can put in whatever string that you need.
79
00:05:57,000 --> 00:06:02,160
And because the passphrase attribute is set to deterministic, then you would be able to
80
00:06:02,160 --> 00:06:03,560
do this kind of query.
81
00:06:03,560 --> 00:06:08,840
However, if it was set to false, then you're not going to be able to query the passphrase,
82
00:06:08,840 --> 00:06:12,680
and you would just get a nil return in this particular example.
83
00:06:12,680 --> 00:06:17,640
Another thing that you may want to do, and this more dependent on your database, is to ignore
84
00:06:17,640 --> 00:06:18,640
the case.
85
00:06:18,640 --> 00:06:20,440
You can set this to true.
86
00:06:20,440 --> 00:06:22,800
You can also set it to downcase.
87
00:06:22,800 --> 00:06:27,200
So if you have something like an email address, then you can set the downcase at that
88
00:06:27,200 --> 00:06:28,200
to true.
89
00:06:28,200 --> 00:06:33,840
So actually convert the value to downcase when it's getting stored and encrypted.
90
00:06:33,840 --> 00:06:39,520
And if you will use ignore case, then it will be important that you add another attribute
91
00:06:39,520 --> 00:06:44,480
to your database, and that'll be the passphrase in this particular case.
92
00:06:44,480 --> 00:06:49,400
But you need to pre-fixes with the original underscore and then the attribute name.
93
00:06:49,400 --> 00:06:54,880
By adding in that attribute, then you're going to be able to use this ignore case, and
94
00:06:54,880 --> 00:07:01,359
that will store a downcase version before it's encrypted of the passphrase, but then it
95
00:07:01,359 --> 00:07:04,960
will store the passphrase in its original text.
96
00:07:04,960 --> 00:07:09,000
And this mainly going to be important when you're doing a query, and this will highly
97
00:07:09,000 --> 00:07:11,400
vary based on your use case.
98
00:07:11,400 --> 00:07:15,840
And depending on your situation, you might have some validations that you need to perform,
99
00:07:15,840 --> 00:07:22,159
and we can do that very easily as well with a validates, and then we specify our passphrase
100
00:07:22,159 --> 00:07:23,159
in this case.
101
00:07:23,159 --> 00:07:28,080
And we can do something like a uniqueness, and we can set this equal to true.
102
00:07:28,080 --> 00:07:32,440
And let's say we do have some kind of serialization that we are doing.
103
00:07:32,440 --> 00:07:37,679
Maybe a user has a group of settings, so you've added a JSON data type, and let's just
104
00:07:37,679 --> 00:07:42,840
call it settings to your database, and you want to encrypt this, because it might contain
105
00:07:42,840 --> 00:07:45,000
some sensitive information.
106
00:07:45,000 --> 00:07:50,120
And so you add the encrypt settings, and then you also add the serialized settings.
107
00:07:50,120 --> 00:07:54,440
And maybe we would set this to a hash or JSON or something similar.
108
00:07:54,440 --> 00:08:00,920
And this will work, however, the one issue here is that we would need to perform the serialization
109
00:08:00,920 --> 00:08:05,840
before the encryption, because the encryption is going to rely on the object being in
110
00:08:05,840 --> 00:08:10,200
a string, and not a more complex object like a hash.
111
00:08:10,200 --> 00:08:15,640
And so now we can test this out, we'll create a new user, we can enter in a description,
112
00:08:15,640 --> 00:08:18,240
and then we can enter in something for the passphrase.
113
00:08:18,240 --> 00:08:23,760
And if we go to the show page, we can see, and plain text, the L'Orealm Epsom of the
114
00:08:23,760 --> 00:08:26,800
description, and we can see the passphrase.
115
00:08:26,800 --> 00:08:31,800
And if we were to go to the logs and scroll up a bit, we can see where we have our posts
116
00:08:31,800 --> 00:08:33,120
for the user.
117
00:08:33,120 --> 00:08:38,159
And within the prints of this request, we have the user's name, as Jane Doe, we have the
118
00:08:38,159 --> 00:08:43,600
email address, the description is now filtered, so we did not see the plain text version
119
00:08:43,600 --> 00:08:47,600
of this, as well as the passphrase is filtered by default.
120
00:08:47,600 --> 00:08:52,480
But if it wasn't, then you would be able to add that to the filter parameters, logging
121
00:08:52,480 --> 00:08:54,719
within the Config Initializer.
122
00:08:54,719 --> 00:09:01,319
And even in the SQL queries that are creating the user, and inserting in, the encrypted attributes
123
00:09:01,319 --> 00:09:07,240
for the rich text, we can see that the passphrases encrypted, as well as the body
124
00:09:07,240 --> 00:09:09,120
for the action text.
125
00:09:09,120 --> 00:09:13,560
And if this is a feature that you need to add into your application, then I would highly
126
00:09:13,560 --> 00:09:17,680
recommend reading through the ActiveRecord Encryption documentation.
127
00:09:17,680 --> 00:09:22,320
And the ActiveRecord Encryption is much more extensible than we have covered.
128
00:09:22,320 --> 00:09:25,960
There are different things around the key management that you're able to do.
129
00:09:25,960 --> 00:09:30,440
If you have a different kind of strategy that you need to use for the encryption, and you're
130
00:09:30,440 --> 00:09:35,960
even able to rotate keys, providing that you give a previous key, just so you can
131
00:09:35,960 --> 00:09:42,760
so decrypt the content, and then you add in the Active key for any new content or updates.
132
00:09:42,760 --> 00:09:46,880
And if you realize that you need to add encryption after the fact, after you already
133
00:09:46,880 --> 00:09:52,040
have your database in production, and it's now determined that one of the attributes on
134
00:09:52,040 --> 00:09:54,760
a table does need to be encrypted.
135
00:09:54,760 --> 00:09:59,960
You are able to do this out of the box with ActiveRecord Encryption, and you would simply
136
00:09:59,960 --> 00:10:02,080
set in your environment.
137
00:10:02,080 --> 00:10:06,960
They can figure ActiveRecord Encryption and support Unencrypted Data.
138
00:10:06,960 --> 00:10:12,320
So you would still be able to read the data that was non-encrypted, but I think it's
139
00:10:12,320 --> 00:10:17,040
also important, and now it probably has some kind of rate task that would then take all
140
00:10:17,040 --> 00:10:19,600
the data and then encrypt it.
141
00:10:19,600 --> 00:10:23,720
Because you would want to leave one of the columns in your database that has some encrypted
142
00:10:23,720 --> 00:10:27,400
data in some unencrypted data in there too long.
143
00:10:27,400 --> 00:10:32,760
I think a rate task or something that can quickly get all of that data encrypted would
144
00:10:32,760 --> 00:10:34,400
be your best bet.
145
00:10:34,400 --> 00:10:37,120
And then you can come back and disable this flag.
146
00:10:37,120 --> 00:10:41,040
And there's also great support for the previous encryption schemes.
147
00:10:41,040 --> 00:10:46,000
And so let's say you had said it previously to determine a sick is set to false, or you
148
00:10:46,000 --> 00:10:49,079
just didn't have this deterministic flag at all.
149
00:10:49,079 --> 00:10:54,000
It defaults to false, but now you need to have a deterministic because later down the road
150
00:10:54,000 --> 00:10:58,720
you've now decided that this needs to be a choreoble attribute.
151
00:10:58,720 --> 00:11:03,560
And so there's a lot of good information here, and a lot of information that really is
152
00:11:03,560 --> 00:11:08,200
specific use cases depending on what you're currently experiencing.
153
00:11:08,200 --> 00:11:10,320
Well, that's all for this episode.
154
00:11:10,320 --> 00:11:25,600
Thanks for watching.
16164
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.