№ 02 Two things called config

A setting, and a secret

Both arrive at your app the same way. What each one is, and who can read it back, are not the same question.

  • A setting

    A value that changes how your app behaves, and is not secret if someone sees it.

    Example: A feature toggle, a display name, a region string, a log level.

    Read back by: Anyone who can already read your code or your running app's output.

  • A secret

    A value that grants access, and must not leak — to a person, a log, or a public bundle.

    Example: An API key, a database password, a signing key, a connection string.

    Read back by: Named CustomHosted accounts only, to service or rotate it — see the matrix rows below.

№ 03 Where a value lives

Where a value lives, hop by hop

Every value takes the same path, whether it is a setting or a secret.

  1. 1

    You send the value

    Through the quote channel, at onboarding or whenever it changes — never a spreadsheet or a chat message.

    You

  2. 2

    It is kept in an encrypted store

    Sent once, at onboarding or whenever it changes, and kept in an encrypted store — never copied into a spreadsheet, a chat message, or a second system to keep in sync.

    CustomHosted

  3. 3

    It is injected at build time or deploy time

    Which one depends on the hosting shape and the value itself — see the build-time-versus-run-time band below.

    CustomHosted

  4. 4

    It lands in the process environment at startup

    The running app reads it at startup. It is never written into a file in your repository, so an agent reading the codebase sees the name of the variable your code uses, never the value stored in it.

    The process

  5. 5

    Your code reads it

    The same way any app reads a setting or a secret — by name, from the environment it is running in.

    You

№ 04 Build time against run time

A build-time value is a public value

Said plainly, because nowhere else on this site has: a value baked into a static bundle ships to every visitor who opens it.

  • A build-time value ends up inside the bundle

    A static site or a single-page app has no server standing by at request time. Anything read into it at build time is baked into the files a browser downloads.

  • That bundle is public

    Every file shipped to a visitor's browser can be read by that visitor. A value baked in at build time is public the moment it ships — not hidden, only unlabelled.

  • A run-time value stays on the server

    A dedicated instance keeps a standing process. A value read from its environment at startup never leaves that process unless your own code sends it somewhere.

  • The rule that follows

    Never put a secret in a build-time value on a static site. A setting is fine there. A secret needs a standing process to hold it — see the shape table below.

№ 05 By hosting shape

What holds a value, by hosting shape

Whether a change needs a rebuild or a restart depends on the shape, not the value.

ShapeHoldsTo change one
Static Starter ST-STARTERBuild-time values only, baked into the deployed files.A rebuild and redeploy — nothing to restart, because nothing stands running.
Static Pro ST-PROThe same build-time values, once per environment — production and staging each hold their own.A rebuild and redeploy of the environment you changed.
Dedicated M DD-MRun-time values in the process environment, read fresh at every startup.A restart of the process — see the restart-visibility table below for what you would notice.
Custom CU-0Whichever mix the design calls for — sized and confirmed at the quote stage.Whatever the design calls for — confirmed once, not guessed at.

What "restart" looks like on a running process, by shape:

  • Static site

    None — there is no running process to restart.

  • Dedicated instance

    A few seconds while the process restarts, confirmed by the health check above before the window closes.

  • Managed database, minor version

    A brief connection blip during failover — existing connections reconnect on their own.

№ 06 Changing one

Changing a value

Sized inside the iteration allowance — around 120 minutes, the same 2-hour unit any small change draws from.

  1. 1

    Send the new value

    Through the quote channel, naming which variable and which environment.

    You

  2. 2

    It is stored, and rotated in

    Stores the value you send and rotates it on request.

    CustomHosted

  3. 3

    It takes effect

    A rebuild on a static shape, or a restart on a dedicated shape — see the restart-visibility table above.

    CustomHosted

  4. 4

    You are told it is done

    A note confirming what changed, in the same shape as every other note on this site.

    CustomHosted

To go back, send the previous value the same way — there is no separate undo button for a configuration change.

№ 07 Per environment

Production values, staging values

Same infrastructure definition, different values — see Environments for the environment itself.

  • Production

    Its own set of values — the ones your live app actually reads.

  • Staging

    Its own separate set, not a copy of production's. Changing one never quietly changes the other.

№ 08 Rotation

Rotating a value

Three real triggers, each with a place that owns it in full.

  • A person leaves

    Anything they held a key to on our side is revoked the same day — the same rule joiners and leavers already sets. See Access — joiners and leavers.

  • A value leaks

    Treated as a live incident: the value is rotated, and the exposure is worked the way any leaked credential is. See Under attack — password guessing.

  • A scheduled rotation

    Send the replacement value whenever you choose — there is no console click, only the same quote channel as any other change. See Access — secrets.

