#!/usr/bin/env bash # Sign a Plynth robot API call with openssl, and send it with curl (7.76 or later). # GATEWAY_URL=https://... GATEWAY_ROBOT_ID=... GATEWAY_ROBOT_SECRET=... ./sign.sh [METHOD PATH [BODY]] # ./sign.sh --vector (or SIGNING_VECTOR=1 ./sign.sh): the test vectors' signatures, one per line # openssl takes the secret on its command line, where other users of this computer can see it in ps while it runs. set -euo pipefail # Hex HMAC-SHA256 keyed with the secret's own characters, over METHOD \n PATH \n TIMESTAMP \n and then the body. sign() { # secret method path timestamp [body] printf '%s\n%s\n%s\n%s' "$2" "$3" "$4" "${5:-}" | openssl dgst -sha256 -hmac "$1" | sed 's/^.*= //' } if [ "${1:-}" = "--vector" ] || [ "${SIGNING_VECTOR:-}" = "1" ]; then key=test-secret-for-docs-only-0123456789abcdef sign "$key" GET /v1/me 1767225600 sign "$key" POST /v1/passages 1767225600 '{"passage_id":"3f2b9c1e-6a4d-4e8b-9f1a-2c7d5e0b8a14","resource_id":"door"}' exit fi : "${GATEWAY_URL:?}" "${GATEWAY_ROBOT_ID:?}" "${GATEWAY_ROBOT_SECRET:?}" method=${1:-GET} path=${2:-/v1/me} body=${3:-} timestamp=$(date +%s) signature=$(sign "$GATEWAY_ROBOT_SECRET" "$method" "$path" "$timestamp" "$body") # The body goes out as the same bytes that were signed: --data-binary sends it untouched. curl -sS --fail-with-body --max-time 10 -w '\n' -X "$method" "${GATEWAY_URL%/}$path" \ -H "X-Robot-Id: $GATEWAY_ROBOT_ID" -H "X-Timestamp: $timestamp" -H "X-Signature: $signature" \ ${body:+-H 'Content-Type: application/json' --data-binary "$body"}