Posted on January 2, 2015 by

Configuration in the Environment

Moving Fast published this article, regarding the danger of using the environment to store secrets. I think that every time is a good time to re-evaluate design choices with security implications. So that’s what I’m doing here.

My previous post focused specifically on the security implications of storing keys in your code repository. This was a particularly harmful situation with a client project I had joined. But as I think about it a little more, security isn’t the reason I use the environment to store configuration. Security is simply a byproduct. The reasons I use the environment in my company are:

1. When bringing up a new contractor or employee, I simply generate an IAM role and a key to our internal API. I plug those into the “Developer” environment IDE config file, and the new developer is up and running.

2. It’s easy to move developers between environments. We are writing V2 of our internal API as I write this. Its really quick to change your environment to build features in V2, or fix bugs in V1.

3. It felt much quicker to have a config.py pull from the environment than to parse command line parameters for our large number of configuration options or to add a dependency for an ini parser.

Reading this short list, there is really nothing here that forces us to use the environment. A config file would be just fine. Maybe I should think about that.

What concerns should I examine?

My application servers have 3 user accounts: nobody, alembic deploy user, root.

That’s it. Access to any one of those three accounts would give an attacker access to our secret keys and database. It wouldn’t matter if the configuration values were in the environment or a file. An attacker could read secrets from disk or from memory. So I don’t really gain or lose anything from using the environment instead of a config file.

My application starts up with an environment set, and reads the values from the environment into config variables.

Not only could this be done with a config file, that’s what is actually happening. The environment parameters are still stored on disk. When the server reboots, it reads the file, sets up the environment, and launches the application. So the “environment” part is simply a mirror of the setup on the developer’s system to keep production and development code consistent. So I may have the downside of both designs from a security perspective.

Very low probability of adding new config options.

When we do add a new environment config, it’s ok that it isn’t an automated process. It doesn’t happen frequently so having to redeploy our configuration manually isn’t a problem.

What do I gain from using the environment?

I don’t run the risk of a developer accidentally checking in their config file. However, if that did happen I would only have to reset their IAM credentials and internal API key.

What do I gain from using a config file?

I may only be gaining “not using the environment”. I think a successful attack on our system would happen regardless of how we stored our secrets.

Conclusions

Well I’m not sure. The Moving Fase article helped me, because we aren’t cleaning up the application environment after setting the config variables. So that is a security enhancement I will make. Other than that, I don’t think changing from the environment to a config file would give much benefit in a security or functionality sense.

Posted on August 23, 2014 by

Keep Private Data Out Of Your Repository

Did you know that Amazon crawls public repositories on Github looking for secret keys? Neither did I. Neither did the ex-contractor that pushed my client’s code base into his public repo to boost his Github profile. There is nothing like a security breach email from Amazon that helps you sell a proper release process to your client. During the prototype, or MVP, things move very quickly. You get the app up and running, start adding features, and start bringing in external resources to help build your product. It’s pretty easy to skip some basic security principles.

Keep private data in the environment, not the config file

If you keep API tokens and AWS access keys hardcoded in a config file, then you are distributing those keys to every person who requires access to your code base. Instead, load that config data from the application environment. This not only keeps your data secure, but it makes it easier to setup a Production/Staging/Development release system.

Create Separate Repositories

So much easier said than done, I know. But do the frontend designers need to have access to your backend code? Is the new contractor working on a feature that could be decoupled from your primary application? This is not just a security measure. If your application is properly decoupled, then you have an easier time making changes without breaking the system.

So product managers beware! Proper devops may seem like an expense to push off until later. But really, making sure your application is easy to deploy will increase security, reduce ramp up time for new developers, and help stabilize your application.

Posted on August 19, 2014 by

The Wrong Problems

Developers spend most of the day working on one, or maybe two, codebases. They run into the same day-to-day problems that all other developers do. They come up with solutions that most other developers will also come up with. They implement these solutions, and try to publicize them. If they are lucky, their solution will be the one that the community rallies around.

