WEBVTT

00:00:00.001 --> 00:00:04.520
Think about the different APIs and databases your applications work with.

00:00:04.520 --> 00:00:10.980
Each one of them requires either an API key or a database connection string that itself contains a password.

00:00:10.980 --> 00:00:19.580
How do you let your application access this sensitive information without storing it in source code or putting it in other compromising locations?

00:00:19.580 --> 00:00:27.320
On this episode, we have Glyph on the show to share his security fable, as well as just good advice for keeping secrets out of Python code.

00:00:27.600 --> 00:00:33.060
This is Talk Python To Me, episode 418, recorded May 24th, 2023.

00:00:33.060 --> 00:00:49.940
Welcome to Talk Python To Me, a weekly podcast on Python.

00:00:49.940 --> 00:00:51.680
This is your host, Michael Kennedy.

00:00:51.680 --> 00:00:56.780
Follow me on Mastodon, where I'm @mkennedy and follow the podcast using @talkpython.

00:00:56.780 --> 00:00:59.160
Both on Bostodon.org.

00:00:59.160 --> 00:01:01.760
Be careful with impersonating accounts on other instances.

00:01:01.760 --> 00:01:02.740
There are many.

00:01:02.740 --> 00:01:07.800
Keep up with the show and listen to over seven years of past episodes at talkpython.fm.

00:01:07.800 --> 00:01:11.820
We've started streaming most of our episodes live on YouTube.

00:01:11.820 --> 00:01:19.360
Subscribe to our YouTube channel over at talkpython.fm/youtube to get notified about upcoming shows and be part of that episode.

00:01:20.020 --> 00:01:26.040
This episode is brought to you by JetBrains, who encourage you to get work done with PyCharm.

00:01:26.040 --> 00:01:32.940
Download your free trial of PyCharm Professional at talkpython.fm/done dash with dash PyCharm.

00:01:32.940 --> 00:01:36.840
And it's brought to you by the compiler podcast from Red Hat.

00:01:36.840 --> 00:01:43.920
Listen to an episode of their podcast to demystify the tech industry over at talkpython.fm/compiler.

00:01:44.800 --> 00:01:46.420
Cliff, welcome to Talk Python To Me.

00:01:46.420 --> 00:01:47.240
It's good to be here.

00:01:47.240 --> 00:01:48.420
Thank you very much for having me.

00:01:48.420 --> 00:01:50.120
It is good to have you here.

00:01:50.120 --> 00:01:51.960
And it's good to have you back.

00:01:51.960 --> 00:01:54.460
You've been on the show a couple of times.

00:01:54.460 --> 00:01:58.060
Way back when you talked about shipping software to users.

00:01:58.320 --> 00:02:03.720
And then also not so long ago, a little while ago, we talked about running Python in production.

00:02:03.720 --> 00:02:09.140
And those were a bunch of fun shows and really excited to now talk about secrets.

00:02:09.140 --> 00:02:11.960
Although it does pose a bit of a problem.

00:02:11.960 --> 00:02:14.760
If we talk about secrets, are they still secrets?

00:02:14.760 --> 00:02:17.740
That is an interesting epistemological question.

00:02:17.740 --> 00:02:21.180
But luckily, that's not the question that we need to answer today.

00:02:21.480 --> 00:02:25.260
Because the kinds of secrets we're going to talk about are the ones that are meaningless.

00:02:25.260 --> 00:02:29.300
They are, by definition, not very interesting to humans, but to computers.

00:02:29.300 --> 00:02:30.220
Yes, they are.

00:02:30.220 --> 00:02:37.360
They're both for you to access your database and cryptocurrency people to get cheaper crypto mining.

00:02:37.360 --> 00:02:39.660
Depending on which way it goes, if you do it right or wrong.

00:02:39.660 --> 00:02:42.420
So before we get into that, let's just do a quick catch up.

00:02:42.420 --> 00:02:46.880
It's been at least a year since you've been on the show a little bit more.

00:02:47.080 --> 00:02:48.320
So what have you been up to?

00:02:48.320 --> 00:02:49.360
What are you doing these days?

00:02:49.360 --> 00:02:51.960
I am nominally independent now.

00:02:51.960 --> 00:02:57.660
I am trying to make a career out of having good ideas and putting them on the internet.

00:02:57.660 --> 00:03:00.380
Work for a lot of different companies, doing a lot of different things.

00:03:00.380 --> 00:03:01.840
Now I am making my own app.

00:03:01.840 --> 00:03:05.700
I'm making an app called Pomodorobros, which is a terrible name that I'm sure you can't spell.

00:03:05.700 --> 00:03:13.500
But I'm sure we'll have some links in the show notes to get to that, which is an ADHD time blindness assistance app.

00:03:13.500 --> 00:03:14.000
Interesting.

00:03:14.400 --> 00:03:18.220
So on the one hand, I'm kind of leaning into the neurodiversity thing.

00:03:18.220 --> 00:03:21.420
I have ADHD and I'm kind of trying to help other people with it as well.

00:03:21.420 --> 00:03:24.480
But also it is written entirely in Python.

00:03:24.480 --> 00:03:28.440
I'm working on the Mac version first, but there'll be other versions later and it's all open source.

00:03:28.440 --> 00:03:34.760
And so I have a Patreon at patreon.com slash creator glyph, which has just terrible reward tiers.

00:03:34.760 --> 00:03:36.400
Hopefully I'll improve those soon.

00:03:36.400 --> 00:03:41.100
But the idea is if you want to support like various open source libraries that I'm working on maintaining,

00:03:41.480 --> 00:03:45.780
we'll talk about a couple of new ones that I've released recently in this podcast.

00:03:45.780 --> 00:03:50.560
If you want to support the random stuff that I do, now you can.

00:03:50.560 --> 00:03:51.600
And so we'll see.

00:03:51.600 --> 00:03:54.300
People have been telling me for years that they love the stuff that I do.

00:03:54.300 --> 00:03:56.780
So I guess we'll find out if they in fact do.

00:03:56.780 --> 00:03:58.960
Well, congratulations.

00:03:58.960 --> 00:03:59.880
That's really awesome.

00:03:59.880 --> 00:04:08.320
As somebody doing independent stuff myself, I know how rewarding it is, but also how stressful it is, especially early days.

00:04:08.320 --> 00:04:08.620
Yep.

00:04:08.620 --> 00:04:11.140
It is equal parts harrowing and amazing.

00:04:11.140 --> 00:04:13.480
Yes, that's well said.

00:04:13.480 --> 00:04:14.340
Well said.

00:04:14.340 --> 00:04:17.340
So yeah, certainly we will link to those in the show notes.

00:04:17.340 --> 00:04:18.200
You give me the links.

00:04:18.200 --> 00:04:19.200
I'll throw them in there for people.

00:04:19.200 --> 00:04:24.920
You said something interesting that I don't hear a lot of people say that I actually wish I heard more often was,

00:04:24.920 --> 00:04:28.600
I'm working on a macOS version and the word's Python.

00:04:29.600 --> 00:04:34.540
So this is actually kind of dovetails with what we're going to be talking about today in an interesting way,

00:04:34.540 --> 00:04:42.480
which is that one of the things that I want to be doing with my independent work is kind of letting people program their own computers.

00:04:42.480 --> 00:04:45.540
And part of that is like a lot of people use Macs.

00:04:45.540 --> 00:04:48.100
So I'm working on Mac desktop stuff.

00:04:48.100 --> 00:04:49.800
I hope to do some mobile stuff later.

00:04:50.220 --> 00:04:54.380
I also want to do Linux and Windows desktop versions of this app and then others.

00:04:54.380 --> 00:04:57.700
Because I think that it's, we've lost touch with that a little bit.

00:04:57.700 --> 00:05:01.640
You know, we all do stuff in the cloud these days, particularly in Python.

00:05:01.640 --> 00:05:04.500
But Python is so versatile and you can use it in so many places.

00:05:04.700 --> 00:05:11.960
And the way that that sort of dovetails with what we're going to be talking about today is that it's also a neglected part of the security story.

00:05:11.960 --> 00:05:21.300
Because no matter how great all of your cloud security is, you're using AWS Secrets Manager and HashiCorp Vault and, you know, all kinds of cloud security stuff.

00:05:21.300 --> 00:05:24.380
It all kind of terminates at your computer.

00:05:24.380 --> 00:05:31.180
If your computer is not secure, if the secrets that you have locally in your possession are not properly managed,

00:05:31.320 --> 00:05:34.820
then all of the cloud stuff, like you're doing it from your computer.

00:05:34.820 --> 00:05:36.880
So that computer had better be secure.

00:05:36.880 --> 00:05:43.020
And if it's not, that kind of flows outward towards everything else if you're a developer or a sysadmin.

00:05:43.020 --> 00:05:47.580
So, yeah, so the two libraries that we're going to be talking about today are also both,

00:05:47.580 --> 00:05:51.080
they're a little bit more traditional kind of console text things,

00:05:51.080 --> 00:05:55.100
but they are designed to be run on your computer and not on the cloud.

00:05:55.100 --> 00:05:55.980
Yeah, absolutely.

00:05:55.980 --> 00:06:00.500
It's a lot of interesting things for like, how do you secure secrets?

00:06:00.980 --> 00:06:03.620
Connection strings and whatnot on your machine, right?

00:06:03.620 --> 00:06:03.900
Yeah.

00:06:03.900 --> 00:06:06.620
So, and as far as the other sort of desktop programming stuff,

00:06:06.620 --> 00:06:08.600
we do not have time to get into that today,

00:06:08.600 --> 00:06:13.380
but you can definitely follow my blog for more interesting details about how PyObjective-C works.

00:06:13.380 --> 00:06:13.640
Right.

00:06:13.640 --> 00:06:18.620
Are you willing to share a quick what GUI framework you're using sort of thing

00:06:18.620 --> 00:06:20.640
and how are you packaging it up or not yet?

00:06:20.640 --> 00:06:24.120
I wrote a little tool called Encrust that does some of the code signing stuff.

00:06:24.120 --> 00:06:26.300
I'm packaging it with PyToApp right now.

00:06:26.800 --> 00:06:33.460
And as for GUI framework, I'm just using PyObjective-C and writing all of the GUI by hand as like a traditional Mac.

00:06:33.460 --> 00:06:39.520
I plan to redo the GUI for each platform because Pometer Obros is a thing that needs to be a local Mac app,

00:06:39.520 --> 00:06:41.600
like it can, or a local desktop app rather.

00:06:41.600 --> 00:06:47.300
And so I really want to get the UI very kind of finely tuned per platform.

00:06:47.300 --> 00:06:50.980
And so cross-platform GUI toolkits don't really do some of the stuff that I need to do.

00:06:51.640 --> 00:06:54.120
So, and that's kind of part of the point I want to make with it is,

00:06:54.120 --> 00:06:57.680
it's actually not that hard to just like write things multiple times.

00:06:57.680 --> 00:07:00.580
The Python lets you keep all the logic and a nice kind of core.

00:07:00.580 --> 00:07:04.760
And then if you need to call some native APIs, Python can do that pretty much everywhere.

00:07:04.760 --> 00:07:05.280
Okay.

00:07:05.280 --> 00:07:06.900
Well, very interesting approach.

00:07:06.900 --> 00:07:09.640
I think one of the things that's held me back from going,

00:07:09.640 --> 00:07:13.000
oh, I'm going to use TK Enter or GDK or whatever.

00:07:13.000 --> 00:07:16.620
It's just like, oh, but it just doesn't really look like it belongs here that much.

00:07:16.620 --> 00:07:19.740
It looks kind of like it belongs here, but not really.

00:07:19.740 --> 00:07:21.620
And that, I don't know, some people don't mind that.

00:07:21.620 --> 00:07:23.520
To me, it's just, I'm not a big fan.

00:07:23.520 --> 00:07:25.020
So I'm looking forward to this.

00:07:25.020 --> 00:07:26.080
It sounds great.

00:07:26.080 --> 00:07:26.320
Cool.

00:07:26.320 --> 00:07:29.000
Maybe you can have me on again to talk about it when it's closer to done.

00:07:29.000 --> 00:07:29.700
Yeah, absolutely.

00:07:29.700 --> 00:07:32.660
It'd be fun to talk about, you know, sort of going through and building,

00:07:32.660 --> 00:07:36.860
how you built it and some lessons that you've learned, right?

00:07:36.860 --> 00:07:41.520
Also, I'm working on some desktop apps now and it's not as easy as it used to be.

00:07:41.520 --> 00:07:42.980
It's like, oh, this one's not signed.

