Scoped Env Injection: AWS Without Hand-Rolled Exports
Dot-notation is good for organizing a vault:
AWS_IAM.access_key_id
AWS_IAM.secret_access_key
AWS_SES.smtp_password
AWS_S3.bucket
But shell tools do not know LocalVault namespaces. By default, a nested key like
AWS_IAM.access_key_id becomes:
AWS_IAM__access_key_id
That is readable, but the AWS CLI expects:
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_SESSION_TOKEN
LocalVault now gives env and exec the same projection DSL, so you can scope
and map values at the boundary where they enter a process.
Use the AWS Profile
For AWS commands, use the built-in profile:
localvault exec --profile aws -- aws sts get-caller-identity
The profile does two things:
- Scopes injection to
AWS_IAM.* - Maps LocalVault names to standard AWS environment variables
The built-in mappings are:
| LocalVault key | Environment variable |
|---|---|
AWS_IAM.access_key_id |
AWS_ACCESS_KEY_ID |
AWS_IAM.secret_access_key |
AWS_SECRET_ACCESS_KEY |
AWS_IAM.session_token |
AWS_SESSION_TOKEN |
If AWS_IAM.session_token is not present, nothing extra is injected.
Select Only What a Process Needs
Selectors are intentionally small:
| Selector | Meaning |
|---|---|
KEY |
exact key |
GROUP.* |
all keys in a dot namespace |
A,B,C |
multiple selectors |
Examples:
localvault exec --only AWS_IAM.* -- aws sts get-caller-identity
localvault exec --only AWS_IAM.*,AWS_SES.* -- your-script
localvault env --only OPENAI_API_KEY,AWS_IAM.*
This is least-privilege injection. A subprocess that only needs AWS identity does not also receive Stripe, database, or webhook secrets from the same vault.
Exclude After Selecting
Use --except to remove a narrower set after selecting a broader namespace:
localvault exec \
--only AWS_IAM.*,AWS_SES.* \
--except AWS_SES.smtp_password \
-- your-script
The process receives AWS identity values and the rest of the SES namespace, but not the SMTP password.
Map One Key Explicitly
Use --map when a tool expects a specific variable name:
localvault exec \
--only AWS_IAM.access_key_id \
--map AWS_IAM.access_key_id=AWS_ACCESS_KEY_ID \
-- your-command
The same mapping works with env:
localvault env --map AWS_IAM.access_key_id=AWS_ACCESS_KEY_ID
env prints export lines for shell sourcing. exec is safer for most work
because values go straight into the child process environment.
Override A Profile
Profiles are defaults, not a cage. Explicit maps win:
localvault exec \
--profile aws \
--map AWS_IAM.access_key_id=CUSTOM_AWS_KEY \
-- your-command
Projection order is:
- Apply profile maps
- Apply
--only - Apply
--except - Apply explicit
--map
That gives LocalVault useful defaults while still letting you adapt to odd tools.
Dot to Double Underscore
When no mapping is provided, nested keys still use the long-standing transform:
GROUP.key
# becomes
GROUP__key
The group is uppercased, the subkey is kept as written. That keeps all-project injection collision-safe:
platepose.DATABASE_URL
inventlist.DATABASE_URL
# become
PLATEPOSE__DATABASE_URL
INVENTLIST__DATABASE_URL
Use -p PROJECT when you want one project group without the prefix:
localvault exec -p platepose -- rails server
Use the selector DSL when you want cross-project or service-specific injection.
A Practical Pattern
For day-to-day cloud work:
localvault exec --profile aws -- aws sts get-caller-identity
localvault exec --profile aws -- aws s3 ls
localvault exec --only AWS_IAM.*,AWS_SES.* -- your-mailer-check
The vault can hold everything. The process only gets what it needs.