/proc/<pid>/cmdline, CloudFormation state, and CI logs. Lowkey’s --kiro-from-secret flag shows the right pattern — pass only a Secrets Manager reference at deploy time, and let the instance resolve the raw value via its IAM role at install time.
Only the secret name flows through CloudFormation or Terraform state. The value is resolved on the EC2 instance at install time, using the instance’s IAM role. It never appears in deploy state, UserData logs, or shell history.
How the reference pattern works
- You store the raw secret in AWS Secrets Manager under a path like
/lowkey/kiro-api-key. - You pass the path (not the value) to the installer with
--kiro-from-secret /lowkey/kiro-api-key. - The installer passes this reference through CloudFormation or Terraform state — only the name, not the value.
- On the EC2 instance, the pack’s
install.shcallsaws secretsmanager get-secret-valueusing the instance’s IAM role. - The resolved key is written to a protected file (for example,
~/.kiro/envwith0600permissions) and sourced at login.
Step-by-step: Kiro CLI headless deploy
Store the Kiro API key in Secrets Manager
SecretString is just the raw API key — no JSON wrapper. You can also create this in the AWS console.Verify the instance profile has permission
Every Lowkey profile (builder, account_assistant, personal_assistant) includes
secretsmanager:GetSecretValue on secrets under the /lowkey/* path by default. If you stored the key under /lowkey/kiro-api-key, no additional IAM changes are needed.The pack resolves and stores the key on the instance
At install time, the pack runs:The resolved key is written to
~/.kiro/env with 0600 permissions and sourced from ~/.bash_profile.Other secret types
OpenAI API key (Codex CLI pack)
OpenAI API key (Codex CLI pack)
The codex-cli pack does not yet have a For persistence across sessions, write to
--from-secret flag. To avoid putting the key in your shell history, store it in Secrets Manager and source it manually after connecting via SSM:~/.bash_profile with 0600 permissions.Anthropic API key (OpenClaw model-mode=api-key)
Anthropic API key (OpenClaw model-mode=api-key)
When you deploy OpenClaw with Write to
model-mode=api-key, the agent uses ANTHROPIC_API_KEY directly instead of Bedrock. Store the key in Secrets Manager and fetch it on the instance:~/.bash_profile (0600) for persistence. Alternatively, pass --provider-api-key at install time — but note that this value passes through UserData. See the warning below.LiteLLM proxy API key
LiteLLM proxy API key
Pass via
--litellm-api-key to the installer. The CloudFormation template marks it NoEcho: true, so it won’t appear in describe-stacks output. However, it still appears in Base64-encoded UserData in stack metadata.For production, fetch the key from Secrets Manager inside a post-install script instead. A --litellm-from-secret flag is planned — check the GitHub repo for current status.Telegram bot token (NemoClaw pack)
Telegram bot token (NemoClaw pack)
NemoClaw accepts
--telegram-token during install. Like other API key flags, this is NoEcho: true in CloudFormation but still present in UserData. For a more secure setup, store the token in Secrets Manager and load it in a post-install script rather than passing it on the command line.Why not use CloudFormation NoEcho directly?
NoEcho: true hides parameter values from describe-stacks output and the CloudFormation console. It is not a complete solution:
- Values still appear in the CloudFormation template body if set as a
Default:. - They appear in Base64-encoded UserData, which is queryable via
describe-instance-attribute. - Terraform stores
sensitive = truevariables in plaintext in its state file. - Both leave a trail in CI logs if the deploy command is logged.
Secret naming convention
Store Lowkey-related secrets under the/lowkey/ prefix. The default IAM policy on every instance profile grants secretsmanager:GetSecretValue on this path: