Hosting a Mesh Server (Advanced)

This is a minimal implementation for running a local instance of the Mesh Gateway and will require Instruxi to share a registry key to use the Docker image used below. You must reach out to your representative at Instruxi for private, production hosting options.

docker-compose.yml

version: '3.8'
services:
  redis:
    build:
      context: .
    ports:
      - "6379:6379"
    volumes:
      - ./data:/data
      - ./keys:/keys
    environment:
      - REDIS_PASSWORD=<passphrase>

  gateway:
    image: ghcr.io/instruxi-io/gateway:408.0.0
    volumes:
      - ./app.yml:/layers/golang/app/config/app.yml
      - ./.env:/layers/golang/app/.env
    ports:
      - "8081:8080"
    restart: unless-stopped
    depends_on:
      - redis

.env

BASEURL_GENERAL="https://api.spaceandtime.app/v1" # Space and Time General API Endpoint
BASEURL_DISCOVERY="https://api.spaceandtime.app/v2"  # Space and Time Discovery API Endpoint
USERID="<SXT_USER_ID>"
SCHEME="ECDSA"
JOINCODE=""

app.yml

port: ":8080"
jwt_expire_in_hr: 24h
s3:
  accessKey: ...
  secretKey: ...
  endpoint: https://gateway.storjshare.io
redis:
  uri: redis:6379
  password: ...
sxt:
  biscuits: []
  userId: ...
  publicKey: ...
  privateKey: ...
  namespace: ...
mail:
  username: ...
  password: ...
  host: smtp.gmail.com // deprectated in version 1, moved to Send Grid API
  port: 587
tmpl:
  activation_prefix: http://localhost:8080/api/v1/enforcer/auth/account/activate
self: http://localhost:8080

clear:
  host: https://verified.clearme.com
  api_key: sandbox_TEST
  secure_host: https://secure.verified.clearme.com
  hmac_key: ...
  projects:
    - id: ...
      hex: ...
      type: ...
storj:
  satellite_address: ...
  api_key: ...
opa:
  host: http://localhost
  port: 9337

entrypoint.sh

#!/bin/bash

# Configuration
KEY_NAME="CUSTOM_KEY_NAME"
KEY_TYPE="RSA"
ALG="RS256"
SIZE=2048
USE="sig"
KEYS_DIR="/data/keys"
JWKS_FILE="${KEYS_DIR}/${KEY_NAME}_jwks.json"

# Function to generate keys and JWKS
generate_keys() {
    mkdir -p "$KEYS_DIR"

    # Generate private key
    openssl genrsa -out "${KEYS_DIR}/${KEY_NAME}.pem" $SIZE

    # Extract public key
    openssl rsa -in "${KEYS_DIR}/${KEY_NAME}.pem" -pubout -out "${KEYS_DIR}/${KEY_NAME}_public.pem"

    # Generate key ID (kid) - using a hash of the public key
    KID=$(openssl rsa -in "${KEYS_DIR}/${KEY_NAME}_public.pem" -pubin -outform DER | openssl dgst -sha256 -binary | openssl enc -base64 | tr '/+' '_-' | tr -d '=')

    # Extract components for JWKS
    N=$(openssl rsa -in "${KEYS_DIR}/${KEY_NAME}.pem" -noout -modulus | cut -d'=' -f2 | xxd -r -p | base64 | tr '/+' '_-' | tr -d '=')
    E=$(openssl rsa -in "${KEYS_DIR}/${KEY_NAME}.pem" -noout -text | grep "publicExponent:" | awk '{print $2}' | xxd -r -p | base64 | tr '/+' '_-' | tr -d '=')

    # Create JWKS JSON
    cat > "$JWKS_FILE" << EOF
{
    "keys": [
        {
            "kty": "$KEY_TYPE",
            "kid": "$KID",
            "use": "$USE",
            "alg": "$ALG",
            "n": "$N",
            "e": "$E"
        }
    ]
}
EOF

    echo "Keys and JWKS generated and stored in $KEYS_DIR"
}

# Start Redis server in the background
redis-server --requirepass "$REDIS_PASSWORD" &

# Wait for Redis to be ready
until nc -z localhost 6379
do
    echo "Waiting for Redis to be ready..."
    sleep 1
done
echo "Redis is ready."

# Generate keys if JWKS doesn't exist
if [ ! -f "$JWKS_FILE" ]; then
    echo "Generating new keys and JWKS..."
    generate_keys
else
    echo "JWKS file already exists."
fi

# Store JWKS in Redis
redis-cli -a "$REDIS_PASSWORD" set jwks "$(cat $JWKS_FILE)"

echo "JWKS stored in Redis"

# Keep the container running
tail -f /dev/null

Authentication Solution Diagram

Validate Authorization w/ OPA Context