00:07:42.980 --> 00:07:47.960
And so it won't open because the macOS gatekeeper says it's probably dangerous.

00:07:47.960 --> 00:07:51.400
And you're just like, God, I usually will just hand out an app, all right?

00:07:51.400 --> 00:07:53.360
We can't have nice things because of people.

00:07:53.360 --> 00:07:56.340
And I guess that's pretty much a great lead into this entire talk,

00:07:56.340 --> 00:08:00.260
because if we could have nice things, we wouldn't even need this talk, would we?

00:08:00.260 --> 00:08:00.760
Exactly.

00:08:00.760 --> 00:08:05.820
I guess it's worth mentioning that I reached out to you and had you on the show here

00:08:05.820 --> 00:08:09.760
because you gave a talk at PyCon, How to Keep a Secret.

00:08:10.320 --> 00:08:11.680
And what is it today?

00:08:11.680 --> 00:08:12.980
It's May 24th.

00:08:12.980 --> 00:08:15.060
So a month and two days.

00:08:15.060 --> 00:08:19.720
And I was kind of looking forward to watching all these on YouTube and they're not out yet.

00:08:19.720 --> 00:08:24.640
So how about we have a podcast episode about it and share that with everyone?

00:08:24.640 --> 00:08:29.740
So I'm looking forward to kind of doing the audio conversational version of your talk.

00:08:29.740 --> 00:08:30.960
How did your talk go there?

00:08:30.960 --> 00:08:31.780
I thought it went great.

00:08:31.780 --> 00:08:32.940
There was pretty good response.

00:08:32.940 --> 00:08:38.600
One of the things I did, which I would recommend for other conference attendees and speakers in the future,

00:08:38.600 --> 00:08:43.080
is whenever anybody came up to me and said, great talk, which is very nice.

00:08:43.080 --> 00:08:44.300
I appreciate it when people do that.

00:08:44.300 --> 00:08:46.300
I didn't just say thanks.

00:08:46.300 --> 00:08:47.640
I said, thank you.

00:08:47.640 --> 00:08:50.700
And how is this going to affect your behavior going forward?

00:08:50.700 --> 00:08:53.320
What did you learn from the talk that's going to change what you do?

00:08:53.560 --> 00:08:59.060
And a lot of people had specific things that they were going to change about their workflows or their kind of personal security.

00:08:59.060 --> 00:09:02.200
And so that was telling me, like, I think this is an important message to get out there.

00:09:02.200 --> 00:09:05.020
And I think that it's something that every developer should know about.

00:09:05.860 --> 00:09:10.600
So the fact that people were, like, really learning from it, I thought, was the best metric for success.

00:09:10.600 --> 00:09:13.480
It's got a lot of small lessons for many people.

00:09:13.480 --> 00:09:17.260
And I suspect most people are not doing all of these things.

00:09:17.260 --> 00:09:22.980
So even if you're like, yes, of course, I keep, you know, I don't put secrets into my source code.

00:09:22.980 --> 00:09:23.660
Or do you?

00:09:23.660 --> 00:09:24.760
But there's something else.

00:09:24.760 --> 00:09:26.180
I'm sure there's something for everyone here.

00:09:26.180 --> 00:09:31.080
So let's kick things off by talking about what you mean by secrets.

00:09:31.080 --> 00:09:31.580
All right.

00:09:31.580 --> 00:09:33.240
What are we talking about here specifically?

00:09:33.240 --> 00:09:38.960
So the main kind of secret that I'm talking about is a token type of secret.

00:09:38.960 --> 00:09:47.460
Whenever you use an API on the web, they'll give you, like, a little hex key, usually a short string that lets you access it.

00:09:47.460 --> 00:09:56.720
Cryptographic secrets, like if you have some encrypted blob that's stored in block storage, you might have crypto key that's a similar kind of thing.

00:09:56.720 --> 00:10:07.240
For your HTTPS certificates, you've got, like, you know, private RSA key or something or ECTSA key that's a little bit longer, but still kind of text file that's no more than 20 lines.

00:10:07.940 --> 00:10:10.780
And so all of those secrets are kind of interesting.

00:10:10.780 --> 00:10:33.060
And I wanted to talk about them in particular because the way that security works just on computers generally is that all of your other security, all of the other bigger secrets you want to keep, the confidential documents, you know, media files or whatever it is that you're securing, your database, your user accounts, all of that stuff is secured by a smaller secret.

00:10:33.060 --> 00:10:40.000
And so these secrets generally represent some kind of authority, like a thing that you can do in the cloud.

00:10:40.000 --> 00:10:44.460
Even cryptographic ones are kind of like the authority to decrypt another secret.

00:10:44.460 --> 00:10:56.700
And so that's, in particular, the reason that restriction of the scope of this discussion to those smaller secrets is interesting is because those smaller secrets don't have, like, a lot of interesting storage requirements.

00:10:56.700 --> 00:11:03.580
Like, they just, they're very small, and it's really about how you secure them, not so much about how you manage, like, a huge scale of them.

00:11:03.580 --> 00:11:13.520
Yeah, also, if you're going to, say, encrypt huge blobs of data, usually what you actually need to get back to it is just the encryption key, right?

00:11:13.520 --> 00:11:14.960
Which is often pretty small, right?

00:11:14.960 --> 00:11:21.200
So even if the actual data is large, usually the thing that is the access to it is also small.

00:11:21.200 --> 00:11:21.500
Right.

00:11:21.600 --> 00:11:23.300
What you said you were not covering?

00:11:23.300 --> 00:11:25.500
Into encryption and that kind of stuff, right?

00:11:25.500 --> 00:11:28.520
There's a lot of other security stuff that you need to do.

00:11:28.520 --> 00:11:31.620
Like, I touched briefly in the talk on disk encryption.

00:11:31.620 --> 00:11:35.460
We can talk about that in a little bit, but it's mostly not about that.

00:11:35.460 --> 00:11:42.660
In particular, like, there's been a lot of discussion lately about end-to-end encrypted messaging between people, and I'm not really talking about that either.

00:11:43.440 --> 00:11:45.280
This is really about securing your applications.

00:11:45.280 --> 00:12:01.120
It's, it's, a lot of these techniques have to do with how you get your secrets, not just secured for you, but, like, into your Python code in a way which keeps them secure, kind of on the whole journey from typing them in to using them in a production application.

00:12:01.120 --> 00:12:01.520
For sure.

00:12:01.520 --> 00:12:01.520
For sure.

00:12:01.520 --> 00:12:05.640
I, I would just, as you're talking, I'm thinking, this problem is only getting worse, right?

00:12:05.640 --> 00:12:13.900
We're only consuming more APIs in our code, and we're only stitching together more back ends of cloud systems, right?

00:12:13.900 --> 00:12:14.360
Yeah.

00:12:14.360 --> 00:12:15.560
We've been writing code for a while.

00:12:15.560 --> 00:12:16.040
I have too.

00:12:16.040 --> 00:12:18.320
Like, it used to be, well, what's your database connection streak?

00:12:18.320 --> 00:12:18.880
All right, we're good.

00:12:18.880 --> 00:12:19.640
We're done.

00:12:19.640 --> 00:12:20.680
That's what you store, right?

00:12:20.680 --> 00:12:21.460
How do you store that?

00:12:21.460 --> 00:12:27.120
Well, and if you were doing something really esoteric, you would have, like, a Twilio API key, so you could send, like, SMS messages.

00:12:27.120 --> 00:12:38.420
And now you've got, like, your billing provider and your database provider and your cloud and your user, you know, your customer relationship management API and your email service.

00:12:38.420 --> 00:12:51.960
It's just, like, there's an API key for everything, and the scale of this stuff is, like, really, if you do this sort of simple thing that all the tutorials show you to do for each of these services, you end up in a complete mess with, like, basically no security on anything.

00:12:51.960 --> 00:12:57.380
So, yeah, and that's why I wanted to talk about this at this point, because we need that security.

00:12:57.380 --> 00:12:58.820
Yeah, we definitely do.

00:12:58.820 --> 00:13:04.700
So I want to start out a little bit like you did with your talk, although not the same.

00:13:04.700 --> 00:13:10.180
I want to start out with sort of something that, you know, maybe gets people's attention that might make them worry a little.

00:13:11.460 --> 00:13:21.540
And that's this project that has been gone unmaintained and has been shut down, I think, because it was a little too much on the edge of what really you should be doing.

00:13:21.540 --> 00:13:23.400
And it's called Shugit.

00:13:23.400 --> 00:13:25.680
Shugit is a CLI thing.

00:13:25.680 --> 00:13:26.600
I'm not exactly sure.

00:13:26.600 --> 00:13:34.120
Basically, a little app you can run, a little CLI that you can run that will show you secrets in Git code, in code and Git repositories.

00:13:34.120 --> 00:13:42.360
So you can look at your own, but for a while they were running this website called, like, Shugit.com or something, like, Shugit.

00:13:42.360 --> 00:13:50.960
And it was just a live stream of just all the secrets that were being committed to public repositories just screaming by.

00:13:50.960 --> 00:13:54.100
And it's going by so fast that you really can't read it.

00:13:54.100 --> 00:13:56.300
And this is just the public.

00:13:56.980 --> 00:13:59.220
Here's all the things being uploaded.

00:13:59.220 --> 00:14:07.280
These are all these API keys, database connection strings, etc. that we've been talking about that are just, you shouldn't be doing an, oh my gosh, look at this, right?

00:14:07.280 --> 00:14:09.040
Like, this has got to grab people's attention.

00:14:09.040 --> 00:14:09.340
Right.

00:14:09.340 --> 00:14:22.420
And this isn't, it's worth noting that this feed is not people accidentally committing their secrets to the improper kind of secure place in their organization where they, like, accidentally push to a private Git repo.

00:14:22.640 --> 00:14:28.840
This is only showing you public repos with API, like, valid API keys being committed to them.

00:14:28.840 --> 00:14:35.880
So, if, you know, you can imagine within organizations, there's probably 10 times as much traffic where stuff is being shared too broadly.

00:14:35.880 --> 00:14:36.220
Oh, yeah.

00:14:36.220 --> 00:14:38.900
People at least know they shouldn't do this and they still are.

00:14:38.900 --> 00:14:42.280
Like, they might think it's okay in their private repos, right?

00:14:42.280 --> 00:14:42.940
Right, exactly.

00:14:42.940 --> 00:14:43.600
It's just easier.

00:14:43.600 --> 00:14:44.580
Yeah, yeah, yeah.

00:14:44.580 --> 00:14:53.040
This portion of Talk Python To Me is brought to you by JetBrains, who encourage you to get work done with PyCharm.

00:14:53.040 --> 00:15:00.240
PyCharm Professional is the complete IDE that supports all major Python workflows, including full stack development.

00:15:00.240 --> 00:15:06.780
That's front-end JavaScript, Python backend, and data support, as well as data science workflows with Jupyter.

00:15:06.780 --> 00:15:09.400
PyCharm just works out of the box.

00:15:09.400 --> 00:15:16.220
Some editors provide their functionality through piecemeal add-ins that you put together from a variety of sources.

00:15:16.220 --> 00:15:18.940
PyCharm is ready to go from minute one.

00:15:18.940 --> 00:15:21.660
And PyCharm thrives on complexity.

00:15:21.660 --> 00:15:28.100
The biggest selling point for me personally is that PyCharm understands the code structure of my entire project,

00:15:28.100 --> 00:15:32.400
even across languages such as Python and SQL and HTML.

00:15:32.760 --> 00:15:37.960
If you see your editor completing statements just because the word appears elsewhere in the file,

00:15:37.960 --> 00:15:42.240
but it's not actually relevant to that code block, that should make you really nervous.

00:15:42.240 --> 00:15:45.920
I've been a happy paying customer of PyCharm for years.

00:15:45.920 --> 00:15:52.160
Hardly a workday passes that I'm not deep inside PyCharm working on projects here at Talk Python.

00:15:52.160 --> 00:15:56.480
What tool is more important to your productivity than your code editor?

00:15:56.480 --> 00:15:58.760
You deserve one that works the best.

00:15:58.760 --> 00:16:07.000
So download your free trial of PyCharm Professional today at talkpython.fm/done with PyCharm and get work done.

00:16:07.000 --> 00:16:09.200
That link is in your podcast player show notes.

00:16:09.200 --> 00:16:15.440
Thank you to PyCharm from JetBrains for sponsoring the show and keeping Talk Python going strong.

00:16:18.240 --> 00:16:26.600
You also pointed out right before we hit record that GitHub has a more constructive, official way of doing this as well.

00:16:26.600 --> 00:16:29.640
You want to tell people about the GitHub secret alerts?

