#!/bin/bash # ============================================================================= # officer-setup — the secret store # ============================================================================= # # Definitions only. # # The store is $OFFICER_ROOT/secrets/officer-keys.db, deliberately a sibling of # the repo and NOT under data/ — that directory holds the managed homes and # attachments people back up, and a key store travelling in the same tarball as a # database dump rebuilds the exact problem it exists to avoid. # # Bootstrapping runs the platform's own module rather than reimplementing the # schema in bash. There is exactly one writer of this file's format, and a second # one in shell would drift the first time a column is added. [[ -n "${OFFICER_SETUP_SECRETS_LOADED:-}" ]] && return 0 OFFICER_SETUP_SECRETS_LOADED=1 secret_store_dir() { echo "${OFFICER_ROOT}/secrets"; } secret_store_path() { echo "$(secret_store_dir)/officer-keys.db"; } # Create the store and the two purposes a core install needs. # # Run AS the owner, not as root: the platform runs as them, and a store root # created would be a store they cannot write. `install -d -o` sets the owner in # one step rather than mkdir-then-chown, so it is never briefly root's. bootstrap_secret_store() { install -d -m 0700 -o "$USERNAME" -g "$(user_group)" "$(secret_store_dir)" || return 1 # From the repo, because the module derives the install root as the parent of # the working directory — the same rule as src/servers/data-path.ts. sudo -u "$USERNAME" bash -c "cd '$(platform_dir)' && bun --eval \" const { getKey } = await import('officerdb/secret-store'); getKey('jwt'); getKey('headscale'); \"" >/dev/null 2>&1 || return 1 [[ -f "$(secret_store_path)" ]] }