Think roles, not secrets

Amarnath
Technology @ Funding Societies | Modalku
3 min readAug 21, 2019

Secrets are inevitable in modern-day application development. These may include database credentials, IaaS platform key-pairs, API keys of third-party web services or encryption keys for generating access tokens for your own application.

Here are some common problems often associated with managing secrets:

  • Secrets may not be kept encrypted at rest
  • Secrets may be shared without an audit trail
  • Secrets may be long-lived
  • Secrets may give users unlimited privileges (violating the principle of least privilege)

Together, these pose a serious security risk.

A new class of tools has now emerged to deal with these problems: Secrets Management Systems. One such tool is Vault from Hashicorp.

User:Jonathunder / Wikimedia Commons / CC BY-SA 3.0

A secrets-management system nicely complements a configuration management system that is often already employed in a distributed applications/micro-services setup. Here are some of the key features that Vault provides:

  • Secret encryption at rest
  • Path-based access control much like a file system
  • Dynamic secrets

The last feature is the most interesting one and is the main topic of this post. We intuitively think about protecting our secrets and rotating them periodically and that makes sense in cases where it is not easy to automate their regeneration — eg., third-party API keys. However, a different way to look at the same problem is to assign roles to your services instead of configuring them with pre-generated, static credentials.

  • A role is a bag of permissions/grants/privileges
  • A role can be assigned to groups or users or services
  • A group is a collection of users or services
  • A user or a service can assume a permitted role

In this model, as a service author, you think about the permissions that your service needs. You can then formally define these permissions in a say, AWS IAM policy document or a set of PostgreSQL GRANT queries. This privilege manifest can then safely be co-located with your source code and checked in to your SCM server (think GitHub, Gitlab or Bitbucket). (Note: Pushing secrets to your SCM server, on the other hand, is generally considered an anti-pattern)

Vault’s Dynamic Secrets feature reads this privilege manifest and when asked to, generates credentials with the given privileges and a reasonably short time-to-live (expiration). These credentials can then be used by the application to authenticate with a target service (AWS or PostgreSQL or RabbitMQ, say) as it would normally do.

Here is how Dynamic Secrets can be set up with PostgreSQL

In summary, Vault’s Dynamic Secrets offers a novel solution to some of the problems that I listed earlier: Secrets no longer need to be long-lived or shared as they can be generated on-demand.

One topic that we have not talked about here is authenticating with Vault itself i.e. How can a service identify itself with Vault and securely only read the secrets that it has access to?. You can find the different authentication methods supported by Vault here.

--

--