00:16:29.640 --> 00:16:36.700
Yeah, I don't know a whole lot about this, except that it is a feed that also produces a lot of data.

00:16:36.700 --> 00:16:39.020
But there are secret scanning alerts.

00:16:39.020 --> 00:16:42.220
And I believe it's also only for public repositories.

00:16:42.220 --> 00:16:45.820
There might be some enterprise stuff that I have not used.

00:16:45.820 --> 00:16:57.060
As it says on the page, I guess, organizations using GitHub Enterprise Cloud with a license for GitHub Advanced Security can also enable secret scanning for users on their private and internal repositories.

00:16:57.060 --> 00:17:02.620
But yeah, this is something that if you're running an open source project or you have a corporate GitHub account,

00:17:02.680 --> 00:17:12.560
you should probably look into just to understand how to manage these alerts, how to get them, and what to do if people are accidentally checking in secrets to your repository.

00:17:12.560 --> 00:17:18.020
Because you may have to worry about open source PRs, including other people's API keys.

00:17:18.020 --> 00:17:20.160
If they were testing something out with your tool.

00:17:20.160 --> 00:17:20.680
Right.

00:17:20.680 --> 00:17:23.280
That's more likely even as you might have a placeholder.

00:17:23.280 --> 00:17:24.800
Enter API key here.

00:17:24.800 --> 00:17:26.220
Don't commit it.

00:17:26.220 --> 00:17:27.820
And someone commits it in a PR, right?

00:17:27.820 --> 00:17:28.480
Something like that.

00:17:28.480 --> 00:17:28.840
Yeah.

00:17:29.060 --> 00:17:29.240
Yeah.

00:17:29.240 --> 00:17:30.000
So don't do that.

00:17:30.000 --> 00:17:33.640
Don't put a place to paste something in a file that's actually checked into Git.

00:17:33.640 --> 00:17:38.000
But I think that it's also important not to shame people too much for doing this.

00:17:38.000 --> 00:17:45.060
One of the points of showcasing these tools is to say, hey, people are leaking secrets constantly.

00:17:45.060 --> 00:17:46.640
You should be aware of it.

00:17:46.640 --> 00:17:47.320
It's a serious problem.

00:17:47.320 --> 00:17:49.720
The other is people are doing this constantly.

00:17:49.720 --> 00:17:52.020
It's a really easy kind of mistake to make.

00:17:52.260 --> 00:17:58.200
And so if you do it, or if some junior engineer on your team pushes some secrets to GitHub, don't shame them.

00:17:58.200 --> 00:17:59.580
It's not a dumb thing to do.

00:17:59.580 --> 00:18:01.800
It's incredibly easy to screw up in this way.

00:18:01.800 --> 00:18:04.940
And we should help each other build better processes.

00:18:04.940 --> 00:18:09.460
So don't feel like it's a thing to mock or laugh at.

00:18:09.660 --> 00:18:16.140
So you're not suggesting that GitHub adopts a new kind of badge, like a secret teller badge or something, if you're caught doing this?

00:18:16.140 --> 00:18:18.920
I think let's not gamify that in either direction.

00:18:18.920 --> 00:18:22.600
It's a hard enough conversation already.

00:18:22.600 --> 00:18:23.240
It is.

00:18:23.240 --> 00:18:25.700
Well, and it can happen even if you know you shouldn't.

00:18:25.700 --> 00:18:32.820
Maybe you understand the security, but you're not good with Git, and you accidentally overcommit stuff.

00:18:32.820 --> 00:18:33.720
And you're like, oh, whoops.

00:18:34.160 --> 00:18:36.480
Yep, that's a very common way that it can happen.

00:18:36.480 --> 00:18:44.200
And even if you are very familiar with Git, and you know not to do this, and all of the projects that you've set up are set up properly,

00:18:44.200 --> 00:18:49.100
you might find yourself in an unfamiliar repository, assuming that something is Git ignored, and it's not.

00:18:49.100 --> 00:18:50.820
There's lots of different ways that it can happen.

00:18:50.820 --> 00:18:51.220
Yeah.

00:18:51.220 --> 00:19:00.820
So I guess if you're running an open source project, it's probably worth turning on, or at least looking into the secret scanning that GitHub has, if it's on GitHub, right?

00:19:00.820 --> 00:19:00.980
Yeah.

00:19:01.320 --> 00:19:06.660
And if you want to startle yourself, just check out the link, the animated GIF in the Shiget repository.

00:19:06.660 --> 00:19:07.880
All right.

00:19:07.880 --> 00:19:23.820
So as we start our conversation about the different secrets, the pitfalls, and how we might keep them, you told, this was a really creative presentation at PyCon, and you presented it through by way, mostly by way of storytelling.

00:19:23.820 --> 00:19:25.080
Well, thank you for saying so.

00:19:25.080 --> 00:19:25.880
Yes, of course.

00:19:25.880 --> 00:19:27.160
Was it Gerald who was your?

00:19:27.160 --> 00:19:28.100
Jethro.

00:19:28.100 --> 00:19:28.700
Jethro.

00:19:28.700 --> 00:19:30.140
Jethro is the protagonist.

00:19:30.140 --> 00:19:31.220
Yes, got it.

00:19:31.220 --> 00:19:38.080
So there's this practice in security engineering, which I'm sure a lot of your listeners would have heard of, which is called threat modeling.

00:19:38.080 --> 00:19:46.320
And threat modeling can be a bit dry, because it's really just repeating kind of these same scenarios over and over and over again, with slight things changed.

00:19:46.440 --> 00:19:52.920
And so I thought a good way to frame that would be like a time loop story, where our protagonist is kind of running this service.

00:19:52.920 --> 00:20:00.120
And every time through the time loop, his service gets pwned and taken down via some kind of compromise of secrets.

00:20:00.360 --> 00:20:04.480
And he wakes up and he wakes up and has to do it all again and try to secure things properly.

00:20:04.480 --> 00:20:06.180
Yes, indeed.

00:20:06.180 --> 00:20:08.020
That's where we get started.

00:20:08.340 --> 00:20:09.240
Yeah, for sure.

00:20:09.240 --> 00:20:09.600
Yeah.

00:20:09.600 --> 00:20:12.980
And one of the things I also kind of called out is like, I should mention this here, too.

00:20:12.980 --> 00:20:16.220
It could be a little bit stressful listening to all these different things.

00:20:16.220 --> 00:20:20.740
So this isn't exactly like a content warning, like a really serious, heavy stuff.

00:20:20.740 --> 00:20:31.140
But be aware that even if it sounds kind of light and fun and informative, if you find yourself ideating on these same ideas of like, oh, no, this could go wrong, this could go wrong, this could go wrong.

00:20:31.140 --> 00:20:33.660
That is kind of just what security engineering is like.

00:20:33.660 --> 00:20:35.860
But also, it can kind of drive you crazy.

00:20:36.160 --> 00:20:39.060
So like, don't let yourself get trapped in cycles of anxiety.

00:20:39.060 --> 00:20:46.220
Just be aware that, you know, you kind of have to do your best and like make a reasonable effort, but you're never going to get everything perfect.

00:20:46.220 --> 00:20:51.100
So and in fact, I'll spoil the story a little bit since we're not quite going through it in order here.

00:20:51.540 --> 00:21:09.000
That's really the twist at the end of the talk is that Jethro needs to like just put forward a good effort across the board for managing his secrets and not, you know, absolutely perfectly defend against every attack, but also not to defend against each attack piecemeal, kind of onesie twosie, just like, oh, I'll address this thing.

00:21:09.000 --> 00:21:09.980
And then I'll address that thing.

00:21:09.980 --> 00:21:11.080
And then I'll address that thing.

00:21:11.080 --> 00:21:13.880
It's like, think about your whole process.

00:21:13.880 --> 00:21:15.260
So, yeah.

00:21:15.260 --> 00:21:19.600
So I guess we should dive into what those actual specific attacks are.

00:21:19.600 --> 00:21:29.060
Before we do that, one thing that I thought was really nice that you pointed out is, at least for me, when I feel like I'm putting a website up there, I feel like, oh, my goodness.

00:21:29.060 --> 00:21:31.700
Have I what have I forgotten?

00:21:31.700 --> 00:21:32.260
Right.

00:21:32.260 --> 00:21:36.180
But there's you point out that there's a lot of people on your side.

00:21:36.180 --> 00:21:36.780
Right.

00:21:36.780 --> 00:21:40.920
There's operating system vendors, the open source maintainers.

00:21:40.920 --> 00:21:42.880
You want to riff on that a bit?

00:21:42.880 --> 00:21:54.020
This is also important to remember because so, for example, just to like some one attack that's been in the news a lot lately is typosquatting and software supply chain attacks.

00:21:54.020 --> 00:21:54.220
Right.

00:21:54.220 --> 00:22:00.680
Like somebody uploading something malicious to PyPI, somebody uploading, you know, pad NAS instead of pandas.

00:22:00.680 --> 00:22:06.880
And you fat finger the name in pip and then, oh, no, you're like running code from some attacker.

00:22:06.880 --> 00:22:08.200
And that is a threat.

00:22:08.200 --> 00:22:10.040
And, you know, you should be concerned about it.

00:22:10.040 --> 00:22:11.820
You should mitigate it in your code.

00:22:11.820 --> 00:22:15.240
All of the different ways to do that are like a little bit out of scope for this discussion.

00:22:15.240 --> 00:22:27.880
But also it's important to remember that a lot of these attacks are things that it's hard to demonstrate in like a quick, like circa 2007 type sniffing your Facebook password off the wire.

00:22:27.880 --> 00:22:31.420
Like, hey, look at this like immediate attack where I've got all of your stuff.

00:22:31.420 --> 00:22:39.180
And they're difficult to demonstrate because PyPI is actively scanning for these types of packages.

00:22:39.180 --> 00:22:41.180
They're actively responding to reports.

00:22:41.180 --> 00:22:42.040
There are lots of people.

00:22:42.040 --> 00:22:51.340
There are lots of security researchers developing tools, some of them kind of over aggressively running them against the index to taking up a little too much, too many resources.

00:22:51.340 --> 00:22:56.480
But there are lots of people doing things to defend you against each one of these attacks.

00:22:56.480 --> 00:23:00.280
And so the simplistic version of them will rarely work out of the box.

00:23:00.280 --> 00:23:04.000
The threat from typosquatting is a race condition.

00:23:04.000 --> 00:23:10.900
It's that somebody uploads a malicious package that doesn't look malicious enough to get automatically caught in these various ways.

00:23:11.060 --> 00:23:13.200
That doesn't get immediately flagged.

00:23:13.200 --> 00:23:16.980
It's not popular enough to like be installed on a lot of people's machines.

00:23:17.160 --> 00:23:23.860
And that you happen to do the typo in the window where it's still up before the admins have taken it down.

00:23:23.860 --> 00:23:29.460
That is a real threat, but it is not as serious as like, oh, it's just a free for all.

00:23:29.460 --> 00:23:30.780
Anybody can upload anything anywhere.

00:23:30.780 --> 00:23:32.000
Like there's a lot of security.

00:23:32.000 --> 00:23:41.720
There's the, not just the PyPI admins, but the distributors of all of the libraries on PyPI that you use are developing better processes on the teams that do uploading.

00:23:41.920 --> 00:23:43.340
PyPI now has orgs.

00:23:43.340 --> 00:23:50.920
And so we're doing like projects are starting to gather into organizations to apply more consistent security rules for uploading across the board.

00:23:50.920 --> 00:23:52.920
So there's lots of work that's going on.

00:23:52.920 --> 00:24:01.220
I happen to know a lot about PyPI, but your operating system vendor also is like, yeah, you could run some malware and that would really ruin your day.

00:24:01.220 --> 00:24:08.140
But Apple, Microsoft, Google, Red Hat, none of them want their operating system to be implicated in the attack.

00:24:08.140 --> 00:24:17.820
So they're constantly hardening their applications, hardening their APIs, developing secure APIs that developers can use to prevent certain attacks.

00:24:17.820 --> 00:24:25.980
Different platforms are kind of at different stages of maturity there and have kind of different security features, but they're all trying their best to prevent the worst case from happening.

00:24:26.160 --> 00:24:28.160
And so you're not like alone in this fight.

00:24:28.160 --> 00:24:36.700
You need to model your own threats and use the tools that you've been provided in ways that are kind of helpful, but you don't have to do everything yourself.

00:24:36.700 --> 00:24:41.100
You don't have to worry that you're kind of besieged with, and you're the only defender, right?

