Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Garet's avatar
Level 3

Application configuration in file or in database?

With a couple of Laravel apps that I've built, I've created a settings screen where the user can modify the configuration of the application via a GUI. Generally I also build in a permissions system which allows users access to different parts of the app, so the settings area would require the user to have the appropriate permission to access.

Settings include various things like notification email addresses, the default number of results to paginate by, the default date format, etc. If the app is linked up to a service such as MailChimp then it would contain the MailChimp API credentials.

I see that most people tend to include such settings in configuration files. I just wondered whether there is any downside to storing them in the database and providing access to them via an interface in the app? This seems to be much more user friendly if someone wants to change a setting and doesn't have the technical knowledge/ability to edit a config file.

Obviously doing it this way encourages a degree of "tinkering", but as I mentioned users need to be assigned the correct permission to access the settings screen, so it's not something that all users would be given the ability to do.

Any downsides to this approach?

0 likes
10 replies
Jaytee's avatar

You could theoretically update the configuration files in production. But you'll need to break the cache each time too (e.g: php artisan config:cache) unless updating the config does it automatically.

What you have is fine to be honest. If I were to ever do this, I would have a settings table or something, which is just a key value pair. Then pull from that table to get the value.

But, as for sensitive information like API credentials. Not the best idea to store in the database, for security reasons.

Take a look at this old question here. As you can see, they update the config for secure values: https://stackoverflow.com/questions/56624117/laravel-5-2-dynamic-environment-variables-based-on-user

And there's also a settings package which is key/value. Can use database or a JSON file: https://github.com/akaunting/setting

Garet's avatar
Level 3

Thanks for your reply @jaytee

Yes, I have a settings model and controller with a database table of key value pairs. Furthermore I specify a field type for each setting, so a setting can be a text box, number input, checkbox, etc.

I then have a settings service provider which retrieves the key value pairs from the database table, caches the results of the query, and then does:

Config::set('settings', $settings);

The above still seems to work even after doing php artisan config:cache in production.

Good call on the API credentials. It's got me thinking that especially where there are two sets of API credentials, sandbox and production, it would be better for these to go in the .env file.

Jaytee's avatar

As long as the API credentials aren't stored in the database in plain text, it's fine. .env ends up being cached into a config file, so you can store API credentials in config.

Garet's avatar
Level 3

Out of interest what's wrong with storing the API credentials in the DB in plain text? If they are cached into a config file then they would presumabely be in plain text in the file?

Thanks!

Jaytee's avatar

Well, take for example, you stored a user's Stripe credentials in the database. What if that database is compromised? The credentials for that user's Stripe account is then exposed. I could use those keys to gain access to their account, and potentially withdraw money.

API public keys would be fine, but secret keys wouldn't. Generally credentials come with both of these, so it makes sense to store them together rather than one in a secure location, and the other in a database.

When a laravel application goes into production, the only folder that is publicly accessible is the public folder, therefore the config files can't be accessible since it's not in the public folder.

Garet's avatar
Level 3

Isn't the database containing the API details and being compromised the same end result as the API details being in a config file and the web server being compromised? Otherwise this assumes that the database server could be compromised but the web server is immune.

I'm not trying to be argumentative, just trying to better my understanding. As it happens I'm going to move the API details to the .env file.

Thanks

Jaytee's avatar

I knew that question was coming, so it's fine.

So. Before I begin, I need to correct something from a previous reply, in case people understand it the wrong way. Storing sensitive API credentials should be done in the .env file, and not in the config file directly.

And also, I'm not an expert on this either, so to anyone who is reading this, feel free to correct me if I make a mistake.

So for example, don't do the following:

return [
    'secret' => 'sakljdaskldjaslkdjasljdasjdl13132'
];

You should instead do:

return [
    'secret' => env('SOME_SECRET_KEY', '')
];

This way, API credentials aren't pushed to source control, since we ignore .env files. And since we only ever want to cache the config files in production, we don't need to worry about that cached config file being exposed due to a commit you made.

Now, if the web server is compromised, then it's game over really. They could potentially have access to everything.

If only the database is compromised for some reason, then only the data within that database is compromised. Or what if you accidentally spat out sensitive data in a view? That would be a vulnerability. Or, perhaps you have a settings page that lists out all settings from the database table, which also happens to have sensitive data; and only admins are allowed access to that page, but then you have a "corrupt" admin or someone gains access to your account etc.

Take a look at these resources. The first is about best practices for databases. The second covers various topics within PHP, including a security section.

https://www.esecurityplanet.com/network-security/6-database-security-best-practices.html https://phptherightway.com/

Jaytee's avatar

Let's start that comment again, because i'm naturally bad at explaining things to start with, but it's also 3:30am in the morning for me.

  1. We don't commit .env files to source control as they often contain sensitive data. When we push to production, we create an .env file on the server, in the root directory of our application, and then copy all of the variables over and assign their values, with production values.

  2. When we run php artisan config:cache, it creates a config.php file in bootstrap/cache directory. In development, we don't cache config files because we often change config values, and if they're cached, it'll mean we need to bust it each time we change a value in order to use the new value. So we only cache in production. Since we use this approach, we also don't commit the config.php file in bootstrap/cache. I believe gitignore also excludes the bootstrap/cache* directory by default, or similar thereof.

  3. It's true, if the web server is compromised, then our data is vulnerable, along with any data stored in the .env or config.php file. So that also means our database would be compromised. This is the worst possible outcome

  4. If the database is compromised and the web server is not, then our sensitive data is still protected. Databases could be exposed via the web server (if access was gained), or because of a stupid mistake like having root as the username and password, which grants full access. It's not hard to get an IP address. In this case, any data in the database is compromised.

So, the moral of the story is, use environment variables in .env to store sensitive data. OR; encrypt sensitive data should it be stored in the database. Our last line of defense is the web server, where this file is stored.

1 like
Sinnbeck's avatar

Also if someone makes a mistake in the code it is possible to allow sql injections that could end up outputting all rows in a table. It is also possible that the sql server can be accessed from the outside directly and thereby be compromised.

Getting access to files outside the public folder should be alot harder (unless again someone dumps config data to the user by mistake) :)

1 like
Garet's avatar
Level 3

OK makes sense, thank you both

Please or to participate in this conversation.