Menu

Secrets

MacTain secrets store sensitive values for runtime projection into containers. MacTain stores these values in the native macOS Keychain through MacTain's signed app and Engine. Blueprint files reference existing secret names and projection metadata; they do not store plaintext secret values.

This is intentional MacTain behavior: local MacTain secrets do not require a third-party vault service, a separate secrets daemon, or a Docker-compatible credential helper. MacTain uses the macOS security mechanisms already present on the user's Mac, then projects the secret into selected containers only at runtime.

Command Reference

CommandDescriptionTypical use
mactain secret set <name> --stdinCreates or replaces a secret from stdin.Store a token, password, or key without putting it in a file or shell argument.
mactain secret listLists configured secrets as metadata only.Confirm a secret exists before referencing it.
mactain secret remove <name>Deletes a configured secret.Remove a secret that is no longer needed.
mactain secret delete <name>Alias for remove.Compatibility with delete wording.

Defaults And Behavior

  • Secret commands require a signed MacTain build because MacTain needs the entitlements required to access its Keychain-backed secret store.
  • Secret values are stored in MacTain's Keychain service, not in Blueprint TOML, project files, shell scripts, or docs.
  • MacTain's native secret store uses the macOS Data Protection Keychain with whenUnlockedThisDeviceOnly accessibility in the current implementation.
  • set requires --stdin; do not pass secret values as command-line arguments.
  • list is metadata-only and should not reveal secret values.
  • Blueprints reference existing secrets; they do not create secrets implicitly.
  • Blueprint secret projection supports environment variables and files.
  • Default file projection writes to /run/secrets/<secret-name> when as = "file" is used without an explicit path.
  • Secret references are validated by name and projection shape. Invalid references should fail before runtime work proceeds.

Keychain-Backed Storage

MacTain-managed secrets are local to the Mac and stored through macOS Keychain. This gives MacTain a native storage path for local container secrets without requiring users to set up a separate vault product just to run a local stack.

Keychain-backed storage affects how you should use secrets:

  • Create secrets with mactain secret set <name> --stdin or through the signed MacTain app.
  • Reference secrets by name from containers or Blueprint TOML.
  • Treat mactain secret list as an inventory command; it lists names only.
  • Rotate a value by setting the same secret name again from stdin.
  • Remove a value with mactain secret remove <name> when no active workflow should use it.
  • Do not put secret values in env, labels, command arguments, Blueprint TOML, docs, logs, or support requests.

Registry credentials are also Keychain-backed, but they are a separate store and workflow. Use Registry credentials for image pull and push authentication. Use MacTain Secrets for values an application reads at runtime, such as database passwords, API tokens, certificates, and service keys.

Blueprint Secret Forms

Use these TOML shapes after creating secrets with the CLI.

[[components]]
id = "api"
image = "ghcr.io/acme/api:latest"
secrets = [
  { secret = "api-token", env = "API_TOKEN" },
  { secret = "db-password", as = "file" },
  { secret = "tls-cert", path = "/var/run/certs/tls.crt" }
]

Projection rules:

  • Use env when the app expects an environment variable.
  • Use as = "file" for the default file path.
  • Use path = "/absolute/container/path" for an explicit file projection.
  • Do not set both env and path on the same secret entry.
  • Do not put inline secret values in Blueprint TOML.

Practical Use Cases

Use case: create a secret for a Blueprint

Use this before adding a secret reference to a Blueprint file.

printf '%s' "$API_TOKEN" | mactain secret set api-token --stdin
mactain secret list
mactain blueprint validate ./myapp.toml

Keep the secret value outside the Blueprint. The Blueprint should only contain the secret name and projection target. The actual value remains in MacTain's Keychain-backed secret store.

Use case: rotate a secret without editing the Blueprint

Use this when a database password or API token changes but the Blueprint still uses the same secret name.

printf '%s' "$NEW_API_TOKEN" | mactain secret set api-token --stdin
mactain secret list
mactain blueprint plan ./myapp.toml

Because the Blueprint references api-token by name, rotation updates the stored value without putting the replacement value into the TOML file.

Use case: project a secret as an environment variable

Use this when the application reads secrets from env.

[[components]]
id = "api"
image = "ghcr.io/acme/api:latest"
secrets = [{ secret = "api-token", env = "API_TOKEN" }]
mactain blueprint validate ./myapp.toml
mactain blueprint plan ./myapp.toml
mactain blueprint start ./myapp.toml

Use case: remove a secret after rotation

Use this when a secret has been replaced and no active workflow should use the old value.

mactain secret remove api-token
mactain secret list

Update Blueprints or recreate the secret before starting workflows that still reference the removed name.

Troubleshooting Entry Points

  • secret command is unavailable: confirm you are using a signed MacTain build.
  • Secret store fails with a Keychain or entitlement error: confirm the MacTain app and Engine are signed builds with access to MacTain's Keychain group.
  • Blueprint validation fails: confirm the referenced secret exists and the projection has exactly one target.
  • Runtime app cannot read the secret: confirm whether the app expects an env variable or file path, then match the Blueprint projection.

Next Steps

Continue to Blueprints to use secret references in a repeatable app definition.

Related