feat: four super-admin keys and production customer API security
Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m18s
CI/CD Pipeline / Security Scanning (push) Successful in 2m34s
CI/CD Pipeline / Lint and Format (push) Failing after 54s
CI/CD Pipeline / Terraform Validation (push) Failing after 27s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 28s
Deploy ChainID 138 / Deploy ChainID 138 (push) Failing after 39s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (push) Failing after 31s
Validation / validate-genesis (push) Successful in 28s
Validation / validate-terraform (push) Failing after 31s
Validation / validate-kubernetes (push) Failing after 11s
Validation / validate-smart-contracts (push) Failing after 11s
Validation / validate-security (push) Failing after 1m27s
Validation / validate-documentation (push) Failing after 21s
Verify Deployment / Verify Deployment (push) Has been cancelled
Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m18s
CI/CD Pipeline / Security Scanning (push) Successful in 2m34s
CI/CD Pipeline / Lint and Format (push) Failing after 54s
CI/CD Pipeline / Terraform Validation (push) Failing after 27s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 28s
Deploy ChainID 138 / Deploy ChainID 138 (push) Failing after 39s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (push) Failing after 31s
Validation / validate-genesis (push) Successful in 28s
Validation / validate-terraform (push) Failing after 31s
Validation / validate-kubernetes (push) Failing after 11s
Validation / validate-smart-contracts (push) Failing after 11s
Validation / validate-security (push) Failing after 1m27s
Validation / validate-documentation (push) Failing after 21s
Verify Deployment / Verify Deployment (push) Has been cancelled
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -42,6 +42,24 @@ if [ -f "$ENV_FILE" ]; then
|
||||
set +a
|
||||
fi
|
||||
|
||||
if [[ -f "$ENV_FILE" ]] && ! grep -q '^OMNL_SUPER_ADMIN_OFFICE24_KEY=' "$ENV_FILE" 2>/dev/null; then
|
||||
log "Generating four super-admin API keys..."
|
||||
bash "$REPO_DIR/scripts/deployment/seed-omnl-super-admin-keys.sh"
|
||||
set -a
|
||||
# shellcheck disable=SC1090
|
||||
source "$ENV_FILE"
|
||||
set +a
|
||||
fi
|
||||
|
||||
if [[ -f "$ENV_FILE" ]]; then
|
||||
bash "$REPO_DIR/scripts/deployment/generate-portal-nginx-auth-snippet.sh" 5827 "$REPO_DIR/deploy/nginx/omnl-portal-auth-current.conf.inc" || true
|
||||
if [[ -f "$REPO_DIR/deploy/nginx/omnl-portal-auth-current.conf.inc" ]]; then
|
||||
sudo cp "$REPO_DIR/deploy/nginx/omnl-portal-auth-current.conf.inc" /etc/nginx/omnl-portal-auth-current.conf.inc 2>/dev/null || \
|
||||
cp "$REPO_DIR/deploy/nginx/omnl-portal-auth-current.conf.inc" "$REPO_DIR/deploy/nginx/omnl-portal-auth-current.conf.inc" 2>/dev/null || true
|
||||
sudo nginx -t 2>/dev/null && sudo systemctl reload nginx 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
|
||||
build_pkg() {
|
||||
local dir="$1"
|
||||
log "Building $dir..."
|
||||
@@ -60,7 +78,8 @@ cd "$REPO_DIR/frontend-dapp"
|
||||
export VITE_TOKEN_AGGREGATION_URL="${VITE_TOKEN_AGGREGATION_URL:-/api/v1}"
|
||||
export VITE_SETTLEMENT_MIDDLEWARE_URL="${VITE_SETTLEMENT_MIDDLEWARE_URL:-/settlement}"
|
||||
export VITE_DBIS_EXCHANGE_URL="${VITE_DBIS_EXCHANGE_URL:-/exchange}"
|
||||
export VITE_OMNL_API_KEY="${VITE_OMNL_API_KEY:-${OMNL_API_KEY:-}}"
|
||||
# Never embed operator API keys in production frontend — nginx injects server-side.
|
||||
unset VITE_OMNL_API_KEY
|
||||
if command -v pnpm >/dev/null 2>&1; then
|
||||
pnpm install --frozen-lockfile 2>/dev/null || pnpm install
|
||||
pnpm run build
|
||||
@@ -84,7 +103,15 @@ start_svc() {
|
||||
DBIS_EXCHANGE_CONFIG="$DBIS_EXCHANGE_CONFIG" \
|
||||
OMNL_SUPPORTED_CHAINS_CONFIG="$OMNL_SUPPORTED_CHAINS_CONFIG" \
|
||||
OMNL_M2_TOKEN_REGISTRY="$OMNL_M2_TOKEN_REGISTRY" \
|
||||
OMNL_API_KEY="${OMNL_API_KEY:-}" \
|
||||
OMNL_API_KEY="${OMNL_API_KEY:-${OMNL_SUPER_ADMIN_SECURE_KEY:-}}" \
|
||||
OMNL_SUPER_ADMIN_OFFICE24_KEY="${OMNL_SUPER_ADMIN_OFFICE24_KEY:-}" \
|
||||
OMNL_SUPER_ADMIN_EXCHANGE_KEY="${OMNL_SUPER_ADMIN_EXCHANGE_KEY:-}" \
|
||||
OMNL_SUPER_ADMIN_SECURE_KEY="${OMNL_SUPER_ADMIN_SECURE_KEY:-}" \
|
||||
OMNL_SUPER_ADMIN_FOREX_KEY="${OMNL_SUPER_ADMIN_FOREX_KEY:-}" \
|
||||
OMNL_PORTAL_INTERNAL_SECRET="${OMNL_PORTAL_INTERNAL_SECRET:-}" \
|
||||
OMNL_CUSTOMER_API_KEYS="${OMNL_CUSTOMER_API_KEYS:-}" \
|
||||
OMNL_CUSTOMER_SECURITY_PRODUCTION="${OMNL_CUSTOMER_SECURITY_PRODUCTION:-1}" \
|
||||
OMNL_BANK_ROOT="$REPO_DIR" \
|
||||
OMNL_FINERACT_BASE_URL="${OMNL_FINERACT_BASE_URL:-${FINERACT_BASE_URL:-}}" \
|
||||
OMNL_FINERACT_TENANT="${OMNL_FINERACT_TENANT:-${FINERACT_TENANT:-omnl}}" \
|
||||
OMNL_FINERACT_USER="${OMNL_FINERACT_USER:-}" \
|
||||
|
||||
47
scripts/deployment/generate-portal-nginx-auth-snippet.sh
Normal file
47
scripts/deployment/generate-portal-nginx-auth-snippet.sh
Normal file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env bash
|
||||
# Write nginx auth snippet for portal (injects super-admin Bearer + internal header server-side).
|
||||
set -euo pipefail
|
||||
|
||||
REPO_DIR="${OMNL_BANK_ROOT:-$HOME/smom-dbis-138}"
|
||||
ENV_FILE="${OMNL_BANK_ENV:-$REPO_DIR/.env}"
|
||||
CTID="${1:-5827}"
|
||||
OUT="${2:-$REPO_DIR/deploy/nginx/omnl-portal-auth-${CTID}.conf.inc}"
|
||||
|
||||
CONFIG="$REPO_DIR/config/omnl-super-admins.v1.json"
|
||||
|
||||
if [[ ! -f "$ENV_FILE" ]]; then
|
||||
echo "Missing $ENV_FILE" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -a
|
||||
# shellcheck disable=SC1090
|
||||
source "$ENV_FILE"
|
||||
set +a
|
||||
|
||||
ENV_KEY="$(node -e "
|
||||
const fs = require('fs');
|
||||
const cfg = JSON.parse(fs.readFileSync('$CONFIG', 'utf8'));
|
||||
const ct = Number('$CTID');
|
||||
const admin = cfg.superAdmins.find(a => a.portalCtid === ct);
|
||||
if (!admin) process.exit(2);
|
||||
console.log(admin.envKey);
|
||||
")"
|
||||
|
||||
API_KEY="${!ENV_KEY:-${OMNL_API_KEY:-}}"
|
||||
INTERNAL="${OMNL_PORTAL_INTERNAL_SECRET:-}"
|
||||
|
||||
if [[ -z "$API_KEY" ]]; then
|
||||
echo "No API key for CT $CTID ($ENV_KEY unset)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$(dirname "$OUT")"
|
||||
cat >"$OUT" <<EOF
|
||||
# Auto-generated — do not commit. CT $CTID portal upstream auth.
|
||||
proxy_set_header Authorization "Bearer ${API_KEY}";
|
||||
proxy_set_header X-OMNL-Portal-Auth "${INTERNAL}";
|
||||
EOF
|
||||
|
||||
chmod 600 "$OUT"
|
||||
echo "Wrote $OUT"
|
||||
@@ -6,6 +6,7 @@ CTID="${1:?CTID required}"
|
||||
REPO_DIR="${OMNL_BANK_ROOT:-$HOME/smom-dbis-138}"
|
||||
ENV_FILE="${OMNL_BANK_ENV:-$REPO_DIR/.env}"
|
||||
PORTAL_ROOT="${OMNL_PORTAL_ROOT:-/srv/zardasht-portal}"
|
||||
CONFIG="$REPO_DIR/config/omnl-super-admins.v1.json"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=lib/omnl-pve-ssh.sh
|
||||
source "${SCRIPT_DIR}/lib/omnl-pve-ssh.sh"
|
||||
@@ -17,8 +18,32 @@ if [[ ! -f "$ENV_FILE" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -a
|
||||
# shellcheck disable=SC1090
|
||||
source "$ENV_FILE"
|
||||
set +a
|
||||
|
||||
FRAG="$(mktemp)"
|
||||
grep -E '^(OMNL_FINERACT_|OMNL_API_KEY=|OMNL_PUBLIC_MONEY_SUPPLY=|OMNL_REQUIRE_API_KEY=|OFFICE24_OPENING_M1_USD=)' "$ENV_FILE" >"$FRAG" || true
|
||||
grep -E '^(OMNL_FINERACT_|OMNL_PUBLIC_MONEY_SUPPLY=|OMNL_REQUIRE_API_KEY=|OFFICE24_OPENING_M1_USD=|OMNL_PORTAL_INTERNAL_SECRET=|OMNL_CUSTOMER_SECURITY_PRODUCTION=|JWT_SECRET=)' "$ENV_FILE" >"$FRAG" || true
|
||||
|
||||
ADMIN_ENV_KEY="$(node -e "
|
||||
const fs = require('fs');
|
||||
const cfg = JSON.parse(fs.readFileSync('$CONFIG', 'utf8'));
|
||||
const ct = Number('$CTID');
|
||||
const admin = cfg.superAdmins.find(a => a.portalCtid === ct);
|
||||
if (!admin) process.exit(0);
|
||||
console.log(admin.envKey);
|
||||
" 2>/dev/null || true)"
|
||||
|
||||
if [[ -n "$ADMIN_ENV_KEY" ]]; then
|
||||
ADMIN_VAL="${!ADMIN_ENV_KEY:-}"
|
||||
if [[ -n "$ADMIN_VAL" ]]; then
|
||||
echo "OMNL_API_KEY=${ADMIN_VAL}" >>"$FRAG"
|
||||
log "Mapped CT $CTID → $ADMIN_ENV_KEY as OMNL_API_KEY"
|
||||
fi
|
||||
elif [[ -n "${OMNL_API_KEY:-}" ]]; then
|
||||
echo "OMNL_API_KEY=${OMNL_API_KEY}" >>"$FRAG"
|
||||
fi
|
||||
|
||||
if [[ ! -s "$FRAG" ]]; then
|
||||
log "No Fineract/API keys found in $ENV_FILE — skip CT $CTID"
|
||||
@@ -29,6 +54,14 @@ fi
|
||||
log "Pushing portal env keys to CT $CTID..."
|
||||
omnl_pve_scp "$FRAG" "${OMNL_PVE_SSH_TARGET}:/tmp/omnl-portal-env.frag"
|
||||
rm -f "$FRAG"
|
||||
|
||||
if [[ -n "$ADMIN_ENV_KEY" ]] && [[ -n "${!ADMIN_ENV_KEY:-}" ]]; then
|
||||
bash "$SCRIPT_DIR/generate-portal-nginx-auth-snippet.sh" "$CTID" "$REPO_DIR/deploy/nginx/omnl-portal-auth-${CTID}.conf.inc"
|
||||
omnl_pve_scp "$REPO_DIR/deploy/nginx/omnl-portal-auth-${CTID}.conf.inc" "${OMNL_PVE_SSH_TARGET}:/tmp/omnl-portal-auth.conf.inc"
|
||||
omnl_pve_ssh "pct push ${CTID} /tmp/omnl-portal-auth.conf.inc ${PORTAL_ROOT}/deploy/nginx/omnl-portal-auth-current.conf.inc"
|
||||
omnl_pve_ssh "pct exec ${CTID} -- chmod 600 ${PORTAL_ROOT}/deploy/nginx/omnl-portal-auth-current.conf.inc"
|
||||
fi
|
||||
|
||||
omnl_pve_ssh "pct push ${CTID} /tmp/omnl-portal-env.frag /tmp/omnl-portal-env.frag"
|
||||
|
||||
omnl_pve_ssh "pct exec ${CTID} -- bash -s" <<EOF
|
||||
|
||||
53
scripts/deployment/seed-omnl-super-admin-keys.sh
Normal file
53
scripts/deployment/seed-omnl-super-admin-keys.sh
Normal file
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env bash
|
||||
# Generate four super-admin API keys + portal internal secret in .env (idempotent).
|
||||
set -euo pipefail
|
||||
|
||||
REPO_DIR="${OMNL_BANK_ROOT:-$HOME/smom-dbis-138}"
|
||||
ENV_FILE="${OMNL_BANK_ENV:-$REPO_DIR/.env}"
|
||||
CONFIG="$REPO_DIR/config/omnl-super-admins.v1.json"
|
||||
|
||||
log() { echo "[$(date -Iseconds)] $*"; }
|
||||
|
||||
gen_key() {
|
||||
if command -v openssl >/dev/null 2>&1; then
|
||||
openssl rand -hex 32
|
||||
else
|
||||
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_kv() {
|
||||
local key="$1"
|
||||
local val="$2"
|
||||
if grep -q "^${key}=" "$ENV_FILE" 2>/dev/null; then
|
||||
log " $key already set — skip"
|
||||
else
|
||||
echo "${key}=${val}" >>"$ENV_FILE"
|
||||
log " $key generated"
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ ! -f "$ENV_FILE" ]]; then
|
||||
touch "$ENV_FILE"
|
||||
chmod 600 "$ENV_FILE"
|
||||
fi
|
||||
|
||||
log "Seeding OMNL super-admin keys into $ENV_FILE"
|
||||
|
||||
node -e "
|
||||
const fs = require('fs');
|
||||
const cfg = JSON.parse(fs.readFileSync('$CONFIG', 'utf8'));
|
||||
for (const a of cfg.superAdmins) console.log(a.envKey);
|
||||
" | while read -r env_key; do
|
||||
ensure_kv "$env_key" "$(gen_key)"
|
||||
done
|
||||
|
||||
ensure_kv "OMNL_PORTAL_INTERNAL_SECRET" "$(gen_key)"
|
||||
ensure_kv "OMNL_CUSTOMER_SECURITY_PRODUCTION" "1"
|
||||
ensure_kv "OMNL_REQUIRE_API_KEY" "1"
|
||||
|
||||
if ! grep -q '^JWT_SECRET=' "$ENV_FILE" 2>/dev/null; then
|
||||
ensure_kv "JWT_SECRET" "$(gen_key)"
|
||||
fi
|
||||
|
||||
log "Super-admin key env vars ready. Map each LXC CTID to its portal key via push-portal-env-to-lxc.sh"
|
||||
Reference in New Issue
Block a user