00:24:41.300 --> 00:24:47.180
You're actually in a pretty big crowd of defenders, and we all got to share knowledge with each other to try to help each other out.

00:24:47.180 --> 00:24:47.720
That's interesting.

00:24:47.720 --> 00:24:54.780
You know, we are, you know, there's a big concern about supply chain attacks and, you know, open source building blocks.

00:24:54.780 --> 00:24:59.380
But it is a bit of a herd immunity type of thing, right?

00:24:59.380 --> 00:24:59.740
Yeah.

00:24:59.820 --> 00:25:07.060
If something comes in pretty soon, if it at all starts to gain any popularity, people are going to notice, and it'll get beat down.

00:25:07.060 --> 00:25:13.840
So it's scary, but it's maybe not as likely to broadly affect the ecosystem.

00:25:13.840 --> 00:25:14.320
Right.

00:25:14.320 --> 00:25:21.560
And that doesn't mean that you can give up on this work or put it off as some kind of gold plating that you're going to do later.

00:25:21.560 --> 00:25:25.800
But it does mean that you can kind of moderate the amount of energy that you put in.

00:25:25.800 --> 00:25:35.660
And the way that you should think about it as an individual, as an app developer, is like, you should be trying to figure out what your responsibility is and handle your part of the responsibility.

00:25:35.660 --> 00:25:43.580
Don't try to, like, you know, think about every threat and become a vulnerability researcher in order to secure your application.

00:25:43.780 --> 00:25:45.760
Like, let those people, there's a lot of people doing that stuff.

00:25:45.760 --> 00:25:48.900
Let them do their job and just kind of figure out, okay, what do you need to do?

00:25:48.900 --> 00:25:57.840
Because obviously, no matter how great the defenses are, if you don't use them, if you're not properly secure in your own processes, then it doesn't matter.

00:25:57.840 --> 00:26:05.480
Like, you can easily, if you're pushing your, you know, root cloud keys to GitHub in a public repo, all of the security of the world is not going to help you.

00:26:05.480 --> 00:26:07.060
Yeah, it's not going to be great.

00:26:07.060 --> 00:26:11.340
You said there's even a PEP to help solve this, PEP 541.

00:26:11.340 --> 00:26:12.460
What is PEP 541?

00:26:12.780 --> 00:26:16.200
541 is actually a little bit broader than just, like, typo squatting.

00:26:16.200 --> 00:26:22.500
It's about how PyPI, like, retains names, how they deal with trademark dispute resolution.

00:26:22.500 --> 00:26:27.580
You know, it outlines some of the responsibilities of package maintainers.

00:26:27.820 --> 00:26:43.360
So, for example, like, one of the typo squatting or one of the attacks against supply chains is if you use a vanity domain name for your PyPI account, and then you let the domain name lapse, and then somebody, like, registers the domain name, now they have access to your account because they can do a password reset.

00:26:43.440 --> 00:26:49.300
And so there are various responsibilities that you have, like, you have to be reachable.

00:26:49.300 --> 00:26:52.760
If your project has been abandoned, the index might take it away, right?

00:26:52.760 --> 00:26:53.960
Like, they might shut it down.

00:26:53.960 --> 00:26:55.000
They might freeze it.

00:26:55.280 --> 00:27:00.600
And there are this PEP kind of lays out a bunch of processes for various things.

00:27:00.600 --> 00:27:07.860
And one of them is, you know, how things get taken down, how projects become invalid, what a typo squat is.

00:27:08.500 --> 00:27:15.540
And so it's an even broader project than just the security of typo squatting or even broader than supply chain security.

00:27:15.540 --> 00:27:18.180
It's, like, the whole supply chain shebang.

00:27:18.180 --> 00:27:21.980
And there will probably be more PEPs in this area in the future, I think.

00:27:21.980 --> 00:27:23.120
Yeah, I would imagine.

00:27:23.120 --> 00:27:34.400
Yeah, so, for example, if I had Michael.com and I registered, my account was Michael or me at Michael.com, and then I didn't, that went away.

00:27:34.400 --> 00:27:43.280
Someone else could buy Michael.com for who knows how much and then do a password reset, and they control all of my super important open source projects on there.

00:27:43.280 --> 00:27:46.280
Yeah, and then they can immediately do uploads, which is kind of a problem.

00:27:46.280 --> 00:27:46.520
Right.

00:27:46.520 --> 00:27:48.440
That might not be awesome.

00:27:48.440 --> 00:27:51.200
Okay, so that's PEP 541.

00:27:51.200 --> 00:27:51.760
Got it.

00:27:51.760 --> 00:27:53.500
So it was all about threat modeling, right?

00:27:53.500 --> 00:27:58.780
And you basically come through and you say, okay, well, first we're going to write some code, and then let's just push it to the cloud.

00:27:58.780 --> 00:28:01.920
And to the cloud, it says.

00:28:01.920 --> 00:28:02.880
Yeah.

00:28:02.880 --> 00:28:03.560
Uh-oh.

00:28:04.080 --> 00:28:06.700
You can't run your website, right?

00:28:06.700 --> 00:28:11.840
So the first thing you got to talk about when you talk about secrets is human-generated secrets.

00:28:11.840 --> 00:28:18.960
The ones, like your passwords that you actually have to remember and type in with your fingers, don't ever share those.

00:28:18.960 --> 00:28:27.700
If you're sharing passwords between accounts, if you've got like a LinkedIn account that has been around for a decade, that's probably been in a breach.

00:28:27.700 --> 00:28:29.320
Even if it hasn't been in a breach.

00:28:29.320 --> 00:28:35.060
Oh, for those who are not on the live stream, Michael is now typing, have I been pwned?

00:28:35.060 --> 00:28:41.380
Which is a great tool that you can use to see if your passwords have been in a previous breach.

00:28:41.860 --> 00:28:43.480
And spoiler alert, yes, they have.

00:28:43.480 --> 00:28:51.500
So the first lesson is like you should be using a password manager because that's the kind of absolute root of your security.

00:28:51.500 --> 00:28:55.820
You have your kind of vault password for your password manager.

00:28:56.120 --> 00:28:58.600
You need to be able to remember that.

00:28:58.600 --> 00:29:00.180
You need to generate that securely.

00:29:00.180 --> 00:29:07.440
And then you should let your password manager actually generate all of the passwords for all of the different sites and apps that you use.

00:29:07.440 --> 00:29:09.640
Because you don't want to be sharing those between them.

00:29:09.640 --> 00:29:17.220
Because inevitably, if you share a password between 10 sites, one of them will get breached, like for sure.

00:29:17.220 --> 00:29:26.580
And then all of the others can be breached later by anybody who can buy that data dump on the dark web or now access that information.

00:29:26.580 --> 00:29:37.520
So I actually wrote like one of the tools that I released during this talk at PyCon is called PinPal, which is kind of to help people adopt a password manager.

00:29:37.520 --> 00:29:46.540
One of the challenging things about adopting a password manager, especially if you haven't got one already, is you really need to generate like a long, secure password.

00:29:46.540 --> 00:29:48.340
And you have to memorize it.

00:29:48.340 --> 00:29:51.020
And you really can't forget that.

00:29:51.020 --> 00:29:53.260
And this is something that happened to Jethro.

00:29:53.800 --> 00:30:03.220
You have to think about not just confidentiality, but there's this thing called the CIA triad where you've got confidentiality, integrity, and availability of your service.

00:30:03.220 --> 00:30:09.380
And if you get hacked and people steal your secrets, then they can access your cloud and it's game over.

00:30:09.380 --> 00:30:15.060
But if you forget all of your passwords and you can't access your cloud, it's just as equally game over.

00:30:15.060 --> 00:30:17.560
So you have to like do that memorization.

00:30:17.560 --> 00:30:21.900
You should ideally also change your root password once every couple of years.

00:30:21.900 --> 00:30:29.500
You shouldn't change it too frequently, like policies that make you rotate every 90 days or whatever are just a kind of relic of a bygone time and not a very good idea.

00:30:29.500 --> 00:30:31.900
But you shouldn't keep it forever.

00:30:31.900 --> 00:30:35.820
And that process can be difficult because you need to memorize it.

00:30:35.820 --> 00:30:40.660
And because password managers try to be convenient, they're not prompting you for it all the time.

00:30:40.660 --> 00:30:48.180
So PinPal is this thing that kind of like sets up a spaced repetition process where it's like gradually generating the password over time.

00:30:48.580 --> 00:30:53.400
It just kind of prompts you over and over for like, here's the first word.

00:30:53.400 --> 00:30:54.160
It generates it.

00:30:54.160 --> 00:30:55.860
It asks you to kind of read it back to it.

00:30:55.860 --> 00:31:01.540
It's a little console tool that you like put in your prompt to see if it's time to do a memorization pass.

00:31:01.540 --> 00:31:05.600
But you can use PinPal, memorize the password before you get the password manager.

00:31:05.600 --> 00:31:07.540
Make sure you've got it thoroughly memorized.

00:31:08.180 --> 00:31:13.620
And then you don't have to worry so much about like, oh, where was that little piece of paper that I put in my wallet that has the password in it?

00:31:13.620 --> 00:31:16.880
Because like it's been a week and now I have to enter my master password again.

00:31:16.880 --> 00:31:23.100
PinPal can kind of get that part of the inconvenience of adopting a password manager in the first place out of the way.

00:31:23.100 --> 00:31:26.240
And so I've made it as easy as I possibly can for you.

00:31:26.320 --> 00:31:28.600
I know that that's the one thing that like gets people stuck.

00:31:28.600 --> 00:31:30.160
And so now you have no excuse.

00:31:30.160 --> 00:31:31.680
You got to get a password manager right now.

00:31:31.680 --> 00:31:34.820
I absolutely, totally recommend a password manager.

00:31:34.820 --> 00:31:39.140
And I personally use one password, but I'm also a big fan of Bitwarden.

00:31:39.140 --> 00:31:41.540
You know, props to the open source side of Bitwarden.

00:31:41.540 --> 00:31:42.180
That's pretty cool.

00:31:42.180 --> 00:31:47.640
And the pricing for the pro version is like a couple dollars a year or something ridiculously small.

00:31:48.100 --> 00:31:49.940
So it's, they're good options.

00:31:49.940 --> 00:31:52.060
Yeah, Dashlane is also pretty good.

00:31:52.060 --> 00:31:56.340
Full disclosure, that was actually started by my cousin in France, oddly enough.

00:31:56.340 --> 00:31:56.620
No kidding.

00:31:56.620 --> 00:31:59.760
Yeah, it's a little weird aside there.

00:31:59.760 --> 00:32:01.320
I don't believe he works there anymore.

00:32:01.320 --> 00:32:02.820
So those options are all good.

00:32:02.820 --> 00:32:05.020
I would avoid LastPass.

00:32:05.020 --> 00:32:07.740
If you've been using LastPass, that's fine.

00:32:07.740 --> 00:32:12.740
It's still way better that like, again, it can be easy to catastrophize security.

00:32:12.740 --> 00:32:17.940
Like LastPass had a bunch of breaches and the breaches were like worse than they said.

00:32:18.020 --> 00:32:23.600
And their security, like they used a lower iterations on their key derivation function than they should have.

00:32:23.600 --> 00:32:25.540
And so there's all these issues with LastPass.

00:32:25.540 --> 00:32:34.620
But like, if you had been using LastPass when they got breached, you're still in way better shape than if you had been trying to like memorize.

00:32:34.620 --> 00:32:36.520
Just reusing your passwords.

00:32:36.520 --> 00:32:36.860
Yeah.

00:32:36.860 --> 00:32:37.560
Yeah.

00:32:37.560 --> 00:32:45.140
One of the big, I think, big no-nos of LastPass, other than also the low iteration, the folding account,

00:32:45.940 --> 00:32:49.220
was that a lot of stuff is stored in plain text.

00:32:49.220 --> 00:32:54.220
So like the URL of the place for which the password goes to is stored in plain text.

00:32:54.220 --> 00:33:00.360
So that the hackers could go through the dump and go, okay, well, just show me all the Bank of America ones.

00:33:00.360 --> 00:33:01.740
Let's just work on that for a while.

00:33:01.740 --> 00:33:02.100
Right?

00:33:02.100 --> 00:33:03.280
Yeah.

00:33:03.280 --> 00:33:07.520
They definitely had an architecture that was like bad for no reason.

00:33:07.520 --> 00:33:09.900
Like there's no reason that they should, that stuff all should be.

00:33:09.900 --> 00:33:10.740
I totally agree.

00:33:10.900 --> 00:33:15.300
So yeah, people can choose LastPass if they want, but there's Bitward and 1Password.

