Secrets
Reference secrets by name with secret("NAME"); values are read from the environment at apply time and never stored.
Amicu never accepts a secret value in configuration. A secret is a reference to a name, resolved when you apply.
secret("NAME")
resource "deployment" "chat" {
model = model.qwen3_8b.id
hardware = hardware_profile.local_dev.id
runtime = "llama_cpp"
api_key = secret("CHAT_API_KEY")
llama_cpp {
context_length = 8192
port = 8000
n_gpu_layers = -1
}
}export CHAT_API_KEY=$(openssl rand -hex 32)
amicu apply- The argument is a name. For the CLI it is the name of an environment variable.
applyreads the variable from the environment of the process that runsamicu apply. If it is unset, apply fails withsecret 'NAME' is not set in the environment.planandvalidatenever read it. The plan showsapi_key: ******.- The value is never written to state. State holds the reference (the name) only.
What is a secret field
Fields that hold credentials accept only secret(...): a deployment's api_key, and a credential resource's api_key, token, password, and env values. A quoted literal is a hard parse error, AMICU-POLICY-004. A secret("...") whose argument itself looks like a secret (for example an sk- key or a JWT) is rejected the same way, so a value cannot be smuggled in as a reference.
Warnings, not errors:
AMICU-POLICY-005: a free-text field (description,display_name) or a comment contains something shaped like a key, JWT, or PEM header. Add# amicu:allowon that line to suppress it.AMICU-POLICY-006: a runtimeenv {}value looks like a secret. Move it to asecret(...)reference.
Per-deployment API key
Each deployment can declare api_key = secret("NAME"). It is the key clients must send as Authorization: Bearer <key>.
| Provider | api_key |
|---|---|
local, local_apple, local_cpu, on_prem | Optional. The endpoint is loopback only. |
| Every other provider (a remote GPU provider such as Modal) | Required. Missing it is AMICU-POLICY-007, reported by validate and plan, and re-checked by apply before anything starts. |
The resolved key must be non-empty and must not contain a comma, whitespace, or non-ASCII characters (AMICU-POLICY-008). Runtimes treat a comma as a list of several keys. openssl rand -hex 32 produces a valid key.
You cannot set the key another way: --api-key, --api-key-file, LLAMA_API_KEY, and VLLM_API_KEY in extra_args or env are rejected (AMICU-CAP-003).
How the key reaches the runtime
The key is delivered through the runtime's environment, never through the command line, logs, plans, or state. Amicu sets LLAMA_API_KEY for llama.cpp and VLLM_API_KEY for vLLM.
| Target | Mechanism |
|---|---|
| macOS | The LaunchAgent plist's EnvironmentVariables, in a file readable only by you (mode 0600). The plist is removed when the service is stopped. |
| Linux | A systemd EnvironmentFile referenced by the transient user unit, mode 0600. Values never appear on systemd-run's command line. |
| Remote GPU provider | Provider-specific, never the command line or the image. On Modal, a Modal Secret injected as the container's environment. See the provider page. |
Other secrets work the same way: for example HF_TOKEN for gated Hugging Face repos is sent only into the running container (on Modal, as a Modal Secret).
What to do if a value leaks
Rotate it at the source. Because plan never reads secret values, it cannot tell that a value changed. To deliver a new key, recreate the deployment: remove it from the configuration and apply, then add it back and apply again.