kimen

One profile. Four ways to supply a runtime.

Give each program the interface it already expects: environment variables, private files, paths to those files or standard input.

Kimen documentation, updated September 2026

A profile describes the runtime without containing its secrets.

Create .kimen/profiles/dev.kmap in the project:

env DATABASE_URL=app.dev.database_url
env APP_ENV=const:development

file tls/client.pem=app.dev.client_certificate
envpath CLIENT_CERT_FILE=tls/client.pem

stdin app.dev.request_body

Each line has a projection on the left and a value source on the right. The profile is safe to commit when it contains only names, references and non-sensitive constants.

Use a named profile for normal project work. Use --map path/to/file.kmap when the map lives elsewhere or is selected by another tool.

Kimen looks up a named profile in this order:

$KIMEN_PROFILE_DIR/dev.kmap
.kimen/profiles/dev.kmap
$XDG_CONFIG_HOME/kimen/profiles/dev.kmap
~/.config/kimen/profiles/dev.kmap

The project-local location makes requirements portable. A configured user location can provide a private or machine-wide alternative without changing the project.

Choose the source of each value.

A bare name is a vault key. secret: makes the same choice explicit:

env DATABASE_URL=app.dev.database_url
env PAYMENTS_API_KEY=secret:app.dev.payments_api_key

const: keeps a non-sensitive value in the project:

env APP_ENV=const:development

exec: reads a value from the standard output of another command:

env API_TOKEN=exec:op read op://Development/MyApp/token

This can bridge to an existing password manager or credential helper. The external command, its authentication and its output become part of the boundary. Kimen invokes the parsed command directly, not through a shell, and uses its output as the value.

Current projection commands still open the selected Kimen vault even when every value comes from exec:. The external source does not make the Kimen unlock step optional.

Inspect the contract before opening the vault.

kimen map lint --profile dev --strict
kimen plan --profile dev

map lint checks syntax. Strict mode also turns warnings into failure. plan prints the projection shape without resolving values.

Then verify that the vault opens and every referenced vault key exists:

kimen doctor --profile dev --strict

doctor asks for the vault passphrase unless a valid session or another unlock method is active. It checks references, but does not print their values.

Environment variables go directly to the child process.

# .kimen/profiles/web.kmap
env DATABASE_URL=web.dev.database_url
env PORT=const:3000
kimen run --profile web -- ./web-server

Kimen inherits the current environment, replaces the declared names and starts the command as a child process. The parent shell does not retain the projected values.

Without an active session, this invocation prompts for the vault passphrase. For repeated development runs:

kimen session start --ttl 30m
kimen run --profile web -- ./web-server
kimen session lock

Private files can exist only for one process.

Some libraries require a certificate, service-account document or private configuration file:

# .kimen/profiles/worker.kmap
file credentials/service-account.json=worker.dev.service_account_json
envpath GOOGLE_APPLICATION_CREDENTIALS=credentials/service-account.json
kimen run --profile worker -- ./worker

Kimen creates a private temporary directory, writes the file with mode 0600, sets KIMEN_FILES_DIR and gives GOOGLE_APPLICATION_CREDENTIALS the full temporary path. It removes the temporary directory when the child exits.

envpath does not create a file by itself. It points an environment variable at a relative path created by a matching file entry.

Choose an explicit directory when the receiving process needs a stable location:

kimen run --profile worker \
  --files-dir "$HOME/.cache/my-worker/runtime" \
  -- ./worker

An explicit files directory is not removed automatically. The caller owns its lifecycle.

Standard input is useful for one private payload.

# .kimen/profiles/request.kmap
stdin request.signed_payload
kimen run --profile request -- ./submit-request

The child reads the selected bytes from standard input. A run may contain only one stdin mapping. This is useful when the program already accepts a token or document on stdin and does not need it in its environment or filesystem.

Small one-off runs do not require a profile.

kimen run \
  --env API_KEY=secret:tools.api_key \
  --file config/private.json=tools.private_config \
  --envpath PRIVATE_CONFIG=config/private.json \
  -- ./tool

Inline projections use the same rules as profile lines. A committed profile is better when the project should document and reuse the contract.

Render persistent artifacts only when another system requires them.

Render all file entries into a protected directory:

kimen render --dir "$HOME/.cache/my-app/runtime" \
  --profile worker

Generate an envfile containing only env entries:

kimen envfile --out "$HOME/.cache/my-app/web.env" \
  --profile web

Both outputs contain plaintext. A rendered directory gets mode 0700, and rendered files and envfiles get mode 0600. The envfile's parent directory must already exist. The files remain until you remove or replace them.

For a systemd service, render under /run/kimen/<service> and print the environment hint:

kimen render --systemd-service my-worker \
  --profile worker \
  --print-systemd-hints

Use --runtime-dir /custom/run to replace the default /run base. Run the command as an identity which can write the chosen runtime directory and open the selected vault.

The receiving interface determines the remaining exposure.

  • Environment variables remain available to the child process for its lifetime.
  • Temporary files remain readable to the child and any other process allowed to access their directory.
  • Standard input avoids a named artifact, but the child can still retain the bytes.
  • Rendered directories and envfiles are persistent plaintext artifacts.
  • exec: moves storage elsewhere, but the helper still needs its own authentication.

Kimen controls storage, selection and delivery. It does not make the receiving process unable to read what it was given.

Match Kimen to the interface the program already has.

Keep the requirement in the profile, select the narrowest useful projection and make persistent output an explicit choice.

Install Kimen