00:33:15.300 --> 00:33:17.620
That's where my heart loves it.

00:33:19.620 --> 00:33:23.240
This portion of Talk Python To Me is sponsored by the Compiler podcast from Red Hat.

00:33:23.240 --> 00:33:29.580
Just like you, I'm a big fan of podcasts, and I'm happy to share a new one from a highly respected open source company.

00:33:29.580 --> 00:33:32.520
Compiler, an original podcast from Red Hat.

00:33:32.520 --> 00:33:35.960
Do you want to stay on top of tech without dedicating tons of time to it?

00:33:35.960 --> 00:33:41.660
Compiler presents perspectives, topics, and insights from the tech industry, free from jargon and judgment.

00:33:41.660 --> 00:33:48.320
They want to discover where technology is headed beyond the headlines and create a place for new IT professionals to learn, grow, and thrive.

00:33:48.620 --> 00:33:54.640
Compiler helps people break through the barriers and challenges turning code into community at all levels of the enterprise.

00:33:54.640 --> 00:33:59.000
One recent and interesting episode is there, The Great Stack Debate.

00:33:59.000 --> 00:34:07.500
I love, love, love talking to people about how they architect their code, the trade-offs and conventions they chose, and the costs, challenges, and smiles that result.

00:34:07.500 --> 00:34:10.580
This Great Stack Debate episode is like that.

00:34:10.580 --> 00:34:16.600
Check it out and see if software is more like an onion, or more like lasagna, or maybe even more complicated than that.

00:34:17.000 --> 00:34:20.340
It's the first episode in Compiler's series on software stacks.

00:34:20.340 --> 00:34:24.420
Learn more about Compiler at talkpython.fm/compiler.

00:34:24.420 --> 00:34:26.760
The link is in your podcast player show notes.

00:34:26.760 --> 00:34:34.840
And yes, you could just go search for Compiler and subscribe to it, but follow that link and click on your player's icon to add it.

00:34:34.840 --> 00:34:36.460
That way they know you came from us.

00:34:36.940 --> 00:34:41.160
Our thanks to the Compiler podcast for keeping this podcast going strong.

00:34:43.020 --> 00:34:45.280
I did have one of Have I Been Pwned up.

00:34:45.280 --> 00:34:48.980
And I would just like to point out, the question is, have I possibly, right?

00:34:48.980 --> 00:34:52.660
I can tell you, it has a list of most recent breaches.

00:34:52.660 --> 00:34:56.660
This Luxottica one here was 77 million.

00:34:56.660 --> 00:34:58.760
I just got a notification that I was in that one.

00:34:58.760 --> 00:35:00.900
That's like literally the most recent one.

00:35:01.460 --> 00:35:05.420
And here's what drives me nuts about these things, this bit of a sidebar.

00:35:05.420 --> 00:35:11.620
So nothing you can do about it, but it's maybe about the, you give it your best shot and you can just only do so much, Cliff.

00:35:11.840 --> 00:35:18.160
And I am in this, I'm in this breach because I went to my eye doctor and my health provider.

00:35:18.160 --> 00:35:23.760
They subcontracted to Luxottica to get my glasses created.

00:35:23.760 --> 00:35:30.640
Luxottica was hacked and therefore my information, I'd never even heard of this company or interacted with them.

00:35:30.640 --> 00:35:32.060
And yet here we are, right?

00:35:32.060 --> 00:35:35.140
And so, you know, do your best, but don't go crazy.

00:35:35.140 --> 00:35:35.560
Yep.

00:35:35.560 --> 00:35:36.500
Okay.

00:35:36.500 --> 00:35:38.960
So I guess you have more control over, right?

00:35:39.220 --> 00:35:48.040
But I guess one of your very first recommendations was use a pass manager, use something like PenPal to help not forget your password to your password.

00:35:48.040 --> 00:35:54.260
And sort of the lesson is the CIA triad, like availability is also important, not just the other two security bits.

00:35:54.260 --> 00:35:56.820
But if you can't get to it anymore, that's still a problem.

00:35:56.820 --> 00:35:57.180
Yep.

00:35:57.180 --> 00:35:58.940
Don't be your own worst attacker.

00:35:58.940 --> 00:36:00.920
Exactly.

00:36:00.920 --> 00:36:01.740
So, yeah.

00:36:01.740 --> 00:36:07.920
And I guess that one of the other major things I wanted to talk about here, part of the story is that the documentation.

00:36:07.920 --> 00:36:13.540
So Jethro follows the docs on a lot of different things that he's looking at.

00:36:13.540 --> 00:36:23.100
And a lot of those docs, and this is kind of the inspiration for the talk in the first place, was that many, many APIs are documented by saying, here's some code.

00:36:23.100 --> 00:36:26.520
And here's where you paste the string of your API key.

00:36:26.520 --> 00:36:28.620
And big companies do this.

00:36:28.620 --> 00:36:30.000
Stripe does this.

00:36:30.000 --> 00:36:31.040
DigitalOcean does this.

00:36:31.160 --> 00:36:34.360
It's not an unusual thing.

00:36:34.360 --> 00:36:38.080
It's not a thing that only kind of low security, uninteresting APIs do.

00:36:38.080 --> 00:36:46.580
The idea is they're writing the docs, assuming that you kind of have some secret management strategy to begin with, that you know your API token is really sensitive.

00:36:46.580 --> 00:36:49.580
So obviously you won't follow their example directly.

00:36:49.580 --> 00:36:59.140
But like, as seen from the GitHub stream of, you know, constant secrets being pushed to public repos, a lot of people don't know that.

00:36:59.140 --> 00:37:01.180
And there shouldn't be any shame in not knowing that.

00:37:01.260 --> 00:37:05.600
Like, if the docs say, put this string here, and you're like, okay, I'm going to put that string there.

00:37:05.600 --> 00:37:16.000
There's no way that you could have, like, somehow known in advance, if you're a novice coder, that, oh, if you put that string there, like they said, then all of your, you know, money will be stolen.

00:37:16.000 --> 00:37:20.060
And your servers, attackers boot thousands of servers to mine cryptocurrency.

00:37:20.960 --> 00:37:31.740
So one of the things that the calls to action here is if you're maintaining those docs, if you're leading people down that path, please at least mention that this token is extremely sensitive.

00:37:31.740 --> 00:37:38.040
At least explain that people should be looking somewhere else for documentation of what to do.

00:37:38.040 --> 00:37:42.420
And like in Python, it's actually quite easy to know what to do.

00:37:42.420 --> 00:37:46.680
It's use key ring, like exactly how you configure key ring and what you do with it.

00:37:46.680 --> 00:37:48.240
We can talk about in a minute or two.

00:37:48.720 --> 00:38:00.180
But from the perspective of like an application loading something, from the example, from the perspective of like a code example that you want to put on a website, just never tell users to put a string directly in the code.

00:38:00.180 --> 00:38:05.020
The string in your code is obviously never the user's like actual API key.

00:38:05.020 --> 00:38:06.580
They're going to have to edit it anyway.

00:38:06.580 --> 00:38:10.980
So in the example code, just import key ring into a key ring.get password.

00:38:10.980 --> 00:38:14.840
And they can replace that with their key as easily as they can replace a string.

00:38:15.040 --> 00:38:21.100
But at least you're calling out there, oh, hey, this is like a piece of data that has to be managed in a particular way.

00:38:21.100 --> 00:38:26.720
Here's how you manage it in Python is you call the key ring get password API.

00:38:26.720 --> 00:38:29.900
So the key ring module is like very simple.

00:38:29.900 --> 00:38:33.300
It's basically just a wrapper around a function that returns a string.

00:38:33.300 --> 00:38:46.200
But by centralizing that function, all of the myriad nuances of what exactly, like how exactly to get that string, how is it encrypted, where is it stored, whatever, can be kind of pushed out of the application.

00:38:46.540 --> 00:38:48.600
Yeah, so let's talk about key ring a little bit.

00:38:48.600 --> 00:38:51.320
It's a Python library that you can use.

00:38:51.320 --> 00:38:55.960
And you can say, basically, save a secret or get a secret.

00:38:55.960 --> 00:38:57.060
It calls it a password.

00:38:57.060 --> 00:39:02.000
I kind of would like it to not be password, because what if it's an API token for that?

00:39:02.000 --> 00:39:02.660
I don't know.

00:39:02.660 --> 00:39:04.680
It seems a little, what if it's a connection string?

00:39:04.680 --> 00:39:05.380
I don't know.

00:39:05.540 --> 00:39:11.540
Yeah, it's a little bit like, it was definitely written quickly and saw just a crazy amount of adoption.

00:39:11.540 --> 00:39:13.680
And, you know, we're kind of just stuck with that naming now.

00:39:13.680 --> 00:39:17.100
I agree that it's not the best, but it's, you know, it's fine.

00:39:17.100 --> 00:39:22.280
Any secret token that you treat this way is kind of functionally a password.

00:39:22.280 --> 00:39:25.480
So the terminology is a little confusing, but it's fine.

00:39:25.480 --> 00:39:34.260
Yeah, so regardless of whether it's an API key or a password or a connection string, you can say keyring.setpassword or keyring.getpassword.

00:39:34.360 --> 00:39:36.480
And that's pretty much the API, right?

00:39:36.480 --> 00:39:40.440
Yeah, and the nice thing about it is that there can be a lot of complexity in how it's configured.

00:39:40.440 --> 00:39:48.460
But the default, if you just like pip install keyring and you start using it on a desktop machine, Windows, Linux, macOS, doesn't matter.

00:39:48.460 --> 00:39:58.100
It, by default, will use your platform's default secret store, which is kind of the best that you can do without any additional configuration.

00:39:59.140 --> 00:40:04.900
And ironically enough, for the talk, I really wanted to talk about, like, how this works on every platform.

00:40:04.900 --> 00:40:08.400
I kind of figured that every platform was, like, equivalently secure.

00:40:08.820 --> 00:40:13.120
I kind of hate being a shill for a, you know, trillion dollar corporation.

00:40:13.120 --> 00:40:24.220
But, like, Apple does this so much better than either of the other major desktop platforms because on the Mac you've got, like, intra-user security boundaries.

00:40:24.220 --> 00:40:29.640
So, like, your, there's, apps are generally sandboxed on the Mac if they come from the App Store or if they've opted in.

00:40:30.180 --> 00:40:33.520
Even if they're not sandboxed, there's a lot of things that they can't do.

00:40:33.520 --> 00:40:45.280
Like, if you, you may have noticed if you use a Mac, if you try to, like, run a Python program on, like, a file on your desktop or in your documents folder, it'll, like, pop up a dialogue and say, like, hey, this program's trying to access this thing.

00:40:45.280 --> 00:40:56.600
Secrets are something like that where when an app tries to access a secret, you have to not just say yes, but you have to, like, enter your account, your login password again.

00:40:56.740 --> 00:40:59.740
And you can choose to either allow it temporarily or permanently.

00:40:59.740 --> 00:41:08.240
And you can then go in and configure it to say, like, oh, this, like, I know I said that I, this app could access its own secrets, but, like, actually, I want to be prompted every time.

00:41:08.240 --> 00:41:19.560
So, like, for example, my PyPI keys, if I use Twine or Flit to upload a package to PyPI, I always get a password prompt because my PyPI token is not stored anywhere on my file system.

00:41:19.560 --> 00:41:23.400
The key that's stored in my Mac keyring is, like, locked.

00:41:23.400 --> 00:41:26.120
It's not allowed to be automatically accessed by anything.

00:41:26.120 --> 00:41:26.400
Right.

00:41:26.400 --> 00:41:31.240
And that adds a little bit of friction, but for something like PyPI package uploads, like, you want to have that friction there.

00:41:31.240 --> 00:41:33.300
You don't, it's not very frequently used.

00:41:33.300 --> 00:41:39.000
Now, on Windows and Linux, you still get, like, some protection against offline attacks.

00:41:39.000 --> 00:41:40.840
You get protection against other users.

00:41:40.840 --> 00:41:51.920
Like, if you share a computer or you're on a Windows, like, you know, a corporate laptop where things are executed under, like, administrative tasks are executed by your company under different users.

00:41:52.560 --> 00:41:54.060
It'll be protected from that.

00:41:54.060 --> 00:41:55.760
It'll be protected when you're not locked in.

00:41:55.760 --> 00:42:00.300
And on Linux, oddly enough, you can lock your credential locker, but, like, only the whole thing.

00:42:00.300 --> 00:42:05.300
And then anytime any app needs to do anything, it's like, hey, do you want to unlock this again?

