News for hackers. Stuff that matters.
Re:The Twelve-Factor App (2011) by numbsafari on Thursday April 28, 2022 @09:00PM (#31200132)
One thing that I think could be updated in the 12F approach is the use of env vars for config, especially secrets.

I’ve generally found it much better to mount these into the filesystem and read from there. It helps with, for example, secret rotation for long running processes. Relying on process restarts can be ugly in some setups, especially if startup time is expensive.

Re:The Twelve-Factor App (2011) by pjbster on Friday April 29, 2022 @02:51AM (#31202161)
The best approach I've seen is to have the secrets in a vault and to keep the vault URL in an env var (so different vaults can be used for dev and prod, for example). The secrets location within the vault is held in a variable defined in an application config file which is checked in to source control. At runtime, a piece of code consults the variable and queries the vault using the provided location and then dynamically configures the db connection with the returned credentials. The credentials are dumped from memory once the transaction completes.

(I should also point out that this is in a batch ETL system.)

The nice thing about this approach is that it is virtually impossible for secrets to end up in source control. The risk is that the vault becomes a major single point of failure.

Re:The Twelve-Factor App (2011) by Someone on Friday April 29, 2022 @03:12AM (#31202282)
It also makes cycling credentials easy. All you have to do is update the values in the vault. No need to hunt down all those places where you set environment variables.

I think you don’t even need to redeploy any long-running tasks. If they have a connection open, it should continue working, and if they don’t, they should consult the vault when they open one and get the new credentials from it (this may be different for different kinds of credentials)

There will be a race condition between creating credentials and storing them in the vault, but even that can be avoided:

  - create new credentials with same rights as the old ones
  - update vault
  - delete old credentials
Another race where credentials get changed between reading them from the vault and using them can’t be avoided, but if you wait a few minutes before you delete the old credentials, it’s extremely unlikely you’ll hit it.
Re:The Twelve-Factor App (2011) by jteppinette on Friday April 29, 2022 @04:03AM (#31202602)
How does the system authenticate with the vault? Why not use that same system to authenticate the database connection? A vault is only useful at scale or with additional compliance requirements. Otherwise, keep it simple. Very few systems actually need that additional level of indirection.
Re:The Twelve-Factor App (2011) by kureikain on Friday April 29, 2022 @05:34AM (#31203193)
It's usually rely on some globa mechanims by the underlying architecture.

Example, if it's AWS it may rely on ec2 instance role, to allow it access to the secret manager.

If it's kubernetes, it can be done through k8s token mount, basically allow token in namespace access the vault, and the token(which is generated and manage by k8s, which is just a JWT btw) is mounted into your pod.

Re:The Twelve-Factor App (2011) by ivan_gammel on Friday April 29, 2022 @04:33AM (#31202787)
There are often multiple sets of credentials that you need to pass to a microservice, some of which may be shared between multiple instances of the service or even between multiple services. Changing them would require plenty of case-specific updates to service configurations or just one update in the vault. By reducing the amount of work to update the credentials you also reduce security and quality-related risks.
Re:The Twelve-Factor App (2011) by pjbster on Friday April 29, 2022 @04:23AM (#31202726)
I don't know and I don't need to know (I'm a mere dev -- no "ops" in my role). And, yes, this client has very high compliance requirements.
Re:The Twelve-Factor App (2011) by vojtad on Friday April 29, 2022 @03:32AM (#31202412)
Do you have any particular vault in mind? We are looking for a simple solution which would work exactly like you described. We just need couple of different sets of variables for our web server, workers and other services.
Re:The Twelve-Factor App (2011) by pjbster on Friday April 29, 2022 @04:27AM (#31202751)
I'm not sure which vault we're using. There's no identifying information in the server responses. The storage type shows as "Consul" so that suggests Hashicorp Vault.

I'm not the person to ask how to set it up but it's seamless in use and can return data in json format which makes it easy to parse. If it were my money I'd look very hard at this product.

Re:The Twelve-Factor App (2011) by dantelex on Monday May 02, 2022 @05:37AM (#31232936)
I built onboardbase.com for this exact purpose and it has continuously solved a lot of use cases for me personally. There is also hashicorp vault which is amazing as well.
Re:The Twelve-Factor App (2011) by remus on Friday April 29, 2022 @05:39AM (#31203215)
I've used GCP secrets manager and it worked well. Pretty simple API and the option for providing your own encryption keys if you want it.
Re:The Twelve-Factor App (2011) by de6u99er on Friday April 29, 2022 @03:30AM (#31202398)
This is the way!
Re:The Twelve-Factor App (2011) by eriner_ on Thursday April 28, 2022 @10:11PM (#31200584)
I agree completely. Storing secrets in environment variables is wrong: https://blog.forcesunseen.com/stop-storing-secrets-in-enviro...

Even unsetting environment variables leaves them in /proc/self/environ. There isn't a thread-safe way to unset environment variables in POSIX, so even if you `unset TOP_SECRET` from within a program the contents of /proc/self/environ will remain unchanged and available.

Re:The Twelve-Factor App (2011) by josephcsible on Thursday April 28, 2022 @10:13PM (#31200597)
But /proc/*/environ is only readable by the user the process is running as and root, so if you can read it, you're already on the other side of the airtight hatchway.
Re:The Twelve-Factor App (2011) by eriner_ on Thursday April 28, 2022 @10:26PM (#31200695)
Arbitrary file read vulnerabilities are extremely common.
Re:The Twelve-Factor App (2011) by josephcsible on Thursday April 28, 2022 @10:48PM (#31200818)
Sure, but if you have one of them, then you can read the secret files out of /vault or whatever too.
Re:The Twelve-Factor App (2011) by eriner_ on Friday April 29, 2022 @12:12AM (#31201353)
Correct! This is why I explicitly said the following in the blog post I linked above:

> Once the application hits “readiness” status (as determined by health endpoints or the load balancer), the secrets volume should be unmounted and made inaccessible.

Re:The Twelve-Factor App (2011) by metadat on Friday April 29, 2022 @12:25AM (#31201423)
Then I'll just pull it from the processes memory directly. It's security through obscurity at best.
Re:The Twelve-Factor App (2011) by mumblemumble on Friday April 29, 2022 @12:39AM (#31201515)
It seems to me in line with the comment that the post quoted:

> Ultimately, secrets need to live somewhere and need to be accessed as plain text. Just make sure that the access as small window is as [sic] possible, and try to obliterate it after use, if possible.

This is not an all-or-nothing situation; it's a game of mitigation. If the process needs to retain the secret in memory, true, there's not much you can do about that. But I don't think that minimizing where else you're storing it is just security through obscurity. Fewer possible attack vectors is still fewer possible attack vectors.

Re:The Twelve-Factor App (2011) by metadat on Friday April 29, 2022 @01:26AM (#31201753)
Now, if you encrypt them in memory, or even better obtain the creds in an audited fashion, use them and clear the memory promptly, it's slightly better.
Re:The Twelve-Factor App (2011) by Rapzid on Friday April 29, 2022 @03:21AM (#31202339)
Just an arbitrary file read vulnerability away at /proc/$pid/mem
Re:The Twelve-Factor App (2011) by mrslave on Friday April 29, 2022 @05:44AM (#31203255)
I really like my applications to at least try to reestablish dropped connections though. But I do appreciate the minimization mindset with respect to secrets.

The last time I was responsible for the scaffolding of a new software service it supported reading secrets from a file. It confused the operations team and I was just told to include support for an environment variable. Oh well, I tried.

Re:The Twelve-Factor App (2011) by hedora on Thursday April 28, 2022 @11:50PM (#31201197)
Or, if you only have access to proc, from the process's heap.
Re:The Twelve-Factor App (2011) by CameronNemo on Friday April 29, 2022 @03:28AM (#31202389)
How do you actually unmount the volume with kubernetes once the secrets are read and the process is ready? I've never heard of a feature like that.
Re:The Twelve-Factor App (2011) by thinkmassive on Friday April 29, 2022 @08:22AM (#31204220)
From my comment farther below:

> If your app can’t interface directly w/k8s, but it can read secrets from a file, you can use a small init program to fetch the k8s secret and write it to a named pipe. This is advantageous compared to mounting as a volume, because the pipe disappears after both ends close their connection to it.

Re:The Twelve-Factor App (2011) by aliswe on Friday April 29, 2022 @05:02AM (#31203007)
you dont ... you remove the mapping and restart the pod.
Re:The Twelve-Factor App (2011) by emmelaich on Thursday April 28, 2022 @10:48PM (#31200817)
It's the part of 12 factor that makes me giggle a bit; like it how does it get into the environment?

Reminds of the "Front fell off" comic sketch. "No, we towed it out of the environment"

https://www.youtube.com/watch?v=3m5qxZm_JqM

Re:The Twelve-Factor App (2011) by mindcrime on Friday April 29, 2022 @12:21AM (#31201397)
"Well what's out there?"

"Nothing's out there."

"Well there must be something out there."

"There is nothing out there. All there is, is sea, and birds, and fish."

"And?"

"And 20,000 tons of crude oil."

"And what else"?

"And a fire."

"And anything else?"

"And the part of the ship that the front fell off. But there's nothing else out there. It's a complete void."

Re:The Twelve-Factor App (2011) by kortex on Friday April 29, 2022 @12:02AM (#31201280)
It's environment variables all the way down.
Re:The Twelve-Factor App (2011) by arinlen on Friday April 29, 2022 @12:35AM (#31201488)
> One thing that I think could be updated in the 12F approach is the use of env vars for config, especially secrets.

The 12F section on config already mentions quite prominently the use of config files.

Taken from https://12factor.net/config

> "Another approach to config is the use of config files which are not checked into revision control, such as config/database.yml in Rails. This is a huge improvement over using constants which are checked into the code repo, but still has weaknesses: it’s easy to mistakenly check in a config file to the repo; there is a tendency for config files to be scattered about in different places and different formats, making it hard to see and manage all the config in one place. Further, these formats tend to be language- or framework-specific."

Re:The Twelve-Factor App (2011) by infamousjoeg on Thursday April 28, 2022 @10:25PM (#31200686)
Check out the Secretless Broker at https://secretless.io. It's a cool open source project that allows applications to not need to know secrets which adheres to 12-factor app guidelines.
Re:The Twelve-Factor App (2011) by cphoover on Thursday April 28, 2022 @10:44PM (#31200798)
hmmm.... im trying to understand the benefit of secretless broker... if someone compromises thisnwouldnt they have access to all credentials for everything?

now we are just moving from trusting a bunch of distinct services to trusting this single broker... just moving the responsibility of trust to a single point of potential failure no?

Also dont credentials have to be passed to secretless broker? how does it know the application has access to the service? isnt that still at risk of being leaked.

i like the idea of not thinking about secrets but it seems to good to be true.

Re:The Twelve-Factor App (2011) by numbsafari on Friday April 29, 2022 @02:35AM (#31202093)
I’ll have to dig into it to see how it compares, but https://spiffe.io/ is what I look to in this area.

Not having long lived secrets is the ultimate destination, but we all live with the legacy around us.

Re:The Twelve-Factor App (2011) by danenania on Friday April 29, 2022 @01:36AM (#31201804)
EnvKey[1] can help with process reloading, and can facilitate both restarts and hot reload updates. (Disclaimer: I’m the founder.)

The pros/cons of environment variables vs. files (or other approaches) is also something I’ve thought about a lot while working on EnvKey.

We use environment variables as a default approach, since it seems to be the most common way to pass secrets/config to a process in the wild and we want to meet people where they’re at. But we also make it easy to use files or system calls instead (I think system calls are actually the most secure.)

One thing it’s always important to remember though in security: if you make the “secure way” too hard, people will route around it, making matters worse in practice. There’s always a balance to be struck.

Honestly, I’m skeptical that threat models where environments are exposed but files are safe are realistic enough to be worth worrying about. At that point, it seems like rearranging deck chairs on the Titanic.

It seems simpler to say “our last line of defense is the OS boundary.” You trust the host and go from there. If the host is breached, you’re screwed in a plethora of ways. There’s no point in sweating the particulars. Just don’t let it happen in the first place!

And when it comes to concerns about leaking the environment to sub-processes, this seems like a deeper problem. Even if you don’t store secrets in the environment, that doesn’t mean it’s safe to just send env vars off wherever. At this point, like it or not, environments are sensitive, because enough people and programs treat them as sensitive that it’s a self-fulfilling prophecy. If they might be leaked, then the leak is the security problem in my eyes, not the data in the environment.

1 - https://envkey.com

Re:The Twelve-Factor App (2011) by zmmmmm on Friday April 29, 2022 @06:50PM (#31211503)
EnvKey looks great!

Only one thing strikes me as unfortunate, which is it seems like it fragments the development process because now your code history is tracked in git but your config history is in EnvKey. It means everything I do is duplicated (for example, tags, branches etc). It isn't clear to me how I would take, for example common operations such as rebasing one git branch on another and replicate the same on the two EnvKey branches involved.

We track all our non-sensitive config in git for this reason - then merging two branches is literally merging the config changes. However, we don't have any of the nice features EnvKey is doing like service restarting, inheritance, secret management etc.

Just curious if I'm missing something here or you have a strategy for what I discuss above?

Re:The Twelve-Factor App (2011) by danenania on Friday April 29, 2022 @09:08PM (#31212427)
Thanks!

I definitely see your point on splitting up the history!

One thing to consider though is that you're already forced to split up the history in order to handle secrets securely.

Given this unfortunate truth, I think you're better off storing all the config and secrets together rather than splitting them up and keeping config with the code.

There's not always a clear line on what's a secret and what's "safe" config, so attempting to split them up like this is asking for trouble: you're almost guaranteed to end up with secrets in your git repo eventually.

All that said, we've thought about adding a git integration that would output a non-sensitive state file ala 'tfstate' so that you can see your EnvKey history baked right into your git history--it wouldn't show values but you could see what keys had changed. Would something along those lines help to address your concern?

Re:The Twelve-Factor App (2011) by zmmmmm on Friday April 29, 2022 @09:58PM (#31212685)
thanks for the reply!

You're right about the split situation for secrets. I guess secrets have a different lifecycle generally anyway (just cos you roll back your code doesn't mean the password to production should be what it was at the time of the prior release). For this reason they (nearly) always sit outside of the versioning process for the code.

However our secrets are probably less than 1/10th of the config and even less of the complexity. So I am content to use a separate secrets manager / process for that.

Would be great to think about how to integrate with git workflows. Seems a bit messy but something like you suggest where it dumps it out to a file could be a way. Would be good to solve as incorrect / missing config is one of our major reasons for deployment issues, and so far despite all its evils, tracking them in source control as part of the dev process has been the best solution to minimise it.

Re:The Twelve-Factor App (2011) by timmahoney on Thursday April 28, 2022 @10:02PM (#31200531)
In kubernetes I run external secrets, which is nice. I store The secrets in key value or file format in AWS Secrets Manager, which gets synchronized to the cluster into a secret. From there it gets mounted into the running pod via the envFrom or volume mount method.
Re:The Twelve-Factor App (2011) by thinkmassive on Friday April 29, 2022 @12:42AM (#31201530)
External secrets are great, especially if your app can read them directly from k8s and avoid ever having them mounted as a volume (or in env var).

If your app can’t interface directly w/k8s, but it can read secrets from a file, you can use a small init program to fetch the k8s secret and write it to a named pipe. This is advantageous compared to mounting as a volume, because the pipe disappears after both ends close their connection to it.

Re:The Twelve-Factor App (2011) by tdfx on Thursday April 28, 2022 @11:36PM (#31201108)
> I’ve generally found it much better to mount these into the filesystem and read from there.

Is there a standardized/best practice way to do this? Some convention for file names or format?

Re:The Twelve-Factor App (2011) by kortex on Thursday April 28, 2022 @11:58PM (#31201255)
I'm fond of the XDG path convention. Which basically boils down to putting configs in ~/.config/your_app/ and secrets in ~/.config/your_app/secrets.

If you use pydantic, it supports a secrets dir with a predefined path.

https://specifications.freedesktop.org/desktop-entry-spec/de...

Re:The Twelve-Factor App (2011) by hakre on Friday April 29, 2022 @04:55AM (#31202948)
There is docker secrets and some specialized convention for example to share the ssh control socket during build time etc.
Re:The Twelve-Factor App (2011) by Cthulhu_ on Friday April 29, 2022 @08:30AM (#31204291)
I wouldn't put them on a filesystem; do you have any guarantees the secrets are wiped clean after your application is shut down? At least env vars are in memory (...I... think...?), and will be offloaded if the server shuts down.

A secrets manager may be a better option, these days. I don't believe they were a thing in 2011 though.

Also 2011 was 11 years ago, and I still keep this webpage in mind when building server-side software <_<.

Re:The Twelve-Factor App (2011) by zach_garwood on Thursday April 28, 2022 @09:09PM (#31200198)
Seconded, but porque no los dos? I tend to put my applications' env vars in `/etc/environment`.
Re:The Twelve-Factor App (2011) by numbsafari on Thursday April 28, 2022 @09:18PM (#31200248)
It’s a good question and idea.

I’ve been trending towards treating secrets and non-secrets differently.

For non-secrets, I tend to have a config discovery mechanism that lets me read config from files, then from env, then from cli args as final fallback. This is mostly for ergonomics. I prefer to use files for deployed processes, and env vars or cli params when debugging or working interactively. Env vars are handy for cli args I’m going to be repeating a lot.

But for secrets I’ve tended to only fetching those from files, but allowing the file location to be specified by env var or cli arg for quick changes.

It sounds kinda complicated, but you write that logic into a library and then everything behaves the way you expect consistently.

Re:The Twelve-Factor App (2011) by dfsdf4sds on Friday April 29, 2022 @01:37AM (#31201811)
For what it's worth at $dayjob (public company, 1B+ revenue) we do the exact same, although either I misunderstood you or we have the exact opposite priority: args always win, if they're not defined then env wins, then config file, then default config value in code which sometimes is an actual value, and sometimes it defaults to throwing an exception and never passing a readiness check, depending on the behavior of the config in question. This last one is mostly a relic of the past and we believe it's better to blow up if there's no default configuration value in the chart in all cases; it also makes it way easier not to have to chase defaults through the code.

We use these for running locally and debugging as you say, but come deployment time we ship all applications as helm charts with default config values, store overrides and static secrets (with SOPS) in a different, company-global repo, and use kubernetes secrets to mount a tmpfs volume to pass them in to the application. There's no way to pass args or env there.

Re:The Twelve-Factor App (2011) by Parrot_NTheKing on Friday April 29, 2022 @07:50AM (#31203980)
One pattern that we use at our company is that we have multiple env files, and we launch programs using `run_with_config <config-file> <command>`. The script loads environment variables from config-file and then launches command.
Re:The Twelve-Factor App (2011) by zach_garwood on Friday April 29, 2022 @07:56PM (#31211954)
I like to do something similar with my personal projects: `set -o allexport && source /ect/environment && set +o allexport; command`
Re:The Twelve-Factor App (2011) by TheRealDunkirk on Friday April 29, 2022 @07:27AM (#31203800)
<Laughs in Rails.> Credentials.yml.enc/master.key sorts this pretty well. I have been very grateful for its addition to the stack.