#!/bin/sh set -eu bootstrap_url='https://api.truckwash.io:4433/bird/control-plane/v1/bootstrap' status_url='https://api.truckwash.io:4433/bird/control-plane/v1/status' expected_algorithm='RSA-OAEP-256' expected_fingerprint='6dc63c6ffe33b8de0b1396d7f529f56aea0a685ef98168016161cf721ddc8c21' private_key='/home/jeppe/.openclaw/credentials/bird.bootstrap-private.pem' credential_dir='/home/jeppe/.openclaw/credentials' destination="$credential_dir/bird.gateway-token" umask 077 mkdir -p "$credential_dir" envelope_file="$(mktemp "$credential_dir/.bird-bootstrap-envelope.XXXXXX")" candidate_file="$(mktemp "$credential_dir/.bird-gateway-token.XXXXXX")" payload_file="$(mktemp "$credential_dir/.bird-bootstrap-payload.XXXXXX")" status_file="$(mktemp "$credential_dir/.bird-bootstrap-status.XXXXXX")" cleanup() { rm -f "$envelope_file" "$candidate_file" "$payload_file" "$status_file" } trap cleanup EXIT HUP INT TERM test -r "$private_key" test "$(stat -c '%a' "$private_key")" = '600' curl --proto '=https' --tlsv1.2 --fail --silent --show-error \ --max-time 30 "$bootstrap_url" > "$envelope_file" test "$(jq -r '.success // false' "$envelope_file")" = 'true' test "$(jq -r '.data.algorithm // empty' "$envelope_file")" = "$expected_algorithm" test "$(jq -r '.data.keyFingerprint // empty' "$envelope_file")" = "$expected_fingerprint" jq -e '.data | keys == ["algorithm","ciphertext","keyFingerprint","tokenVersion","updatedAt"]' \ "$envelope_file" >/dev/null jq -e '.data.tokenVersion | type == "number" and . >= 1 and floor == .' \ "$envelope_file" >/dev/null jq -e '.data.updatedAt | type == "string" and test("^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$")' \ "$envelope_file" >/dev/null jq -e '.data.ciphertext | type == "string" and length == 512 and test("^[A-Za-z0-9+/]{512}$")' \ "$envelope_file" >/dev/null jq -r '.data.ciphertext' "$envelope_file" \ | base64 -d \ | openssl pkeyutl -decrypt -inkey "$private_key" \ -pkeyopt rsa_padding_mode:oaep \ -pkeyopt rsa_oaep_md:sha256 \ -pkeyopt rsa_mgf1_md:sha256 > "$payload_file" jq -e '. | keys == ["algorithm","keyFingerprint","token","tokenVersion","updatedAt"]' \ "$payload_file" >/dev/null test "$(jq -r '.algorithm // empty' "$payload_file")" = "$expected_algorithm" test "$(jq -r '.keyFingerprint // empty' "$payload_file")" = "$expected_fingerprint" test "$(jq -r '.tokenVersion // empty' "$payload_file")" = \ "$(jq -r '.data.tokenVersion' "$envelope_file")" test "$(jq -r '.updatedAt // empty' "$payload_file")" = \ "$(jq -r '.data.updatedAt' "$envelope_file")" jq -j '.token' "$payload_file" > "$candidate_file" test "$(wc -c < "$candidate_file")" = '64' grep -Eq '^[A-Za-z0-9_-]{64}$' "$candidate_file" chmod 600 "$candidate_file" token="$(cat "$candidate_file")" { printf 'url = "%s"\n' "$status_url" printf 'proto = "=https"\n' printf 'tlsv1.2\n' printf 'fail\nsilent\nshow-error\n' printf 'max-time = 30\n' printf 'header = "Authorization: Bearer %s"\n' "$token" } | curl --config - > "$status_file" unset token jq -e '.success == true and .data.enabled == true and .data.webhookConfigured == true' \ "$status_file" >/dev/null mv -f "$candidate_file" "$destination" chmod 600 "$destination" trap - EXIT HUP INT TERM rm -f "$envelope_file" "$payload_file" "$status_file" printf 'Bird gateway credential bootstrapped and authenticated.\n'