00:42:05.300 --> 00:42:10.160
And so, like, your mail client will be checking your mail, and it'll constantly be saying, like, hey, do you want to unlock this?

00:42:10.160 --> 00:42:19.480
But nevertheless, it is still locked in a way that, like, if you step away from your computer, if the screensaver is on, I think it will generally kind of lock it for you.

00:42:19.480 --> 00:42:27.040
So it provides as much protection as it can, given the way the platform works, without any additional inconvenience.

00:42:27.040 --> 00:42:33.420
Like, if you use Keyring and you just kind of use it in the default mode, you get a bunch of extra security, and it's all for free.

00:42:33.420 --> 00:42:34.880
Like, you don't have to think about it.

00:42:34.880 --> 00:42:36.320
It'll just work.

00:42:36.320 --> 00:42:42.320
I'm pretty comfortable just putting true secrets into macOS Keychain, for example.

00:42:42.320 --> 00:42:47.140
I feel like that's a pretty safe, probably better than a source file, a text file.

00:42:47.140 --> 00:42:49.080
Yes, it's definitely better than a text file.

00:42:49.080 --> 00:42:50.100
And it's better than a text.

00:42:50.100 --> 00:42:52.960
I mean, it's way better than a text file in your Git repo.

00:42:52.960 --> 00:42:57.800
It's still much better than a text file, like, in your home directory.

00:42:57.800 --> 00:43:09.300
Like, a lot of the less irresponsible code documentation tends to tell you to, like, put your keys into, like, dot this app dot CFG in your home directory or something.

00:43:09.300 --> 00:43:12.240
And that's, like, kind of okay.

00:43:12.460 --> 00:43:20.420
Like, any software that can steal stuff out of your home directory has probably already, you know, got a lot of control over your computer.

00:43:21.180 --> 00:43:25.220
But it's still better to put it in Keyring if you can.

00:43:25.220 --> 00:43:25.620
Right.

00:43:25.680 --> 00:43:32.200
Well, my assumption about most malware type of things is it's going to be 100% automated.

00:43:32.400 --> 00:43:33.900
I imagine there's very few.

00:43:34.120 --> 00:43:37.820
I'm just going to remotely log into each computer and go hunting for secrets.

00:43:37.820 --> 00:43:40.580
More like it's going to look for well-known things.

00:43:40.580 --> 00:43:47.280
Much like if you tail the log of your website, you're going to see some things trying to access slash WP admin dot PHP.

00:43:47.520 --> 00:43:54.360
Even if it's not a PHP site, like, they just got the things they look for and they're going to go through their processes to gather secrets and access.

00:43:54.360 --> 00:43:59.900
And I guess the less standard, the less obvious it is to get a hold of it, probably the better.

00:43:59.900 --> 00:44:07.280
It's easy to kind of trick yourself into thinking, like, oh, I should just put everything in, like, really weird locations and, like, the automation won't find it.

00:44:07.280 --> 00:44:13.360
Quite often the automation, like, does kind of scrape through every file it can get access to because it doesn't cost them anything.

00:44:13.360 --> 00:44:14.700
They can just, like, read every file.

00:44:14.700 --> 00:44:15.440
It's your processor.

00:44:15.440 --> 00:44:16.260
It's your processing.

00:44:16.260 --> 00:44:19.980
Maybe just run shigit on every git repo I can find on your computer.

00:44:19.980 --> 00:44:21.540
Right.

00:44:21.540 --> 00:44:25.980
So it's better to kind of, like, put all your eggs in one basket and really watch that basket.

00:44:25.980 --> 00:44:27.960
And that's what the keyring approach is.

00:44:27.960 --> 00:44:35.900
But it also, like, beyond just the, you know, protection against malware, there's also a kind of level of management that you can do.

00:44:35.900 --> 00:44:44.380
It puts, by using your platform's default keyring or encrypted store, there are platform-specific APIs for, like,

00:44:44.440 --> 00:44:45.420
enumerating secrets.

00:44:45.420 --> 00:44:52.580
And so if you're trying to do an inventory of, like, what secrets are on my computer, having them in there is nice because you don't have to go hunting around for them.

00:44:52.580 --> 00:44:56.240
It gives you, as a defender, a little bit of an advantage because you know what you're defending against.

00:44:56.240 --> 00:44:59.180
You know, oh, hey, this secret shouldn't be on this computer.

00:44:59.180 --> 00:45:02.480
This should really be, like, only, you know, on this one server over here.

00:45:03.180 --> 00:45:05.320
So using keyring also gets you that.

00:45:05.320 --> 00:45:14.520
It also gets you this configurability because, like, once you actually put your code into production in the cloud, it's not going to have access to your local, you know, keyring on your Mac.

00:45:14.660 --> 00:45:18.220
It's going to be a certain deadlock of your app if it pops up.

00:45:18.220 --> 00:45:20.640
Can this website access the keychain?

00:45:20.640 --> 00:45:22.320
You know, use Touch ID to allow.

00:45:22.320 --> 00:45:23.920
It's probably not going to work in production.

00:45:23.920 --> 00:45:24.300
Right.

00:45:24.400 --> 00:45:29.020
So you have to use an alternate keyring backend on your server.

00:45:29.020 --> 00:45:30.680
And that is a little bit awkward.

00:45:30.680 --> 00:45:33.680
And that sometimes turns people off and they're just like, ah, I'll just use a config file.

00:45:33.680 --> 00:45:39.500
But there are ways to configure, like, and they're actually documented, like, right on the keyring webpage.

00:45:39.500 --> 00:45:47.220
Like, you can, it talks about keyrings.crypt file, which is this, like, extra backend that you can get that stores stuff in an encrypted file.

00:45:47.220 --> 00:45:51.260
Keyrings.alt includes, like, just a plain text file.

00:45:51.520 --> 00:46:03.000
If you know that on your server you have, like, a secure place to put a text file because the server is going to need to be accessing the secret over and over again, you can just say, okay, I'm going to configure the backend as part of this Docker container.

00:46:03.000 --> 00:46:08.360
Like, it's just going to read this file from this volume and that's the keyring backend I'm using.

00:46:08.360 --> 00:46:10.300
But again, that's all configuration.

00:46:10.300 --> 00:46:13.280
You write your app to just use keyring.

00:46:13.280 --> 00:46:20.100
And then after the fact, when you're setting up your deployments, you can select what the most appropriate backend is.

00:46:20.460 --> 00:46:33.360
And in fact, one of the things I talked about during the talk was as I was trying to find, like, the super secure way to, like, disable access to secrets on Windows and Linux, and I didn't find it, I actually wrote my own keyring backend to demonstrate how you would do this.

00:46:33.360 --> 00:46:47.260
So, when you're doing this, like, you're doing this, like, you're doing this, like, you're doing this.

00:46:47.260 --> 00:46:58.760
It works on macOS, it works on Windows, and it requires you to be seated at your computer with your YubiKey plugged in in order to use this, like, keyring backend.

00:46:58.760 --> 00:47:00.160
So, by configuring...

00:47:00.160 --> 00:47:07.060
When your Python code hits keyring.getpassword, the next thing that has to happen before that returns, you have to attach the YubiKey.

00:47:07.060 --> 00:47:10.660
And this is also a good example of how, like, this was a cool project.

00:47:10.660 --> 00:47:12.700
It was fun to play around with that API.

00:47:13.200 --> 00:47:19.660
I had some smarter security people than me look at it to make sure I wasn't releasing something super unsafe, just for a laugh.

00:47:19.660 --> 00:47:21.380
So, I think it is definitely usable.

00:47:21.380 --> 00:47:26.040
But it's also an example of a keyring backend that you would not always want to use, right?

00:47:26.040 --> 00:47:29.360
Like, this is for your super high security secrets.

00:47:29.360 --> 00:47:32.180
It doesn't even have support for multiple YubiKeys.

00:47:32.420 --> 00:47:34.340
So, again, you've got to think about availability.

00:47:34.340 --> 00:47:37.600
Like, anything you put into this, you probably want to back up somewhere else.

00:47:37.600 --> 00:47:40.540
But it is a relatively convenient thing.

00:47:40.540 --> 00:47:43.600
You just have to kind of touch it with your finger to unlock it.

00:47:43.600 --> 00:47:45.720
But it's also really, really secure.

00:47:45.720 --> 00:47:52.620
So, like, some of your secrets you might want to put into this backend to make sure that there's no way for software to access them automatically.

00:47:52.620 --> 00:47:57.120
There's no way that malware running on your computer is going to be able to just, like, hoover them up.

00:47:57.460 --> 00:48:05.240
Anytime you see a prompt for an authenticator touch that you weren't expecting, that's like a real eyebrow raise moment.

00:48:05.240 --> 00:48:11.700
And so, but, you know, Token Ring is just kind of my example of one of these things.

00:48:11.700 --> 00:48:17.600
There are dozens of other keyring backends that you can use for either different levels of security on your own machine.

00:48:17.600 --> 00:48:22.760
Although, honestly, the platform encrypted stores are generally pretty good, like, for a default.

00:48:23.180 --> 00:48:27.880
But you can also use alternate backends for different cloud secret providers.

00:48:27.880 --> 00:48:32.560
Like, I believe HVAC, which is a HashiCorp vault backend.

00:48:32.560 --> 00:48:35.840
I haven't actually used HVAC, so I'm not totally sure how it works.

00:48:35.840 --> 00:48:41.500
But I believe it actually has a keyring backend, which is only one, like, tiny part of what it does.

00:48:41.640 --> 00:48:46.120
But it can turn a vault into a keyring for you, I think.

00:48:46.120 --> 00:48:50.380
If it can't, then the adapter to do so would be very, you know, trivial to write.

00:48:50.380 --> 00:48:57.100
But that's the idea, is that you write your code to use keyring, and then wherever you deploy it, you can figure it to use the keyring that's appropriate to that context.

00:48:57.100 --> 00:48:57.700
All right, right.

00:48:57.700 --> 00:49:02.000
One of the interesting ones is the Bitwarden backend, which is kind of nice.

00:49:02.000 --> 00:49:02.340
Right.

00:49:02.340 --> 00:49:04.760
I was actually a little disappointed because I'm a big 1Password fan.

00:49:04.760 --> 00:49:05.160
I know.

00:49:05.160 --> 00:49:06.120
I don't use Bitwarden personally.

00:49:06.120 --> 00:49:07.920
And I was like, oh, but there's a CLI.

00:49:07.920 --> 00:49:09.440
Like, they could have made one.

00:49:09.440 --> 00:49:10.980
And I'm sure somebody eventually will.

00:49:11.300 --> 00:49:19.100
Yeah, I think it's also worth just a quick pointing out that both 1Password and Bitwarden come with CLIs.

00:49:19.100 --> 00:49:21.100
So that is an option, right?

00:49:21.100 --> 00:49:26.600
And 1Password even can be an SSH daemon for some of that as well.

00:49:26.600 --> 00:49:32.680
So those are both options for ways that your app can directly interact with your password manager.

00:49:32.680 --> 00:49:35.600
And it doesn't have to necessarily be the one that you use, right?

00:49:35.600 --> 00:49:39.800
For example, you and I are 1Password people, but maybe our app is a Bitwarden person.

00:49:40.920 --> 00:49:47.220
It's all about separating that software authorship thing from the user experience, right?

00:49:47.220 --> 00:49:49.480
Like, the user should be able to select their own keyring.

00:49:49.560 --> 00:49:54.080
It almost sounds like a little bit trivial to say, just use keyring and it'll all work.

00:49:54.080 --> 00:50:03.440
But like, it's that separation that you're trying to achieve is that you want code that can be configured to be as secure as it needs to be and has like good defaults for most people.

00:50:03.440 --> 00:50:03.760
Okay.

00:50:03.760 --> 00:50:04.300
All right.

00:50:04.300 --> 00:50:06.320
So there's a couple more lessons in here.

00:50:06.820 --> 00:50:13.240
If you're a doc writer, don't encourage people to put their API token straight in the source code.

00:50:13.240 --> 00:50:17.240
And you shame a few well-known companies saying it's not just that, but...

00:50:17.800 --> 00:50:18.120
Yeah.

00:50:18.120 --> 00:50:20.060
So that was like the biggest lesson.

00:50:20.060 --> 00:50:22.220
But some other things here is that...

00:50:22.220 --> 00:50:29.100
Or sorry, not another call to action here is that you really want to think about, you know, think about that time loop that you're in.

00:50:29.100 --> 00:50:32.500
What are all of the different attacks could impact you?

00:50:32.500 --> 00:50:34.180
Write them down.

00:50:34.180 --> 00:50:36.020
Think about how...

