#!/bin/bash # ============================================================================= # officer-setup — the environment file # ============================================================================= # # Definitions only. # # ── No secrets are written here ── # # Every encryption and signing key lives in the secret store — a 0600 SQLite file # at $OFFICER_ROOT/secrets/officer-keys.db, one key per purpose, created on first # use. See docs/secret-store.md and the Secrets section of officer-setup.sh. # # So this file holds no credential except POSTGRES_URL, which is a connection # string to a database bound to loopback. # # ── Derived, not asked ── # # DATA_PATH, OFFICER_ITEMS_DIR and HOME_DIR are gone too, and this time nothing # replaces them. The platform derives the install root as the parent of its own # working directory, so data/, capabilities/ and dockers/ follow from the layout # on disk, and the owner's home comes from the OS. They were three environment # variables that had to agree with each other and with the directory tree. [[ -n "${OFFICER_SETUP_ENV_LOADED:-}" ]] && return 0 OFFICER_SETUP_ENV_LOADED=1 env_file() { echo "$(platform_dir)/.env"; } env_exists() { [[ -f "$(env_file)" ]]; } # One value out of an existing .env, without sourcing it — the file holds # secrets and arbitrary shell would run as root. # # Checks the OFFICERDEV_-prefixed key first, matching the priority `OFFICERDEV_X ?? X` # gives it at runtime — write_env ALWAYS writes prefixed keys (see below), so plain `env_get # PORT` used to compare against a key that could never appear in a file this script wrote, # and always came back empty. That silently defeated the resume block below it was written # to fix, and the Environment step's own re-run showed the wrong default. Verified against a # real written .env: `env_get PORT` -> [], `env_get OFFICERDEV_PORT` -> [9000], before this. # Falls back to the bare key so an old, hand-written unprefixed file still works, same as the # runtime does. env_get() { [[ -r "$(env_file)" ]] || return 0 awk -F= -v k="$1" -v pk="OFFICERDEV_$1" ' $1 == pk { v = substr($0, index($0, "=") + 1) gsub(/^"|"$/, "", v) print v exit } $1 == k && !found { v = substr($0, index($0, "=") + 1) gsub(/^"|"$/, "", v) bare = v found = 1 } END { if (bare != "") print bare }' "$(env_file)" } write_env() { local dest dest="$(env_file)" [[ -f "$dest" ]] && cp -a "$dest" "${dest}.before-officer-setup" # Restrictive from the moment it exists rather than chmod'd afterwards, so the # secrets are never briefly world-readable. Restored straight after: umask is # not scoped to a function, and leaving it at 077 would quietly make every file # a later section creates owner-only. local prior_umask prior_umask="$(umask)" umask 077 cat >"$dest" <