<p>Ok.. so, we have Google Secret Manager on GCP, AWS Secret Manager in AWS, Key Vault in Azure... and so on.</p>
<p>Those services give you libs so you can code the way your software will access the secrets there. They all look straightforward and sort of easy to implement. Right?</p>
<p>For instance, using Google SM you can like:</p>
<pre><code>from google.cloud import secretmanager
client = secretmanager.SecretManagerServiceClient()
request = {&quot;name&quot;: f&quot;projects/&lt;proj-id&gt;/secrets/mysecret/versions/1&quot;}
response = client.access_secret_version(request)
payload = response.payload.data.decode(&quot;UTF-8&quot;)
</code></pre>
<p>and you're done.</p>
<p>I mean, if we talk about K8S, you can improve the code above by reading the vars from a configmap where you may have all the resources of your secrets, like:</p>
<pre><code>apiVersion: v1
kind: ConfigMap
metadata:
  name: myms
  namespace: myns
data:
  DBPASS: projects/&lt;proj-id&gt;/secrets/mysecretdb/versions/1
  APIKEY: projects/&lt;proj-id&gt;/secrets/myapikey/versions/1
  DIRTYSECRET: projects/&lt;proj-id&gt;/secrets/mydirtysecret/versions/1
</code></pre>
<p>And then use part of the code above to load the vars and get the secrets from the SM.</p>
<p>So, when I was looking the <em>interwebs</em> for best practices and examples, I found projects like the below:</p>
<ol>
<li><a href="https://github.com/GoogleCloudPlatform/secrets-store-csi-driver-provider-gcp" rel="nofollow noreferrer">https://github.com/GoogleCloudPlatform/secrets-store-csi-driver-provider-gcp</a></li>
<li><a href="https://github.com/doitintl/secrets-init" rel="nofollow noreferrer">https://github.com/doitintl/secrets-init</a></li>
<li><a href="https://github.com/doitintl/kube-secrets-init" rel="nofollow noreferrer">https://github.com/doitintl/kube-secrets-init</a></li>
<li><a href="https://github.com/aws-samples/aws-secret-sidecar-injector" rel="nofollow noreferrer">https://github.com/aws-samples/aws-secret-sidecar-injector</a></li>
<li><a href="https://github.com/aws/secrets-store-csi-driver-provider-aws" rel="nofollow noreferrer">https://github.com/aws/secrets-store-csi-driver-provider-aws</a></li>
</ol>
<p>But those projects don't clearly explain what's the point of mounting my secrets as files or env_vars..</p>
<p>I got really confused, maybe I'm too newbie on the K8S and cloud world... and that's why I'm here asking, maybe, a really really dumb questions. Sorry :/</p>
<p>My questions are:</p>
<ol>
<li>Are the projects, mentioned above, recommended for old code that I do not want to touch? I mean, let's say that my code already use a env var called DBPASS=mypass and I would like to workaround it so the value from the DBPASS env would be <em>hackinjected</em> by a value from a SM.</li>
<li>The implementation to handle a secret manager is very hard. So it is recommended to use one of the solutions above?</li>
<li>What are the advantages of such injection approach?</li>
</ol>
<p>Thx a lot!</p>

<p>There are many possible motivations why you may want to use an abstraction (such as the CSI driver or sidecar injector) over a native integration:</p>
<ul>
<li><p><strong>Portability</strong> - If you're multi-cloud or multi-target, you may have multiple secret management solutions. Or you might have a different secret manager target for local development versus production. Projecting secrets onto a virtual filesystem or into environment variables provides a &quot;least common denominator&quot; approach that decouples the application from its secrets management provider.</p>
</li>
<li><p><strong>Local development</strong> - Similar to the previous point on portability, it's common to have &quot;fake&quot; or fakeish data for local development. For local dev, secrets might all be fake and not need to connect to a real secret manager. Moving to an abstraction avoids error-prone spaghetti code like:</p>
<pre class="lang-js prettyprint-override"><code>let secret;
if (process.env.RAILS_ENV === 'production') {
  secret = secretmanager.access('...')
} else { 
  secret = 'abcd1234'
}
</code></pre>
</li>
<li><p><strong>De-risking</strong> - By avoiding a tight coupling, you can de-risk upstream API changes in an abstraction layer. This is conceptual similar to the benefits of microservices. As a platform team, you make a guarantee to your developers that their secret will live at <code>process.env.FOO</code>, and it doesn't matter <em>how</em> it gets there, so long as you continue to fulfill that API contract.</p>
</li>
<li><p><strong>Separate of duties</strong> - In some organizations, the platform team (k8s team) is separate from the security team, is separate from development teams. It might not be realistic for a developer to ever have direct access to a secret manager.</p>
</li>
<li><p><strong>Preserving identities</strong> - Depending on the implementation, it's possible that the actor which accesses the secret varies. Sometimes it's the k8s cluster, sometimes it's the individual pod. They both had trade-offs.</p>
</li>
</ul>
<hr />
<p>Why might you <em>not</em> want this abstraction? Well, it adds additional security concerns. Exposing secrets via environment variables or via the filesystem makes you subject to a generic series of supply chain attacks. Using a secret manager client library or API directly doesn't entirely prevent this, but it forces a more targeted attack (e.g. core dump) instead of a more generic path traversal or env-dump-to-pastebin attack.</p>