№ 09 What it costs

Nothing extra

A configuration change is priced the same as any other small change.

A config change sits inside the iteration allowance — 3 changes a month, 2 hours each, the same allowance covered under Agentic iteration — CodeHerder ($25/mo). See The hours ledger for the full ledger.

№ 10 The worked artifact

This site's own configuration

Every row below is provable from this repository, not asserted.

  • One build-time value, set on purpose

    PUBLIC_CONTACT_ENDPOINT is read in at build time and ships inside this site's own static bundle — public by design, because it only names where the quote form posts to.

  • No secret anywhere in the repository

    This site holds no API key, password, or signing key of its own. The quote form itself carries no secret — it posts to a relay that holds the credential instead.

  • A relay, not a direct write

    The quote form sends a request to a relay rather than writing anywhere directly, so nothing this site's own code runs ever needs a stored credential.

№ 11 Said plainly

The honest limits

Not buried in a footnote — the same discipline as every other honesty band on this site.

  • No self-serve console

    There is nowhere to click a value in or out yourself. Every change goes through the quote channel, the same as any other request on this site.

  • A build-time value in a static bundle is public

    Said plainly, not buried: baking a secret into a static build ships it to every visitor's browser. Use a run-time value on a standing process instead.

  • We can read a value back

    Named accounts only, to service or rotate a value. A named account, never a shared login.

  • No per-branch configuration sets

    Production and staging each hold their own values. There is no wider fleet of per-branch value sets on a standard plan.

  • No feature-flag service

    A setting can toggle behaviour, but there is no separate flag service here to turn one on or off per visitor. That is application code, not a platform feature.

№ 12 CodeHerder

A name, never a value

This is the exact boundary CustomLabs draws for the CodeHerder agent — the one that makes agentic iteration safe to run against your live code.

It sees that your code reads a variable, never the value stored in it.

A briefed change that needs a new value comes back as a pull request naming the variable, not the value in it. A person sets the value once the change is reviewed — the same ship mechanics as any other briefed change:

  1. 1

    A routine scan flags a dependency

    The same kind of check that watches the infrastructure layers above, run against your application’s own dependency list.

    CustomHosted

  2. 2

    It's triaged as application-level, not infrastructure

    A library your own code imports isn't ours to patch silently — it can change how the app behaves.

    CustomHosted

  3. 3

    Briefed as a change

    Written up the same way any other change request is — this is what the Agentic iteration — CodeHerder add-on covers.

    CustomLabs

  4. 4

    An agent opens the pull request

    The upgrade lands as a real pull request against the repository, with the test suite run against it.

    CodeHerder

  5. 5

    A human reviews and merges

    Someone reads the diff before it goes anywhere near production — nothing here is auto-applied blind.

    CustomLabs

  6. 6

    It ships through the same pipeline

    The same pipeline that deploys everything else on your stack ships this too — no separate process to babysit.

    CustomHosted

  7. 7

    You're told it's done

    A note confirming what changed and that it merged, in the same shape as every other note on this site.

    CustomHosted

№ 13 Answers

Configuration questions

What people ask once "an environment variable" stops being self-explanatory.

  1. 01What counts as a secret, rather than just a setting?

    Anything that grants access on its own — an API key, a password, a signing key, a connection string. If seeing the value would let someone do something they should not, it is a secret.

  2. 02Can I read my own secret's value back?

    There is no console to read it from — ask, and we tell you.

  3. 03Is it safe to put an API key in a static site's build?

    No. A static build ships to every visitor's browser, so anything baked in at build time is public. Keep a secret on a dedicated shape that reads it at run time instead.

  4. 04Does changing a value take my app down?

    On a static site, a rebuild replaces the deploy — nothing was running to go down. On a dedicated instance, the process restarts — see the restart-visibility table above for exactly what that looks like.

  5. 05Do staging and production share the same values?

    No. Each environment holds its own set, so a value changed in one never quietly changes the other.

  6. 06Can the CodeHerder agent read or set a value?

    No, on both counts. It can see that your code reads a variable by name. It can open a pull request that adds a new one. It never sees or sets the value stored in it.

  7. 07What does a config change cost?

    Nothing on top. It sits inside the iteration allowance — 3 changes a month, 2 hours each, the same allowance any other small change draws from.

№ 14 Keep reading

What configuration connects to

Need a value changed, or a new one added?

Brief it through the same quote channel as any other request — see Access for who can read one back.

Get a quote →