Skip to main content

Running it locally

Your application's secrets are declared in its configuration. What a development machine needs is a different question, and the platform answers it separately on purpose: a production credential must never be copied onto a laptop, because a laptop is the least controlled place a credential can live and the copy outlives the reason it was made.

So a declared secret can carry a local development value beside its name and whether it is required. That value is not a secret — it is a development default such as password or a fixture key — and it lives in the same document you already review:

secrets:
app_key:
description: The application's encryption key.
required: true
local: base64:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
payments_api_key:
description: The payment provider's key.
required: true

Getting those values onto your machine​

hostingctl environment secret local <environment-uuid> --company acme --out .env.local

This writes one line per declared secret that has a local value, and names the ones that do not, so you are told what to provide instead of discovering an empty variable at runtime:

# Local development values for <environment-uuid>.
# Every value below is declared in the document for development; none of them is a credential.
# No local value declared, so supply these yourself: payments_api_key
APP_KEY=base64:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=

It reads nothing from the platform's secret store. The only thing it can ever write is what the document already says, so there is no path by which a production credential reaches the file. The file is written with permissions 0600 anyway, because you may add a real value to it yourself.

Run it without --out to print the same content instead of saving it.

Sending a value the other way​

When you already hold a value locally — a key you generated, a credential a provider gave you — you can set it without typing it into a form:

hostingctl environment secret write <environment-uuid> --company acme \
--key payments_api_key --value-source file --value-file ~/payments-key --confirm

hostingctl environment secret import <environment-uuid> --company acme --file secrets.env --confirm

A value is never taken from a command-line argument, and it never appears in output, logs or a dry-run description. A secret already in use is not replaced unless you ask to rotate it — the platform refuses, because rotating a key invalidates data encrypted with the old one.

Declaring a local value​

Open the environment's configuration and add local under the secret's declaration, in the panel or in the YAML you upload. It is a plain field: it appears in the document you review and in the configuration you export, which is the point — you can see what a fresh checkout will use without being trusted with what production uses.

A secret with no local value is not an error. It means a local run has nothing harmless to fall back on, so the down-sync names it and you supply your own development value.