#!/usr/bin/env bash set -euo pipefail CA_URL="${CA_URL:-https://10.10.40.53}" CA_FINGERPRINT="${CA_FINGERPRINT:-5fc8c379cab1119c1a9ac7038225f6bcf3a2ffb0e71b257af796b2bd6c71d594}" STEP_VERSION="${STEP_VERSION:-0.28.7}" FORCE="${FORCE:-0}" usage() { cat <&2 exit 1 } need_cmd() { command -v "$1" >/dev/null 2>&1 } download_file() { local url="$1" local out="$2" if need_cmd curl; then curl -fsSL "$url" -o "$out" elif need_cmd wget; then wget -qO "$out" "$url" else fail "Neither curl nor wget is installed" fi } detect_os() { case "$(uname -s)" in Linux*) echo "linux" ;; Darwin*) echo "darwin" ;; MINGW*|MSYS*|CYGWIN*) echo "windows_bash" ;; *) echo "unknown" ;; esac } detect_arch() { case "$(uname -m)" in x86_64|amd64) echo "amd64" ;; aarch64|arm64) echo "arm64" ;; armv7l) echo "armv7" ;; *) uname -m ;; esac } install_step_linux() { local arch="$1" local tmpdir pkg_name url tmpdir="$(mktemp -d)" trap 'rm -rf "$tmpdir"' RETURN if need_cmd apk; then case "$arch" in amd64) pkg_name="step-cli_${STEP_VERSION}_amd64.apk" ;; arm64) pkg_name="step-cli_${STEP_VERSION}_arm64.apk" ;; *) fail "Unsupported Alpine architecture: $arch" ;; esac url="https://github.com/smallstep/cli/releases/download/v${STEP_VERSION}/${pkg_name}" download_file "$url" "$tmpdir/$pkg_name" sudo apk add --allow-untrusted "$tmpdir/$pkg_name" return fi if need_cmd dpkg; then case "$arch" in amd64) pkg_name="step-cli_${STEP_VERSION}_amd64.deb" ;; arm64) pkg_name="step-cli_${STEP_VERSION}_arm64.deb" ;; *) fail "Unsupported Debian/Ubuntu architecture: $arch" ;; esac url="https://github.com/smallstep/cli/releases/download/v${STEP_VERSION}/${pkg_name}" download_file "$url" "$tmpdir/$pkg_name" sudo dpkg -i "$tmpdir/$pkg_name" || { sudo apt-get update sudo apt-get install -f -y } return fi fail "Unsupported Linux distribution. Supported: Debian/Ubuntu and Alpine" } install_step_darwin() { if need_cmd brew; then brew install step else fail "Homebrew is required on macOS to install step automatically" fi } ensure_step() { if need_cmd step; then log "step CLI already installed" return fi local os arch os="$(detect_os)" arch="$(detect_arch)" log "Installing step CLI for $os/$arch" case "$os" in linux) install_step_linux "$arch" ;; darwin) install_step_darwin ;; windows_bash) fail "Use the PowerShell installer on native Windows" ;; *) fail "Unsupported OS: $os" ;; esac need_cmd step || fail "step CLI installation failed" } bootstrap_step() { if [ "$FORCE" = "1" ]; then rm -rf "$HOME/.step" fi log "Bootstrapping against $CA_URL" step ca bootstrap \ --ca-url "$CA_URL" \ --fingerprint "$CA_FINGERPRINT" \ --install \ --force } install_linux_trust() { local root_cert="$HOME/.step/certs/root_ca.crt" [ -f "$root_cert" ] || fail "Root certificate not found at $root_cert" if need_cmd update-ca-certificates; then sudo mkdir -p /usr/local/share/ca-certificates sudo cp "$root_cert" /usr/local/share/ca-certificates/insmw-root-ca.crt sudo update-ca-certificates return fi if need_cmd trust; then sudo trust anchor "$root_cert" return fi fail "Could not determine how to install the CA into this Linux trust store" } install_macos_trust() { local root_cert="$HOME/.step/certs/root_ca.crt" [ -f "$root_cert" ] || fail "Root certificate not found at $root_cert" sudo security add-trusted-cert \ -d \ -r trustRoot \ -k /Library/Keychains/System.keychain \ "$root_cert" } install_trust_store() { case "$(detect_os)" in linux) install_linux_trust ;; darwin) install_macos_trust ;; *) fail "Unsupported OS for trust-store installation" ;; esac } verify_install() { local root_cert="$HOME/.step/certs/root_ca.crt" log "Installed root CA:" step certificate inspect "$root_cert" --short || true echo echo "Done." } parse_args() { while [ $# -gt 0 ]; do case "$1" in --force) FORCE=1 shift ;; -h|--help) usage exit 0 ;; *) fail "Unknown argument: $1" ;; esac done } main() { parse_args "$@" ensure_step bootstrap_step install_trust_store verify_install } main "$@"