This is why every language has a ton of web frameworks. Every language has lots of options for devops tools. There are dozens of websites with video tutorials on Python, Ruby, Java, AngularJS, Node, Go, and everything else. More and more will emerge. Even though we all try to avoid reinventing the wheel, we only see so many problems a day. Those are the problems we try to solve.

But what if they’re the wrong problems. What if people in the offices right next door would pay lots of money to automate some Windows tasks. What if independent shops in the warehouse district would pay for a small scale inventory tracker. What if we could make real differences in the live’s of people surrounding us. What if we didn’t have to scale, or count eyeballs, or have traction, or raise money, or show growth in order to have a business with a positive affect on the community.

What if Process Management Consulting is the most interesting field, because you see the widest range of problems to solve?

Posted on August 11, 2014 by

Lose The Employee Mentality

I still haven’t done this. I run into problems in almost every project because of it. I think a very long winded discussion about this basically boils down to:

Employees need skills. Businesses need successes.

Employees hand a resume to a company that has a list of skills on it; programming languages, frameworks, databases, other technical achievements. Employees are evaluated on how well they preform a task, not how well their past projects have gone. This is why candidates for a development position go through coding interviews. They don’t have strategy brainstorming sessions about how to improve their last project.

Businesses need successes. As a freelancer, you are a business. If you walk away from a project with nothing more than another notch on your resume, then you have to really ask what you gained from the project. Money disappears. Technology gets out of date really fast.

You need to walk away from a project with another win for your portfolio. A business needs to show clients that there is money to be made in this relationship. Your clients should do business with you because you helped previous clients achieve their goals.

This has nothing to do with Python, Hadoop, Node, or any other technical skill. This is all about your business improving the bottom line of your client’s business. All your previous successes prove you have whatever skills are necessary to do that.

Posted on July 30, 2014 by

Log Errors to Github

Log files are great, but why not make errors front and center in your issue tracker. One thing I like to do is automatically log errors to Github. That way when something goes wrong, it is right in my face.

class GithubError(logging.Handler):
    def __init__(self, token, repo_owner, repo):
        logging.Handler.__init__(self)
        self.token = token
        self.repo_owner = repo_owner
        self.repo = repo
 
    def log_issue(self, title, body):
        from github3 import login
 
        gh = login(token=self.token)
        if gh is None:
            app.logger.warning('Could not login to Github!')
            return
 
        repo = gh.repository(self.repo_owner, self.repo)
 
        try:
            issue = repo.create_issue(title, unicode(body), self.repo_owner)
        except Exception as e:
            app.logger.warning(e)
 
    def emit(self, record):
        import traceback
 
        title = 'Auto-reported Bug'
        if record.exc_info is not None:
            # If we are passed traceback information, format it nicely
            tb = traceback.format_tb(record.exc_info[2])
            body = unicode('\n'.join(tb))
        else:
            # Otherwise just include the error and some meta
            body = u'{}:{}\n{}'.format(record.pathname, record.lineno, record.msg)
 
        self.log_issue(title, body)

This class extends logging.Handler, which lets use it as a handler in Flask’s logging system. The emit method is passed a logRecord object that can be examined for useful information to pass to Github.

To hook the GithubError class into Flask’s logger, you want to run some code before the first request.

@app.before_first_request
def setup_logging():
    if not app.debug:
      import logging
      from logging import StreamHandler
 
      handler = StreamHandler(sys.stdout)
      app.logger.addHandler(handler)
      app.logger.setLevel(logging.INFO)
 
      if app.config['GITHUB_USER'] is not None and app.config['GITHUB_PASS'] is not None:
          gh_handler = GithubError(app.config['GITHUB_TOKEN'],
              app.config['GITHUB_USER'],
              app.config['GITHUB_REPO'])
          gh_handler.setLevel(logging.ERROR)
          app.logger.addHandler(gh_handler)

If Flask is running in debug mode, then there is no reason to send anything off to Github. This is really for production mode only.

Newer Posts
Older Posts