| 1 | # Env and secrets |
| 2 | |
| 3 | Your app's configuration lives in two stores. Both arrive at your process |
| 4 | as ordinary environment variables, and from inside the app you cannot |
| 5 | tell them apart. The difference is what happens to the value on the way |
| 6 | there, and it is worth getting right the first time. |
| 7 | |
| 8 | Plain config goes in `carlos env`: |
| 9 | |
| 10 | ```sh |
| 11 | carlos env set -app hello LOG_LEVEL=debug |
| 12 | ``` |
| 13 | |
| 14 | Credentials go in `carlos secrets`. Same shape: |
| 15 | |
| 16 | ```sh |
| 17 | carlos secrets set -app hello STRIPE_KEY=sk_live_example |
| 18 | ``` |
| 19 | |
| 20 | ## Which store a value belongs in |
| 21 | |
| 22 | Ask whether you would mind the value appearing in a screenshot. A log |
| 23 | level, a feature flag, the public URL of a service you call — nobody |
| 24 | cares, and `carlos env` keeps them readable, which is what you want when |
| 25 | you are working out why staging behaves oddly. |
| 26 | |
| 27 | An API key, a database URL with a password in it, a signing secret, |
| 28 | anything a third party issued you: `carlos secrets`. If in doubt, the |
| 29 | sealed store costs you nothing except the ability to read the value back, |
| 30 | so put it there. |
| 31 | |
| 32 | ## What sealing actually does |
| 33 | |
| 34 | `carlos secrets set` seals the value on your machine, using the |
| 35 | deployment's public key, before anything leaves your terminal. What gets |
| 36 | stored is an envelope. The private half of that key lives on the box that |
| 37 | runs your app and never leaves it, so the console holds a secret it |
| 38 | cannot itself open. |
| 39 | |
| 40 | The consequence is the one thing people trip over: nothing can show you |
| 41 | the value again. `carlos secrets list` prints key names and stops there. |
| 42 | Lose the value and your only move is setting a new one. |
| 43 | |
| 44 | One practical wrinkle. The value is on your command line when you type |
| 45 | it, so your shell history keeps a copy of it. Clear that out on a machine |
| 46 | other people use. |
| 47 | |
| 48 | ## Getting the new value into your app |
| 49 | |
| 50 | Changing config converges on its own. The write bumps a marker, every box |
| 51 | serving the app notices within seconds, rewrites the environment file for |
| 52 | each of the app's routes, and cycles the process so it comes back holding |
| 53 | the new value. There is no separate deploy, and no restart for you to |
| 54 | remember. |
| 55 | |
| 56 | Two things follow from the cycling. A config change is a small |
| 57 | interruption for a running app, so batch related changes into one call — |
| 58 | `carlos env set` takes several `KEY=value` pairs at once. And a change |
| 59 | that appears not to have taken effect is more likely to be your app |
| 60 | reading the variable once at startup than the platform failing to deliver |
| 61 | it. |
| 62 | |
| 63 | To see what is set: |
| 64 | |
| 65 | ```sh |
| 66 | carlos env list -app hello |
| 67 | ``` |
| 68 | |
| 69 | That prints values as well as names, and the sealed store's `list` prints |
| 70 | names alone. Both families also take `unset` with a key name, and the |
| 71 | reference pages for |
| 72 | [carlos env](https://carlosframework.com/docs/cli/#carlos-env) and |
| 73 | [carlos secrets](https://carlosframework.com/docs/cli/#carlos-secrets) |
| 74 | have their remaining sub-verbs. |
| 75 | |
| 76 | If you take one thing from this page: put the credential in the sealed |
| 77 | store on the day you first set it. Moving it later means rotating it, |
| 78 | because by then it has been sitting somewhere readable. |
| 79 | |