I am Tim Corey. I teach coding online and my inbox is full of questions from current and future developers. I wish I could sit down with each of you and share the answers I know will help you go further, faster in the world of development. This podcast is the next best thing. On this podcast, I will answer the biggest questions people are asking! Send us to your suggestion for a future Dev Questions at https://suggestions.iamtimcorey.com/ To keep the podcast coming, like, subscribe, rate, and share it with your friends and colleagues. See why thousands of students have chosen to learn to think and code like a professional developer at www.DevForge.com.
Use Left/Right to seek, Home/End to jump to start or end. Hold shift to jump forward or backward.
0:00
|
12:02
Where do I put my secrets in my application? Should I encrypt my connection strings? Are user secrets actually secure when they are in plain text? How do I protect my passwords and API keys from developers and users? These are the questions we will answer in today's episode of DevQuestions.
Most applications have to deal with secret information. From API keys to passwords to connection strings, connecting to sensitive resources involves secrets. So where do you put them? How do you ensure they are staying secret? Those answers change based upon a lot of factors, including development versus production, and whether or not you're using an AI to help you in development. So let's talk about it in today's episode of DevQuestions. Software development is more than just writing code. So let's talk about the rest of it. Specifically, let's talk about where to store your secrets as a developer. And let's start off by saying that this answer has changed a bit in light of AI agents. So what was recommended practice isn't necessarily the right call anymore. Also, I'm going to be addressing this as a.NET developer. If you are a.NET developer, some of this might not apply. However, most of it will. And the principles will be similar for your language. I will be talking about front-end frameworks like React as well. So that will directly apply. Let's start with a big one. Developers should not have access to any production resources. Now, there is an exception here for if you're on a very small team where you're also the production deployment person. But even then, there needs to be some separation. So the information you have, whether you are a small team as your job too, or whether it's somebody else's job, the information about the secrets, about the connection strings, and other things should be stored in something like Azure Key Vault. And the devs should not have access to it or to the production servers. This is especially true if AI has access to developer machines. AI looks for credentials. It's unfortunately one of the things that people don't realize AI does. When you give an AI permission to look at your hard drive, it doesn't always stay where it's supposed to stay. Sometimes it wanders a bit. And one of the things that we have seen over and over is that an AI will look to elevate its own permissions to solve the problem of not having access to something. And it has more than one once looked and found those credentials and then treated that like it's a development resource and done some pretty horrific things in production. So we need to be very careful to separate out our sensitive data from our AIs, but even from developers, they should not have access to production. And I know a lot of developers say, no, I definitely should. How else could I debug it? How else could I? There are ways, as long as you're focused on being secure. If you're focused on being fast and on just quote unquote getting the job done and not worried about security, sure. Have access to the keys for everything and then just be safe, right? But that's not a good practice. A good practice is to have clear separation and automated systems that take you the last steps. Because part of your process should be a good CI CD process that takes your code from one location to another in automated manner. So you're testing how it's going to work when you deploy. That way you are sure this is going to work and you're not going to have surprises when you hit production. This makes your deployment to production faster, it makes it cleaner, it makes it less likely to have to be rolled back and more. So that whole process should be automated anyway. So developers shouldn't be touching production directly for deployments. So the other part of that is well, developers need to have access in order to debug stuff. Well, if you are properly backing up your production systems, especially your databases, and then cleaning that data and putting it into development as a development database, you often don't need to even do that because the development data is just hours different than production. So all of a sudden, now you have all the data you need while being secure. Things like email addresses have been sanitized, things like person-identifiable information has been changed so that you're not giving developers access to sensitive information, but at the same time, they have all the information they need for testing. And your environment should be very, very similar between production and development so that you can accurately test on things. So, yes, I recommend that developers not have access to any production resources, especially not just because, but especially if they use AI. Because too often AI will use those credentials or ingest those credentials, which means they all need to be rotated. Okay, so what do you do during development? Well, if you're a.NET developer, store your secrets in the user secrets JSON file. If you don't know what that is, I've got videos on my channel. I have a whole course dedicated to app settings, including user secrets. Um, these are for things where it's gonna be local. So you're working on a local database, you're working on a local email server equivalent where it's just you know showing that yes, an email went out or something like that, but it's not actually sending emails. Um, all these different things, they're local and you have your own local settings. If you put those in user secrets, they don't go into your source control, they don't disrupt the other users on the team and what their local secrets are, and yet you can all use your own local secrets to have your own local setup. This is the way you do it. So that's kind of step one. Have a place for local secrets. Again,.NET developers, we have it easy. We just use user secrets. Now, with that, do not give AI access to your hard drive. Which you probably say, uh, that's too late for that. I've already done that. Change that. Don't do that. Instead, run it in a container. Give it full access if you want to that container, but not to your actual hard drive. Otherwise, there are too many things that AI can do to compromise you. It can read through your entire drive and figure out what secrets might be there. It can look at different your browser headless and look at all the local storage and session storage in your browser for any secrets that may be there. So it can do a lot of things that you really don't want to have at have it have access to. And all of a sudden, your AI might have access to things that you never expected it to. So make sure you isolate your AI from your actual development machine. Run it in a container. It's absolutely possible. It's not that hard. You can do this. Make sure you separate it from your development machine. Again, because when you store your user secrets in that secrets.json, well, your AI can go and read those. And those should not be secret. Okay? Those should not be a big deal. They should be something that can be given away. They because you should be using like, you know, SA for both a username and password for a SQL database. And you might, you know, using a connection string that has no credentials but lets you log into a local database. These things should not be secrets. But you still don't want to have access, give AI access to things it shouldn't have access to, especially if you're a person who reuses credentials too much. Don't do that. And that kind of leads us into the next point. Do not access production resources locally. This is one that we all violate at some point because it's just easier. And don't do this, don't give into this. But this is one where, you know what, I'm gonna put the production connection string in my app and run it locally just to see what's happening. But I can debug easier if I have Visual Studio open in debug mode, but have the production connection string. Don't do that. Because then what happens is you've given access to potentially an AI to scan that. If you have, if you're using Visual Studio, you might have copilot running and that could potentially see your connection strings. Don't do that. You might accidentally put it into source control, and that's a big issue. Um so don't do that. Don't use production resources locally. It's just too easy to let those slip out in some way. Next up, do not give AI full access to GitHub. Again, I've told you put AI in a container and run a container. Well, give it a personal access token. Okay. Don't give it a full token, give it access to just what it needs in GitHub. Because again, if you give it full access, if you get your access to GitHub, if it's using your access on your machine, well, you have access to go look at user secrets potentially or change user secrets. That's a problem. Like there are GitHub secrets that it could access or use in a way that you don't want it to use. Don't do that. Don't give it full access to GitHub. Use a personal access token and limit that, restrict that. Next up, use containers for all local development resources as much as possible. So for instance, I used to install SQL Server on my development machine. I use it so often, I'm like, well, this is what you do. You install it locally because I don't want to work across a network somehow. And yes, you can use local DB or something like that, but it was just easy to install SQL Server. I haven't done that in years because I use containers. I can spin up a SQL Server in minutes and have it running. I have a SQL Server, I have a MongoDB server, I have a RavenDB server, I have uh Azure, I have a whole bunch of different servers running when I need them to. And when I don't need them to, I shut them down. This isolates them. It also makes them very easy to dispose and restart. This is something you want to do. Get used to using containers, use them over and over again, but then throw them away when you don't need them anymore and start over. Containers are amazing. They make your system run faster, but you're not running SQL Server in the background, taking up lots of memory for no reason. So it makes your system faster, but it also makes it easier to reset things and start over. So as a developer, you shouldn't be directly accessing production systems or resources. Keep that separation clear. Otherwise, a mistake locally can damage or destroy your production systems. Instead, use local resources with throwaway credentials for local development. Even then, keep your AI tools and agents away from your development machine itself. Keep them segmented into containers or virtual machines so they cannot find elevated permissions in a credential hunt. They're gonna try at some point, just protect yourself. All right. Thanks for listening. As always, I am Tim Corey.