<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">
	<channel>
		<title>Hiding Secrets in a Vault | Infinum</title>
		<atom:link href="https://infinum.com/blog/hiding-secrets-in-vault/feed/" rel="self" type="application/rss+xml" />
		<link>https://infinum.com/blog/hiding-secrets-in-vault/</link>
		<description>Building digital products</description>
		<lastBuildDate>Thu, 16 Apr 2026 11:27:35 +0000</lastBuildDate>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>

					<item>
				<image>
					<url>7942https://infinum.com/uploads/2017/02/hiding-secrets-in-vault-0.webp</url>
				</image>
				<title>Hiding Secrets in a Vault</title>
				<link>https://infinum.com/blog/hiding-secrets-in-vault/</link>
				<pubDate>Tue, 19 Jul 2016 19:35:00 +0000</pubDate>
				<dc:creator>Stjepan Hadjić</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/hiding-secrets-in-vault/</guid>
				<description>
					<![CDATA[<p>Every application needs configuration data like database passwords, AWS access keys, and social app IDs before it can run.</p>
<p>The post <a href="https://infinum.com/blog/hiding-secrets-in-vault/">Hiding Secrets in a Vault</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-213"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-92">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-95"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-93">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-94'
	>
	Every application needs configuration data like database passwords, AWS access keys, and social app IDs before it can run.<br>What’s the easiest way to do it? Hardcode those values, push them to Git and everyone who has a copy of the source code can run the application. The only problem is, you don’t want the whole world to know your usernames and passwords.<br>They need to be kept <strong>secret</strong>. They need to be kept <strong>safe</strong>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-98"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-96">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-97'
	>
	Point III. of the <a href="http://12factor.net/config">12-factor</a> methodology calls for a <strong>strict separation of configuration from code</strong>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-101"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-99">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-100'
	>
	This means removing your database configuration and similar files from version control and copying them directly to your server and CI. That, I don’t need to tell you, is a tedious job. Additionally, this approach is highly prone to errors and makes it harder to collaborate with other developers. You and all your collaborators need to remember to update configuration files everywhere.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-104"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-102">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-103'
	>
	Having multiple environments (such as production, staging, and acceptance) with different configuration files makes this even more difficult.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-107"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-105">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-106'
	>
	<a href="http://www.heroku.com/">Heroku</a> solved this problem through its <a href="https://devcenter.heroku.com/articles/getting-started-with-ruby#define-config-vars">config</a> setup. All configuration files can be set with <code>heroku config:set</code> independently for each environment.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-110"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-108">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-109'
	>
	If you have your own servers like us, Heroku’s strategy of using environment variables won’t work as easily. This is where <a href="https://www.vaultproject.io/">Vault</a> comes into play. We use HashiCorp’s Vault to store and retrieve our secrets.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-113"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-111">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-112'
	>
	12-factoring it up</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-116"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-114"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-115">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2017/02/hiding-secrets-in-vault-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="587"
															width="1000"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-119"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-117">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-118'
	>
	We use Rails for web development. Luckily, there are a couple of gems that handle the setup of application environment variables. We agreed on using&nbsp;<a href="https://github.com/laserlemon/figaro" target="_blank" rel="noreferrer noopener">Figaro</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-122"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-120">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-121'
	>
	The easiest and least error-prone way to do it is moving all your secrets to the <code>config/secrets.yml</code> file. There you can list all application secrets and make them use environment variables. Here’s an example:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-124"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6a737d;">#</span><span class="token" style="color: #6a737d;"> config/secrets.yml</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #d73a49;">default</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&amp;</span><span class="token" style="color: #d73a49;">default</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">secret_key_base</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">%=</span><span class="token"> </span><span class="token" style="color: #005cc5;">Figaro</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">env</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">secret_key_base</span><span class="token" style="color: #d73a49;">!</span><span class="token"> </span><span class="token" style="color: #d73a49;">%</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">database_name</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">%=</span><span class="token"> </span><span class="token" style="color: #005cc5;">Figaro</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">env</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">database_database</span><span class="token" style="color: #d73a49;">!</span><span class="token"> </span><span class="token" style="color: #d73a49;">%</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">database_username</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">%=</span><span class="token"> </span><span class="token" style="color: #005cc5;">Figaro</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">env</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">database_username</span><span class="token" style="color: #d73a49;">!</span><span class="token"> </span><span class="token" style="color: #d73a49;">%</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">database_password</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">%=</span><span class="token"> </span><span class="token" style="color: #005cc5;">Figaro</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">env</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">database_password</span><span class="token" style="color: #d73a49;">!</span><span class="token"> </span><span class="token" style="color: #d73a49;">%</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">database_host</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">%=</span><span class="token"> </span><span class="token" style="color: #005cc5;">Figaro</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">env</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">database_host</span><span class="token" style="color: #d73a49;">!</span><span class="token"> </span><span class="token" style="color: #d73a49;">%</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">bugsnag_api_key</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">%=</span><span class="token"> </span><span class="token" style="color: #005cc5;">Figaro</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">env</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">bugsnag_api_key</span><span class="token" style="color: #d73a49;">!</span><span class="token"> </span><span class="token" style="color: #d73a49;">%</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">devise_secret_key</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">%=</span><span class="token"> </span><span class="token" style="color: #005cc5;">Figaro</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">env</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">devise_secret_key</span><span class="token" style="color: #d73a49;">!</span><span class="token"> </span><span class="token" style="color: #d73a49;">%</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">development</span><span class="token">:</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">*</span><span class="token" style="color: #d73a49;">default</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">test</span><span class="token">:</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">*</span><span class="token" style="color: #d73a49;">default</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">staging</span><span class="token">:</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">*</span><span class="token" style="color: #d73a49;">default</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">production</span><span class="token">:</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">*</span><span class="token" style="color: #d73a49;">default</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">aws_access_key_id</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">%=</span><span class="token"> </span><span class="token" style="color: #005cc5;">Figaro</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">env</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">aws_access_key_id</span><span class="token" style="color: #d73a49;">!</span><span class="token"> </span><span class="token" style="color: #d73a49;">%</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">aws_secret_access_key</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">%=</span><span class="token"> </span><span class="token" style="color: #005cc5;">Figaro</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">env</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">aws_secret_access_key</span><span class="token" style="color: #d73a49;">!</span><span class="token"> </span><span class="token" style="color: #d73a49;">%</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">aws_region</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">%=</span><span class="token"> </span><span class="token" style="color: #005cc5;">Figaro</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">env</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">aws_region</span><span class="token" style="color: #d73a49;">!</span><span class="token"> </span><span class="token" style="color: #d73a49;">%</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">aws_bucket</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">%=</span><span class="token"> </span><span class="token" style="color: #005cc5;">Figaro</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">env</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">aws_bucket</span><span class="token" style="color: #d73a49;">!</span><span class="token"> </span><span class="token" style="color: #d73a49;">%</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-127"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-125">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-126'
	>
	<strong>PROTIP:</strong> By using Figaro’s bang methods we make sure all environment variables are set. If an environment variable is not set it will throw a <code>Figaro::MissingKey</code> error.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-130"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-128">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-129'
	>
	With the <code>secrets.yml</code> file all ready, we created three Figaro config files: <code>config/application.yml</code>, <code>config/application.staging.yml</code> and <code>config/application.production.yml</code> and remembered to add those files to <code>.gitignore</code>. Here&#8217;s an example of a config file: </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-132"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6a737d;">#</span><span class="token" style="color: #6a737d;"> config/application.yml</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">secret_key_base</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">05</span><span class="token" style="color: #005cc5;">d822712453f3433298f3</span><span class="token" style="color: #d73a49;">...</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">devise_secret_key</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">682</span><span class="token" style="color: #005cc5;">a7bd0fefc30d2fda448062ccd828d3f13</span><span class="token" style="color: #d73a49;">...</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">database_username</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">postgres</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">database_password</span><span class="token">:</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">database_host</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">localhost</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">bugsnag_api_key</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&amp;</span><span class="token" style="color: #6a737d;">#</span><span class="token" style="color: #6a737d;">8217;5780d02c163...&amp;#8217;</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">development</span><span class="token">:</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">database_name</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">application_dev</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">test</span><span class="token">:</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">database_name</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">application_test</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-135"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-133">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-134'
	>
	And here’s an example of how to actually use those secrets:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-137"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6a737d;">#</span><span class="token" style="color: #6a737d;"> config/database.yml</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #d73a49;">default</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&amp;</span><span class="token" style="color: #d73a49;">default</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">adapter</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">postgresql</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">encoding</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">unicode</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">pool</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">5</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">database</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">%=</span><span class="token"> </span><span class="token" style="color: #005cc5;">Rails</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">application</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">secrets</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">database_name</span><span class="token"> </span><span class="token" style="color: #d73a49;">%</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">username</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">%=</span><span class="token"> </span><span class="token" style="color: #005cc5;">Rails</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">application</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">secrets</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">database_username</span><span class="token"> </span><span class="token" style="color: #d73a49;">%</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">password</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">%=</span><span class="token"> </span><span class="token" style="color: #005cc5;">Rails</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">application</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">secrets</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">database_password</span><span class="token"> </span><span class="token" style="color: #d73a49;">%</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">host</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">%=</span><span class="token"> </span><span class="token" style="color: #005cc5;">Rails</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">application</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">secrets</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">database_host</span><span class="token"> </span><span class="token" style="color: #d73a49;">%</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">development</span><span class="token">:</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">*</span><span class="token" style="color: #d73a49;">default</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">test</span><span class="token">:</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">*</span><span class="token" style="color: #d73a49;">default</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">production</span><span class="token">:</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">*</span><span class="token" style="color: #d73a49;">default</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">staging</span><span class="token">:</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #d73a49;">*</span><span class="token" style="color: #d73a49;">default</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-140"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-138">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-139'
	>
	Sharing secrets</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-143"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-141">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-142'
	>
	Now that our application is all 12-factored up, we need a way to share environment variables between developers and servers. Remember, we added <code>application.*.yml</code> files to <code>gitignore</code> so they don&#8217;t end up in the repository. No one has access to those files except for the person who wrote them. We are using Vault for sharing those files. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-146"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-144">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-145'
	>
	Here&#8217;s a summary of what <a href="https://www.vaultproject.io/" target="_blank" rel="noreferrer noopener">Vault</a> does:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-149"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-147">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-148'
	>
	<li>Vault secures, stores, and tightly controls access to tokens, passwords, certificates, API keys, and other secrets in modern computing.</li><li>Vault handles leasing, key revocation, key rolling, and auditing.</li><li>Vault presents a unified API to access multiple backends: HSMs, AWS IAM, SQL databases, raw key/value, and more.</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-152"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-150">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-151'
	>
	Basically, it is an all-in-one solution for storing your critical information somewhere safe.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-155"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-153">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-154'
	>
	After setting up Vault on a separate server, we configured it to use <a href="https://www.consul.io/">consul.io</a> as a backend. For authentication backends we are using <code>github</code> and <code>app-id</code> methods. A <code>simple file system</code> is used for an audit backend. You can look into <a href="https://www.vaultproject.io/docs/index.html">Vault’s documentation</a> for more information.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-158"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-156">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-157'
	>
	As we have hundreds of projects under our belt, naming conventions are a must if we want our developers to know where the secrets are stashed. We agreed on <code>rails/#{git_repository_name}/#{environment}</code> for a path to store secrets within Vault. We are using the Git repository name here as a part of the path because that isn&#8217;t something that ever changes, so everyone knows the location of the secrets. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-161"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-159">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-160'
	>
	Next, a policy needs to be created to give someone writing and/or reading privileges on a specific Vault path. Here&#8217;s an example of such a policy: </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-163"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-shellscript github-light" data-language="shellscript" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6f42c1;">path</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">rails/application/*</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> </span><span class="token" style="color: #032f62;">{</span><span class="token">
</span></span><span class="line"><span class="token">   </span><span class="token" style="color: #6f42c1;">policy</span><span class="token"> </span><span class="token" style="color: #032f62;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">write</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">}
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-166"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-164">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-165'
	>
	As Vault is easily <a href="https://www.vaultproject.io/docs/auth/github.html">integrated with GitHub</a>, we are using GitHub teams to apply different application policies to users. Simply create a new GitHub team, add all needed users, and link the Vault policy to that team. This has an added benefit of only having to remove someone from your GitHub organization in order to revoke their access to all secrets. This can come in handy when someone leaves the company.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-169"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-167"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-168">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2017/02/hiding-secrets-in-vault-2.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1000"
															width="682"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-172"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-170">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-171'
	>
	Except to users, we also need to grant access to servers and CI clients. We use what Vault calls <a href="https://www.vaultproject.io/docs/auth/app-id.html">app-id authentication</a>. App-id authentication uses two strong keys to authenticate a Vault server. We give our machines read-only access to secrets within Vault.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-175"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-173"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-174">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2017/02/hiding-secrets-in-vault-3.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1000"
															width="918"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-178"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-176">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-177'
	>
	Real world usage</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-181"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-179">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-180'
	>
	As I mentioned before, Vault has no web interface, and its command line tool has a steep learning curve. We mitigated that problem by creating our own <a href="https://github.com/infinum/secrets_cli">secrets gem</a>. It uses the official <a href="https://github.com/hashicorp/vault-ruby">Vault Ruby gem</a> and is built around the requirements described above.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-184"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-182">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-183'
	>
	It has a couple of simple commands:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-186"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-shellscript github-light" data-language="shellscript" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6f42c1;">$</span><span class="token"> </span><span class="token" style="color: #032f62;">secrets</span><span class="token"> </span><span class="token" style="color: #032f62;">init</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-189"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-187">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-188'
	>
	This will create a .secrets file with the project configuration. The command will ask for everything you don’t supply via options.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-192"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-190">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-191'
	>
	Here’s an example of a .secrets file:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-194"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-ruby github-light" data-language="ruby" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6a737d;">#</span><span class="token" style="color: #6a737d;"> file where your secrets are kept depending on your environment gem</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #005cc5;">:</span><span class="token" style="color: #005cc5;">secrets_file</span><span class="token">:</span><span class="token"> config</span><span class="token" style="color: #d73a49;">/</span><span class="token">application</span><span class="token">.</span><span class="token" style="color: #6f42c1;">yml</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6a737d;">#</span><span class="token" style="color: #6a737d;"> vault &amp;#8217;storage_key&amp;#8217; where your secrets will be kept</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #005cc5;">:</span><span class="token" style="color: #005cc5;">secrets_storage_key</span><span class="token">:</span><span class="token"> rails</span><span class="token" style="color: #d73a49;">/</span><span class="token">my_project</span><span class="token" style="color: #d73a49;">/</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-197"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-195">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-196'
	>
	And if you set up your environment variables correctly you can push and pull secrets:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-199"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-shellscript github-light" data-language="shellscript" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6f42c1;">$</span><span class="token"> </span><span class="token" style="color: #032f62;">secrets</span><span class="token"> </span><span class="token" style="color: #032f62;">push</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">$</span><span class="token"> </span><span class="token" style="color: #032f62;">secrets</span><span class="token"> </span><span class="token" style="color: #032f62;">pull</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-202"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-200">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-201'
	>
	This can also be set up on a server, so your deployment scripts pull secrets on every deployment. We use <a href="https://github.com/mina-deploy/mina">mina</a> for our deployment purposes, and we created a <a href="https://github.com/infinum/mina-secrets">mina-secrets</a> plugin which simplifies our deployment with secrets.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-205"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-203">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-204'
	>
	Conclusion</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-208"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-206">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-207'
	>
	So there it is, our approach to building a production-grade, scalable system for managing secrets. Using Vault makes the system secure. Using Github for the authentication makes it convenient for managing access. And using the <code>secrets</code> gem makes sharing secrets quick and dead simple for developers. Don’t sacrifice security for the sake of convenience any more.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-211"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-209">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-210'
	>
	Hope you enjoy using it.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/hiding-secrets-in-vault/">Hiding Secrets in a Vault</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
		
	</channel>
</rss>