00:50:36.020 --> 00:50:44.280
What you want to be secure against the talk when it's out on YouTube kind of goes through them in order and can maybe when it comes out, you can have a listen.

00:50:44.280 --> 00:50:57.020
But once you've written that down, stick to it and make sure that your processes are such that it's really easy to do all of the defenses that you have selected that are like relevant to you and to your application.

00:50:57.020 --> 00:51:03.980
Like doing threat modeling is a great way to draw a line around that anxiety about like how secure are my secrets?

00:51:04.120 --> 00:51:05.380
Like if you kind of...

00:51:05.380 --> 00:51:12.900
If it's all just vibes and like, oh, you think about this one news story one day and then you write some security that like defends against that one particular thing.

00:51:12.900 --> 00:51:23.800
Or you like do something on your laptop one day that's in a more secure way, but you don't like encode that as a process or something that you do repeatedly for each new secret.

00:51:23.800 --> 00:51:29.800
Like as you said close to the top of the show here, like we're all using a zillion APIs now.

00:51:30.600 --> 00:51:41.780
So if you think of a good way to access your Stripe API key and then next week you have to add Braintree support and then the week after that you have to add, you know, OpenAI, right?

00:51:41.780 --> 00:52:05.000
Like as you add each one, you need to be doing things the same way, both so that you can correctly implement your security controls for each new thing, but also so that once you've implemented them, when you want to enhance them, when you grow to a certain size, you start getting more attacks, you start getting, you know, facing new, more difficult threats as you're a bigger target.

00:52:05.000 --> 00:52:11.680
You have to be able to upgrade and you want to be able to upgrade all of your secrets management at once as easily as you can.

00:52:11.680 --> 00:52:14.220
And there, there are other things outside the scope of what we're talking about today.

00:52:14.220 --> 00:52:19.140
Like you also need to be able to like rotate those secrets, which is a whole other mess.

00:52:19.140 --> 00:52:24.420
I mean, that's what tools like HashiCorp's vault can like help manage that part of the process.

00:52:25.100 --> 00:52:31.600
But yeah, so the call to action for like doc writers and framework authors is like, don't document things the wrong way.

00:52:31.600 --> 00:52:32.880
Don't provide bad defaults.

00:52:32.880 --> 00:52:44.220
You use key ring if you're doing Python stuff, but the call to action for like app maintainers and people operating services is do some threat modeling, write it down and do everything the same way.

00:52:44.220 --> 00:53:01.060
Like the more that it's all funneled through that choke point of key ring and of your documented security processes, the more that when you have to make it better, it will not be a giant pain of like trawling through all of your code and all of your libraries and trying to figure out where things even are.

00:53:01.060 --> 00:53:17.240
You'll just be able to look at your, you know, the code that's accessing the secret and say like, oh, well, we're, we're going to switch from like, you know, our sort of homegrown thing to some vault or to Amazon secret store or Google cloud equivalent, or, you know, digital ocean has a thing.

00:53:17.240 --> 00:53:19.260
Everybody's got their own secret storage thing.

00:53:19.260 --> 00:53:20.460
There's a bunch of products in this area.

00:53:20.460 --> 00:53:24.060
And when you adopt one, you want that process to be as smooth as possible.

00:53:24.060 --> 00:53:26.840
It's also probably a bit of a friction.

00:53:26.840 --> 00:53:30.860
I always think about, you know, how do you encourage people to do the right thing?

00:53:30.860 --> 00:53:36.340
In a way you discourage them is you add friction and you make it harder to do the right thing.

00:53:36.340 --> 00:53:36.780
Right.

00:53:36.780 --> 00:53:47.540
So if the right thing is to, you figure out a way to manage one of your secrets, well, make it easy to bring on another API, make it easy to, you know, basically get in there and change that and work with that system.

00:53:47.540 --> 00:53:47.880
Yeah.

00:53:47.880 --> 00:53:48.260
All right.

00:53:48.260 --> 00:53:48.640
Let's see.

00:53:48.640 --> 00:53:51.020
We're getting short on time, but what other lessons do we have?

00:53:51.020 --> 00:53:53.420
You know, talk a bit about where do we put some of these things.

00:53:53.500 --> 00:54:03.680
You did also point out that there's beyond the keyring stuff is you do have stuff for like AWS secrets in particular.

00:54:03.680 --> 00:54:06.920
And I suppose there's probably other ones as well, right?

00:54:06.920 --> 00:54:16.140
Like what we talked about so far mostly is security on your computer or security on the one server that you go and run your app or the cluster of servers.

00:54:16.420 --> 00:54:18.820
But, you know, what about GitHub automation?

00:54:18.820 --> 00:54:20.960
You know, things like that, right?

00:54:20.960 --> 00:54:22.120
There's various tools.

00:54:22.120 --> 00:54:26.400
The two that I've talked about in my talk are there's a tool called AWS Vault.

00:54:26.400 --> 00:54:33.920
There's another one called Gimme AWS Creds, which make it more secure to store your AWS credentials in particular.

00:54:33.920 --> 00:54:38.940
Because those are pretty in the same way that like your computer is the root of security for like everything.

00:54:38.940 --> 00:54:40.800
And that's where all your secrets are ultimately stored.

00:54:40.800 --> 00:54:47.420
Your AWS account is like kind of the root of your security for AWS for all of your cloud resources if you're using them.

00:54:47.420 --> 00:54:53.280
So it's that it's good to focus more on like the specific things that have a lot of power.

00:54:53.280 --> 00:55:01.580
Those also can reduce the power, like have roles that have like less permission that isn't just like your cloud root API key for everything.

00:55:01.820 --> 00:55:07.700
There's also like GitHub has a secrets system, which is effectively just injecting environment variables.

00:55:07.700 --> 00:55:11.820
But it stores them in a way that like keeps them out of your repo.

00:55:11.820 --> 00:55:15.260
It puts them in a place that, again, you can enumerate.

00:55:15.260 --> 00:55:19.920
You can see all of the secrets that are provisioned against your particular repository.

00:55:19.920 --> 00:55:31.180
It manages access control for like, you know, public open source PRs can't like immediately access all those secrets because they're running like they have to be run in a way that indicates that like an admin has kind of.

00:55:31.720 --> 00:55:33.880
Seen that something is going to happen.

00:55:33.880 --> 00:55:37.720
So they only run on like your main branch or things like that.

00:55:37.720 --> 00:55:39.560
And it's a little difficult to talk about these.

00:55:39.560 --> 00:55:48.920
And this is one of the reasons that I focus so heavily on your local computer, both because it's kind of the base of this pyramid, but also because you really have to do that research on your own.

00:55:48.920 --> 00:55:56.700
Because you have to know what services you're using and what tools are available to manage certain secrets within them.

00:55:56.700 --> 00:56:04.700
And keyring is so important because it's the thing that gives you the joint of flexibility to say like, oh, well, when it's running in GitHub, it's going to be in an N var.

00:56:04.700 --> 00:56:06.000
And it's going to be in this N var.

00:56:06.000 --> 00:56:07.980
And I'm going to write a keyring back in that knows that.

00:56:07.980 --> 00:56:08.420
Interesting.

00:56:08.420 --> 00:56:08.760
Yeah.

00:56:08.840 --> 00:56:11.740
Keyring sounds like a really important piece of this story.

00:56:11.740 --> 00:56:12.060
Yeah.

00:56:12.060 --> 00:56:14.000
I mean, it is in the Python world.

00:56:14.000 --> 00:56:20.220
It really is like the beginning of every story about improving your security is, okay, now that you're using keyring, you can.

00:56:20.220 --> 00:56:21.740
And then there's like the next thing.

00:56:21.740 --> 00:56:29.440
And there's a bunch of directions you can go in depending on if it's your local computer, if it's the cloud, if it's like a dedicated server, if it's an embedded device.

00:56:29.500 --> 00:56:35.800
There's all different ways that you could go, but it kind of all starts with like acknowledging that you're going to need that flexibility.

00:56:35.800 --> 00:56:38.800
And honestly, you could write your own version of keyring.

00:56:38.800 --> 00:56:43.840
You know, all it is a function that like looks at a config file and figures out what other function to call.

00:56:43.840 --> 00:56:52.600
But because it's the standard one, like it is a social convention that is very powerful because you really don't want to write all of your own backends for everything.

00:56:52.600 --> 00:57:00.360
Right. It's about the integration with the other systems, about integrating with the Bitwarden CLI and with macOS keychain and doing all those things right.

00:57:00.360 --> 00:57:00.760
Yeah.

00:57:00.760 --> 00:57:08.000
Right. Yeah. And those good defaults are really important because like integrating with the macOS keychain is not easy and keyring just does it all for you.

00:57:08.000 --> 00:57:08.640
So yeah.

00:57:08.640 --> 00:57:18.580
One thing I also wanted to, this is kind of a minor point, but I just, I really want to toss it in there because I feel like it's rarely covered, which is environment variables have kind of taken over in the cloud.

00:57:18.580 --> 00:57:22.100
Like they're the standard way that a lot of services expect you to inject stuff.

00:57:22.100 --> 00:57:39.060
So I can't say like, don't use env vars, like it's just, that's not feasible, but when you can avoid them, like if you can get your credentials stored some other way, like in a text file or whatever, try to stick to that because env vars are really easy to accidentally dump in a debugging session.

00:57:39.060 --> 00:57:41.460
Like you can just type env and it'll dump out everything.

00:57:41.460 --> 00:57:49.400
And a lot of like CI builds or debug log uploaders will just like kind of dump out the environment because it's useful to know.

00:57:49.400 --> 00:57:54.600
And filtering secrets out of that is a whole like discipline that you have to develop.

00:57:54.740 --> 00:58:02.900
And like a lot of tools that do debugging like Sentry will have like a lot of code to do that filtering, but it's best if you could just put the secrets where the secrets go.

00:58:02.900 --> 00:58:11.420
So like one idiom that you could use is like, you can put a crypto key in your environment variable, which can't do anything but like decrypt the text file.

00:58:11.540 --> 00:58:15.060
And so that key is kind of useless outside the CI context or whatever.

00:58:15.060 --> 00:58:21.900
And so you just like indirect it so that the actual secret is stored in a place that is not just going to be dumped in every debug log.

00:58:22.000 --> 00:58:23.940
The danger may be given away too much.

00:58:23.940 --> 00:58:24.640
That's what I do.

00:58:24.640 --> 00:58:31.340
I have one encryption key that's pretty long and a really high level of encryption of the actual secret somewhere else.

00:58:31.340 --> 00:58:37.200
And for me to add another secret, another API endpoint as well, to add it to this file and then re-encrypt it.

00:58:37.200 --> 00:58:39.600
You know, it doesn't, it's sort of the same process.

00:58:39.600 --> 00:58:45.400
So it's not like, well, these APIs are encrypted that way and the database connection is encrypted that way.

00:58:45.400 --> 00:58:50.780
It's like, here's the file that's got all the info in it and then it's highly encrypted.

00:58:50.940 --> 00:58:53.020
Yeah, and that's exactly what I want to encourage people to do.

00:58:53.020 --> 00:58:55.460
Put all your eggs in one basket and then watch the basket.

00:58:55.460 --> 00:58:58.640
Passwords go in the password manager.

00:58:58.640 --> 00:59:00.240
Crypto stuff goes in the file.

00:59:00.240 --> 00:59:02.800
Please, please, please don't let it get exposed.

00:59:02.800 --> 00:59:03.160
Okay.

00:59:03.160 --> 00:59:10.000
Let's wrap up this conversation with a bit of a summary from what you take away from your talk here.

00:59:10.000 --> 00:59:13.840
Yeah, so I think we've hammered home, you know, you should use a password manager.

00:59:13.840 --> 00:59:19.520
You should make sure that your master passwords for that password manager are backed up.

00:59:19.780 --> 00:59:24.960
One thing we didn't cover today, but it's pretty big in the talk is like, you should trust the autofill on your password manager.

00:59:24.960 --> 00:59:32.080
Because like, a lot of phishing attacks will make a very convincing website that will trick even the most seasoned security people.

00:59:32.080 --> 00:59:38.340
So like, just if it doesn't autofill, close the window, type the URL by hand, make sure it autofills.

00:59:38.340 --> 00:59:40.780
Yeah, I think people often see that.

00:59:40.780 --> 00:59:43.460
Well, this is just the password manager is incomplete.

00:59:43.460 --> 00:59:45.180
So it's not helping me with this website.

00:59:45.180 --> 00:59:50.140
Like, that should be, you know, a super big red flag if the password manager is not suggesting to autofill.

