Secrets on source code: don’t!

2 minute read

MicroK8S photo by Ian Tuck

What is a secret

A secret can be any sensitive data that we want to keep private. In the context of software development, secrets generally refer to digital authentication credentials that grant access to services, systems and data. These are most commonly API keys, usernames and passwords, security certificates and other types of configuration files.

Why so many secrets

Some years ago, the prevalent paradigm to build applications and services was the Multi-tier architecture and, more specifically, the Three-tier architecture, which is a client-server software architecture pattern made of three components:

  • Presentation tier: User Interface, mostly a Web applications
  • Application tier: functional process logic, aka. business rules, typically embodied embodied as an application server.
  • Data tier: data persistence mechanisms as databases.

Although there exists a lot of applications developed using that n-tier paradigm, with the advent of the micro-services and cloud-native architectures there has been an explosion on the number of components used by the current services, as they break up those monoliths: cloud infrastructure, platforms, SaaS, service meshes, proxies, load balancers, etc. and therefore a huge increase in the number of secrets needed to tie together these different building blocks.

Accessibility vs. security

Because these secrets tie together each component of an application, developers need access to these secrets to build, connect, deploy and test applications. This creates a dilemma because secrets are extremely sensitive, yet they need to be accessible to other developers, applications and infrastructure.

Handling this dilemma needs often complex secrets management systems and policies, but keeping secrets encrypted and tightly wrapped makes it harder for developers to both access and distribute them, so it is quite common that they (we :smiley:) end up hardcoding them into source code and storing them on our laptop and on the version control system. The danger of this may not immediately be apparent as all these systems still have some level of access control, but once secrets start to enter different systems you lose both:

  • Control over where your secrets end up and who has access.
  • Visibility over where your secrets are.

That code could be shared in a message, uploaded into a git repository, cloned onto multiple different professional and personal workstations, forked into a different project, included inside a package manager and ultimately could end up accessible to a malevolent actor.

Preventing dissemination of secrets

The prevention of secret disseminations is based on:

  1. Implementation of policies and best practices when handling secrets
  2. Fine grain visibility into systems and services
  3. Enforcement of policies and practices
  4. Secure storage of secrets

The three first points are about, creating policies around the handling of secrets and using coding best practices are important steps in combatting the dissemination of secrets, but these are useless if not enforced by the CI/CD system, the detection of secrets should be part of the CI/CD pipeline to detect and reject any commit that contains any secret. There are open source tools to automate this task, i.e. [1], [2].

The fourth point involves the deployment of a service to store your secrets in a secure location and wrap it with tight access control. The need of this system really differs between projects. What is important is that your secrets remain encrypted at rest and in transit. There are some well-known systems that can help with this task: Jenkins secrets, AWS secrets manager or Hashicorp Vault.