00:59:50.140 --> 00:59:59.440
Yeah, and one of my favorite things about 1Password is that they have been getting progressively more aggressive about making it super annoying to like disable that.

00:59:59.440 --> 01:00:08.640
Like now when you do, if you try to autofill with 1Password in the wrong app or the wrong website, it now pops up a dialogue that's like, do you want to like add this URL?

01:00:08.640 --> 01:00:09.800
Do you want to fill this once?

01:00:09.800 --> 01:00:10.940
Or was this a mistake?

01:00:10.940 --> 01:00:15.160
Like it will ask you every time if you try to force it to.

01:00:15.160 --> 01:00:18.680
But obviously like copy paste kind of circumvents all those protections.

01:00:18.680 --> 01:00:20.720
So like never, ever use copy paste.

01:00:20.720 --> 01:00:22.400
Always try to get it to autofill.

01:00:22.400 --> 01:00:23.980
You should use full disk encryption.

01:00:23.980 --> 01:00:27.260
Just turn on FileVault or what's the Microsoft?

01:00:27.260 --> 01:00:27.760
BitLocker.

01:00:27.760 --> 01:00:28.920
BitLocker, yeah.

01:00:28.920 --> 01:00:31.080
Or DMCrypt, I think is the Linux one.

01:00:31.080 --> 01:00:34.600
Like you should, the technology now is like pretty much free.

01:00:34.600 --> 01:00:36.480
It doesn't really cost much in the way of performance.

01:00:36.480 --> 01:00:44.200
Like, and it gives you peace of mind if your laptop gets stolen, which is sadly a thing that speaking of like, you know, GitHub credentials leaking constantly.

01:00:44.540 --> 01:00:45.840
Laptops are stolen every day.

01:00:45.840 --> 01:00:48.460
So you should make encrypted backups.

01:00:48.460 --> 01:00:51.820
You should make sure you have like a restore plan because availability is really important.

01:00:51.820 --> 01:00:54.860
Obviously, use keyring, use keyring, use keyring.

01:00:54.860 --> 01:00:59.960
And pick an appropriate backend for the level of security that you need in each place where your code's deployed.

01:00:59.960 --> 01:01:01.120
Yeah, absolutely.

01:01:01.120 --> 01:01:01.740
All right.

01:01:01.740 --> 01:01:06.160
Well, Cliff, thanks for thinking about all this for everyone and giving us a list.

01:01:06.160 --> 01:01:13.040
And I think people will really enjoy your storytelling when the PyCon video eventually comes out.

01:01:13.040 --> 01:01:15.720
Yeah, I can't wait to start sending people over to the YouTube video.

01:01:15.720 --> 01:01:17.760
I was pretty proud of how it went.

01:01:17.760 --> 01:01:24.900
It's my first talk in quite a while because I don't know if you know this, but the last few years have been a little stressful for everybody.

01:01:24.900 --> 01:01:27.640
A lot of stuff going on.

01:01:27.840 --> 01:01:32.080
It scrambles up the whole conference track, conference circuit a little bit.

01:01:32.080 --> 01:01:32.340
Yes.

01:01:32.340 --> 01:01:32.920
All right.

01:01:32.920 --> 01:01:36.640
Before we get out of here, let's give you a chance to give a shout out to a PyPI package.

01:01:36.640 --> 01:01:41.920
I mean, feel free to pick keyring if you want one more time or something else that you think is kind of awesome people should check out.

01:01:41.920 --> 01:01:42.800
That's always tough.

01:01:42.900 --> 01:01:46.260
I remember, I know that this question is coming every time I'm on this podcast.

01:01:46.260 --> 01:01:46.960
Well, let's see.

01:01:46.960 --> 01:01:52.740
The choices are getting harder because we're up to 456,000 packages on PyPI.

01:01:52.740 --> 01:01:53.560
How nuts is that?

01:01:53.560 --> 01:01:54.500
There's a lot out there.

01:01:54.860 --> 01:01:58.740
I guess I should take this as an opportunity to like, oh, you know what?

01:01:58.740 --> 01:02:05.960
Actually, I do have a self-promotion thing that I should put in here that is not, we did not talk about at all today, which is date type.

01:02:05.960 --> 01:02:08.660
Date type is another little package that I wrote.

01:02:09.320 --> 01:02:24.980
And it's a workaround for like one specific bug in the standard library, which is that dates are assignable to like dates and date times are considered equivalent because they are one subclass is the other.

01:02:24.980 --> 01:02:31.640
And this will make it so that you can't assign a date time to a date because they don't actually, like they're not compatible.

01:02:31.640 --> 01:02:33.180
They're not Liskov substitutable.

01:02:33.180 --> 01:02:37.480
And it will also give you separate types for naive and aware date times.

01:02:37.480 --> 01:02:38.620
So you can't mix those up.

01:02:39.040 --> 01:02:39.360
Oh, nice.

01:02:39.360 --> 01:02:41.640
It is not actually a library.

01:02:41.640 --> 01:02:43.320
It looks like a library.

01:02:43.320 --> 01:02:44.780
And I guess it does have one function in it.

01:02:44.780 --> 01:02:50.160
But what it actually is, is a bunch of abstract protocol like type stubs.

01:02:50.160 --> 01:02:53.020
And so the actual, at runtime, there's still date times.

01:02:53.020 --> 01:02:54.220
Everything works exactly the same.

01:02:54.220 --> 01:02:55.620
It doesn't change how your code behaves at all.

01:02:55.620 --> 01:03:00.520
But by importing from date type instead of date time, you get this extra mypy type safety.

01:03:00.520 --> 01:03:00.920
Excellent.

01:03:00.920 --> 01:03:01.460
All right.

01:03:01.460 --> 01:03:01.800
Very cool.

01:03:01.800 --> 01:03:06.340
That and also Rich, because like that text UI stuff is amazing.

01:03:06.340 --> 01:03:07.800
But I feel like everybody talks about that one.

01:03:08.760 --> 01:03:09.560
Rich is awesome.

01:03:09.560 --> 01:03:11.860
Will's doing a good job over there with that for sure.

01:03:11.860 --> 01:03:12.920
All right.

01:03:12.920 --> 01:03:13.540
Final question.

01:03:13.540 --> 01:03:18.460
If you're going to work on date type or any of these other projects, what editor are you using these days?

01:03:18.460 --> 01:03:22.740
I use Emacs as I have for nigh on 30 years now.

01:03:22.920 --> 01:03:25.320
You prefer to have an operating system for your editor?

01:03:25.320 --> 01:03:26.980
I don't treat it as an OS.

01:03:26.980 --> 01:03:30.180
I feel like a lot of people, you know, kind of live inside Emacs all the time.

01:03:30.180 --> 01:03:31.320
And I use Emacs for a lot.

01:03:31.320 --> 01:03:33.980
I think I love the text editing facilities.

01:03:33.980 --> 01:03:43.480
Every time I kind of try to drop into like VS Code or one of the, you know, new cool text editors, I always like the IDE stuff is often nicer than Emacs.

01:03:43.480 --> 01:03:55.000
But the text editing itself, like the number of motions, the kinds of things you can do to like select a word, select a function, select a line, you know, select a sentence, rewrap a paragraph.

01:03:55.000 --> 01:04:00.520
There's all these things that you do as you're just working with text in Emacs.

01:04:00.520 --> 01:04:06.420
So it's like a, it's a text editor in a way that few other IDEs are really text.

01:04:06.420 --> 01:04:07.180
Yeah.

01:04:07.180 --> 01:04:09.460
I feel like Vim is a little more interchangeable.

01:04:09.460 --> 01:04:09.800
Yeah.

01:04:09.800 --> 01:04:11.740
A lot of the editors have Vim bindings, right?

01:04:11.740 --> 01:04:12.660
I've used Vim.

01:04:12.660 --> 01:04:17.260
I actually kind of took a break from Emacs for about two years at one point and switched entirely to Vim.

01:04:17.260 --> 01:04:21.200
But my Vim config has been slowly breaking over the years.

01:04:21.200 --> 01:04:28.900
So I actually deleted the whole thing last year and I've been trying to get into NeoVim, but there's a little bit of like, it's a different world.

01:04:28.900 --> 01:04:30.840
So I haven't managed to get into it.

01:04:30.840 --> 01:04:31.660
Very cool.

01:04:31.660 --> 01:04:32.520
All right.

01:04:32.520 --> 01:04:38.820
Well, final call to action for people who are now maybe a little bit nervous and thinking about how they should treat their secrets differently.

01:04:38.820 --> 01:04:39.260
Yeah.

01:04:39.260 --> 01:04:41.300
I mean, I think that that's a good point.

01:04:41.300 --> 01:04:42.320
They might be a little nervous.

01:04:42.320 --> 01:04:42.980
Relax.

01:04:42.980 --> 01:04:44.340
It's going to be okay.

01:04:44.340 --> 01:04:45.720
That's my call to action.

01:04:45.720 --> 01:04:50.300
And use keyring and don't like write docs that tell people to paste stuff into their source code.

01:04:50.460 --> 01:04:54.080
But like mostly just like relax and take this methodically.

01:04:54.080 --> 01:04:55.900
Nobody's attacking you right now.

01:04:55.900 --> 01:05:02.880
And it's very easy to get worked up about security and think like, oh no, you know, all of these attacks, like all this horrible stuff could happen.

01:05:02.880 --> 01:05:05.120
But really, like today's the same as yesterday.

01:05:05.120 --> 01:05:08.440
You just need to start adding those defenses a little bit at a time.

01:05:08.440 --> 01:05:08.880
Absolutely.

01:05:08.880 --> 01:05:10.520
Well, thanks again for being on the show.

01:05:10.520 --> 01:05:11.400
It's great to catch up with you.

01:05:11.400 --> 01:05:12.360
Thanks so much for having me.

01:05:12.360 --> 01:05:12.840
This was great.

01:05:12.840 --> 01:05:13.320
Yeah, you bet.

01:05:13.320 --> 01:05:13.560
Bye.

01:05:13.560 --> 01:05:13.580
Bye.

01:05:13.580 --> 01:05:17.360
This has been another episode of Talk Python To Me.

01:05:17.360 --> 01:05:19.180
Thank you to our sponsors.

01:05:19.560 --> 01:05:20.780
Be sure to check out what they're offering.

01:05:20.780 --> 01:05:22.200
It really helps support the show.

01:05:22.200 --> 01:05:27.040
The folks over at JetBrains encourage you to get work done with PyCharm.

01:05:27.040 --> 01:05:38.240
PyCharm Professional understands complex projects across multiple languages and technologies, so you can stay productive while you're writing Python code and other code like HTML or SQL.

01:05:38.240 --> 01:05:43.380
Download your free trial at talkpython.fm/done with PyCharm.

01:05:44.000 --> 01:05:48.080
Listen to an episode of Compiler, an original podcast from Red Hat.

01:05:48.080 --> 01:05:55.520
Compiler unravels industry topics, trends, and things you've always wanted to know about tech through interviews with the people who know it best.

01:05:55.520 --> 01:05:59.640
Subscribe today by following talkpython.fm/compiler.

01:06:00.380 --> 01:06:01.440
Want to level up your Python?

01:06:01.440 --> 01:06:05.420
We have one of the largest catalogs of Python video courses over at Talk Python.

01:06:05.420 --> 01:06:10.580
Our content ranges from true beginners to deeply advanced topics like memory and async.

01:06:10.580 --> 01:06:13.260
And best of all, there's not a subscription in sight.

01:06:13.260 --> 01:06:16.160
Check it out for yourself at training.talkpython.fm.

01:06:16.300 --> 01:06:20.840
Be sure to subscribe to the show, open your favorite podcast app, and search for Python.

01:06:20.840 --> 01:06:22.160
We should be right at the top.

01:06:22.160 --> 01:06:31.500
You can also find the iTunes feed at /itunes, the Google Play feed at /play, and the direct RSS feed at /rss on talkpython.fm.

01:06:31.500 --> 01:06:34.940
We're live streaming most of our recordings these days.

01:06:34.940 --> 01:06:42.720
If you want to be part of the show and have your comments featured on the air, be sure to subscribe to our YouTube channel at talkpython.fm/youtube.

01:06:43.260 --> 01:06:44.620
This is your host, Michael Kennedy.

01:06:44.620 --> 01:06:45.920
Thanks so much for listening.

01:06:45.920 --> 01:06:47.080
I really appreciate it.

01:06:47.080 --> 01:06:48.980
Now get out there and write some Python code.

01:06:48.980 --> 01:07:09.680
I'll see you next time.

01:07:09.680 --> 01:07:39.660
Thank you.