Skip to content

Releases: hkjang/vibe-coders

v0.85.2 - AI Proxy Gateway

Choose a tag to compare

@hkjang hkjang released this 12 Sep 12:03

AI Proxy Gateway v0.85.2

주요 변경 사항

  • 콘솔을 키보드로 움직이고, 첫 화면이 할 일을 알려주고, 워크플로를 조립해 만든다 (v0.85.2): 2026년 AI 게이트웨이 제품·콘솔 UX 자료를 조사해 구현 상태와 대조한 뒤, 실제로 비어 있던 세 곳을 채웠다. 명령 팔레트가 화면 이동만 하던 것을 명령·최근 화면·ID 바로 찾기까지 다루도록 했다 — 지금 새로고침, 테마·정보 밀도·자동 갱신 주기 전환, 사이드바 접기를 헤더 메뉴를 찾지 않고 실행하고, 검색창을 비우면 방금 보던 화면이 먼저 나오며, 요청·추적·세션 ID를 붙여넣으면 해당 요청으로 직행한다(값이 URL 쿼리에 들어가므로 필터 폼과 같은 검사로 자격 증명처럼 보이는 문자열은 거부하고 퍼센트 인코딩한다). ? 로 단축키 시트를 열 수 있게 해 Ctrl+K 의 존재를 알 방법을 만들었고, 입력 칸에 포커스가 있을 때는 물음표가 그냥 물음표로 남는다. 아직 한 건도 처리하지 않은 게이트웨이의 통합 현황은 모든 패널이 0이라 무엇을 설정해야 하는지 알려주지 못했다 — 공급자 연결·인증 켜기·모델 가격 설정·첫 요청 보내기 네 단계를 게이트웨이가 보고하는 값에서 판정해 보여주고, 요청이 들어오면 스스로 사라진다. 특히 가격 설정이 빠지면 비용·예산·절감 화면이 0으로 남아 고장으로 보이던 문제를 표면화한다. 워크플로 정의는 JSON 배열을 직접 타이핑해야 했는데, 서버가 이미 타입이 잡힌 단계 모델을 갖고 있었으므로 단계 편집기로 바꿨다 — 종류를 골라 추가하고 순서를 바꾸며, 그 종류가 쓰는 항목만 표시한다(채팅은 모델과 상한, MCP 는 허용 도구, Text2SQL 은 허용 테이블). 폼이 같은 JSON 문자열을 유지하므로 검증과 요청 본문은 그대로이고 JSON 뷰가 정확한 대안으로 남으며, 이 빌드가 모르는 필드를 가진 단계는 값을 보존하고 그 사실을 화면에 적는다. 한도를 비우면 0 대신 항목을 제거한다 — 서버는 상한이 없으면 제한 없음, 0 이면 진짜 0 으로 읽는다.

배포 파일

파일 설명
ai-coding-proxy-gateway-v0.85.2.tar.gz Docker 이미지 패키지 (linux/amd64)
ai-coding-proxy-gateway-v0.85.2.tar.gz.sha256 SHA256 체크섬
README-offline-v0.85.2.md 오프라인 배포 가이드
SBOM-v0.85.2.spdx.json Go+npm 통합 SPDX SBOM
THIRD_PARTY_LICENSES-v0.85.2.md Go·Frontend 제3자 라이선스 목록
init-deployment-env-v0.85.2.sh 운영 env 원자 생성·검증 helper
backup-volume-v0.85.2.sh named volume·env 백업·복구 helper

빠른 시작

# 이미지 로드
gunzip -c ai-coding-proxy-gateway-v0.85.2.tar.gz | docker load

# 최초 1회 비밀값 파일과 nonroot 호환 named volume 준비
ENV_FILE=/opt/proxy-gateway/gateway.env
install -d -m 0700 "$(dirname "$ENV_FILE")" || exit 1
command -v openssl >/dev/null 2>&1 || { echo "openssl이 필요합니다." >&2; exit 1; }
if [ ! -e "$ENV_FILE" ]; then
  umask 077
  ADMIN_TOKEN_VALUE="$(openssl rand -hex 32)" || exit 1
  GATEWAY_SECRET_VALUE="$(openssl rand -hex 32)" || exit 1
  [ "${#ADMIN_TOKEN_VALUE}" -eq 64 ] && [ "${#GATEWAY_SECRET_VALUE}" -eq 64 ] || exit 1
  printf '%s\n' "$ADMIN_TOKEN_VALUE" | grep -Eq '^[0-9A-Fa-f]{64}$' && 
    printf '%s\n' "$GATEWAY_SECRET_VALUE" | grep -Eq '^[0-9A-Fa-f]{64}$' || exit 1
  UPSTREAM_API_KEY_VALUE="${UPSTREAM_API_KEY:-}"
  if [ -z "$UPSTREAM_API_KEY_VALUE" ]; then
    read -r -s -p 'Upstream API key: ' UPSTREAM_API_KEY_VALUE || exit 1
    echo
  fi
  case "$UPSTREAM_API_KEY_VALUE" in
    ''|*[!A-Za-z0-9._~:/+=-]*) echo 'UPSTREAM_API_KEY 형식이 안전하지 않습니다.' >&2; exit 1 ;;
  esac
  ENV_TMP="$(mktemp "${ENV_FILE}.tmp.XXXXXX")" || exit 1
  trap 'rm -f -- "$ENV_TMP"' EXIT HUP INT TERM
  {
    echo 'UPSTREAM_BASE_URL=https://api.openai.com'
    echo "UPSTREAM_API_KEY=${UPSTREAM_API_KEY_VALUE}"
    echo 'GATEWAY_VERSION=v0.85.2'
    echo "ADMIN_TOKEN=${ADMIN_TOKEN_VALUE}"
    echo "GATEWAY_SECRET=${GATEWAY_SECRET_VALUE}"
    echo 'UI_APP_ENABLED=false'
  } > "$ENV_TMP" || exit 1
  chmod 0600 "$ENV_TMP" && mv -f -- "$ENV_TMP" "$ENV_FILE" || exit 1
  trap - EXIT HUP INT TERM
fi
chmod 0600 "$ENV_FILE" || exit 1
[ "$(grep -Ec '^ADMIN_TOKEN=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^ADMIN_TOKEN=[0-9A-Fa-f]{64}$' "$ENV_FILE" && 
  [ "$(grep -Ec '^GATEWAY_SECRET=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^GATEWAY_SECRET=[0-9A-Fa-f]{64}$' "$ENV_FILE" && 
  [ "$(grep -Ec '^UPSTREAM_API_KEY=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^UPSTREAM_API_KEY=[A-Za-z0-9._~:/+=-]+$' "$ENV_FILE" && 
  ! grep -q '^UPSTREAM_API_KEY=replace-before-start$' "$ENV_FILE" && 
  [ "$(grep -Ec '^GATEWAY_VERSION=' "$ENV_FILE")" -eq 1 ] && 
  grep -qxF 'GATEWAY_VERSION=v0.85.2' "$ENV_FILE" || 
  { echo "gateway.env의 필수 비밀값이 유효하지 않습니다." >&2; exit 1; }
docker volume create proxy-gateway-data >/dev/null || exit 1

# 기존 볼륨·바인드 마운트 재사용 시 nonroot(65532) 소유권 복구 (새 볼륨은 변경 없음)
docker run --rm --user 0:0 --mount source=proxy-gateway-data,target=/data ai-coding-proxy-gateway:v0.85.2 repair-data-dir || exit 1

docker run -d --name proxy-gateway --restart=always \
  -p 8080:8080 \
  --mount source=proxy-gateway-data,target=/data \
  --env-file "$ENV_FILE" \
  ai-coding-proxy-gateway:v0.85.2
  • Legacy Stable Console: http://localhost:8080/admin
  • Next Console Preview: http://localhost:8080/app/ (/app is OFF unless UI_APP_ENABLED=true)
  • React assets are embedded in the Go binary; the runtime image does not contain Node.js.
  • Reuse and back up the same 0600 env file; rotating GATEWAY_SECRET without migration makes stored Provider Secrets unreadable.
  • Transfer, checksum, and chmod 0700 the bundled init-deployment-env-v0.85.2.sh and backup-volume-v0.85.2.sh helpers.
  • The init helper preserves secrets and atomically updates only GATEWAY_VERSION during upgrades.
  • If the container restarts and 8080 never opens with 'readonly database' in docker logs, /data was written by another user: run the repair-data-dir command above once, then verify with: docker run --rm --mount source=proxy-gateway-data,target=/data ai-coding-proxy-gateway:v0.85.2 check-data-dir

v0.85.0 - AI Proxy Gateway

Choose a tag to compare

@hkjang hkjang released this 10 Sep 11:06

AI Proxy Gateway v0.85.0

주요 변경 사항

  • 감사가 놓치던 화면 15개를 /app으로 이식하고, 조작 URL이 다른 리소스를 지우던 결함을 수정 (v0.85.0): Legacy 콘솔과 /app 콘솔의 격차를 CI가 기계적으로 검사하도록 하고(cmd/api-surface-audit), 그 검사가 스스로 놓치던 두 허점을 막았다. 생성된 OpenAPI 타입 디렉터리를 비교 대상에 포함하고 있어 Legacy 콘솔을 /app 콘솔이 아니라 카탈로그와 비교했고, Legacy 호출의 첫 문자열만 읽어 '/admin/requests/' + id + '/trace'/admin/requests/ 로 잘리면서 이어붙인 경로 아래 모든 하위 동작이 이식된 것으로 계산됐다. 둘을 막자 /app이 한 번도 호출하지 않던 엔드포인트 15건이 드러났고 전부 이식했다 — 운영 홈(운영 신호 카드·장애 후보·백그라운드 워커·배포 프리플라이트·인덱스 드리프트와 추가 삭제 후보·마이그레이션 SQL 전문, 모두 읽기 전용), 요청 상세의 종단 간 스팬 워터폴과 연관 기록 집계, 요청 탐색기의 필터 자동완성과 두 요청 비교, 통합 현황의 사용 추이 차트와 요일·시간대 히트맵, 데이터 인사이트의 비용 절감·모델 전환 추천, 시스템 설정의 지식 캐시. 함께 고친 서버 결함: 서브 액션 URL이 부모 리소스에 작용해 DELETE /admin/prompt-lab/test-cases/{id}/run 이 테스트 케이스를, .../dw/metrics/{key}/validate 가 지표를, /admin/apps/{id}/publish 가 앱을 삭제하던 문제(URL은 실행·검증·발행을 가리키는데 서버는 삭제를 수행했고 오류조차 없었다), GET /admin/dw/dashboard/refresh 가 조회만으로 DW 캐시를 비우고 감사 기록을 남기던 문제, MCP 업스트림 프로브가 GET 이라 읽기 전용 권한으로도 등록된 모든 업스트림에 외부 연결을 발생시킬 수 있던 문제(POST 로 변경, mcp:admin 필요). 문서와 구현이 어긋나 호출할 수 없던 계약 3건도 바로잡았다 — 골든 쿼리 삭제(경로가 아닌 ?id=), 지식 항목 수정(PATCH), 자동 라우팅 학습 상태 조회(GET). 프런트엔드 의존성 js-yaml 을 4.3.2 로 올려 GHSA-2883-xcg3-v3hh 를 해소했다.

배포 파일

파일 설명
ai-coding-proxy-gateway-v0.85.0.tar.gz Docker 이미지 패키지 (linux/amd64)
ai-coding-proxy-gateway-v0.85.0.tar.gz.sha256 SHA256 체크섬
README-offline-v0.85.0.md 오프라인 배포 가이드
SBOM-v0.85.0.spdx.json Go+npm 통합 SPDX SBOM
THIRD_PARTY_LICENSES-v0.85.0.md Go·Frontend 제3자 라이선스 목록
init-deployment-env-v0.85.0.sh 운영 env 원자 생성·검증 helper
backup-volume-v0.85.0.sh named volume·env 백업·복구 helper

빠른 시작

# 이미지 로드
gunzip -c ai-coding-proxy-gateway-v0.85.0.tar.gz | docker load

# 최초 1회 비밀값 파일과 nonroot 호환 named volume 준비
ENV_FILE=/opt/proxy-gateway/gateway.env
install -d -m 0700 "$(dirname "$ENV_FILE")" || exit 1
command -v openssl >/dev/null 2>&1 || { echo "openssl이 필요합니다." >&2; exit 1; }
if [ ! -e "$ENV_FILE" ]; then
  umask 077
  ADMIN_TOKEN_VALUE="$(openssl rand -hex 32)" || exit 1
  GATEWAY_SECRET_VALUE="$(openssl rand -hex 32)" || exit 1
  [ "${#ADMIN_TOKEN_VALUE}" -eq 64 ] && [ "${#GATEWAY_SECRET_VALUE}" -eq 64 ] || exit 1
  printf '%s\n' "$ADMIN_TOKEN_VALUE" | grep -Eq '^[0-9A-Fa-f]{64}$' && 
    printf '%s\n' "$GATEWAY_SECRET_VALUE" | grep -Eq '^[0-9A-Fa-f]{64}$' || exit 1
  UPSTREAM_API_KEY_VALUE="${UPSTREAM_API_KEY:-}"
  if [ -z "$UPSTREAM_API_KEY_VALUE" ]; then
    read -r -s -p 'Upstream API key: ' UPSTREAM_API_KEY_VALUE || exit 1
    echo
  fi
  case "$UPSTREAM_API_KEY_VALUE" in
    ''|*[!A-Za-z0-9._~:/+=-]*) echo 'UPSTREAM_API_KEY 형식이 안전하지 않습니다.' >&2; exit 1 ;;
  esac
  ENV_TMP="$(mktemp "${ENV_FILE}.tmp.XXXXXX")" || exit 1
  trap 'rm -f -- "$ENV_TMP"' EXIT HUP INT TERM
  {
    echo 'UPSTREAM_BASE_URL=https://api.openai.com'
    echo "UPSTREAM_API_KEY=${UPSTREAM_API_KEY_VALUE}"
    echo 'GATEWAY_VERSION=v0.85.0'
    echo "ADMIN_TOKEN=${ADMIN_TOKEN_VALUE}"
    echo "GATEWAY_SECRET=${GATEWAY_SECRET_VALUE}"
    echo 'UI_APP_ENABLED=false'
  } > "$ENV_TMP" || exit 1
  chmod 0600 "$ENV_TMP" && mv -f -- "$ENV_TMP" "$ENV_FILE" || exit 1
  trap - EXIT HUP INT TERM
fi
chmod 0600 "$ENV_FILE" || exit 1
[ "$(grep -Ec '^ADMIN_TOKEN=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^ADMIN_TOKEN=[0-9A-Fa-f]{64}$' "$ENV_FILE" && 
  [ "$(grep -Ec '^GATEWAY_SECRET=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^GATEWAY_SECRET=[0-9A-Fa-f]{64}$' "$ENV_FILE" && 
  [ "$(grep -Ec '^UPSTREAM_API_KEY=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^UPSTREAM_API_KEY=[A-Za-z0-9._~:/+=-]+$' "$ENV_FILE" && 
  ! grep -q '^UPSTREAM_API_KEY=replace-before-start$' "$ENV_FILE" && 
  [ "$(grep -Ec '^GATEWAY_VERSION=' "$ENV_FILE")" -eq 1 ] && 
  grep -qxF 'GATEWAY_VERSION=v0.85.0' "$ENV_FILE" || 
  { echo "gateway.env의 필수 비밀값이 유효하지 않습니다." >&2; exit 1; }
docker volume create proxy-gateway-data >/dev/null || exit 1

# 기존 볼륨·바인드 마운트 재사용 시 nonroot(65532) 소유권 복구 (새 볼륨은 변경 없음)
docker run --rm --user 0:0 --mount source=proxy-gateway-data,target=/data ai-coding-proxy-gateway:v0.85.0 repair-data-dir || exit 1

docker run -d --name proxy-gateway --restart=always \
  -p 8080:8080 \
  --mount source=proxy-gateway-data,target=/data \
  --env-file "$ENV_FILE" \
  ai-coding-proxy-gateway:v0.85.0
  • Legacy Stable Console: http://localhost:8080/admin
  • Next Console Preview: http://localhost:8080/app/ (/app is OFF unless UI_APP_ENABLED=true)
  • React assets are embedded in the Go binary; the runtime image does not contain Node.js.
  • Reuse and back up the same 0600 env file; rotating GATEWAY_SECRET without migration makes stored Provider Secrets unreadable.
  • Transfer, checksum, and chmod 0700 the bundled init-deployment-env-v0.85.0.sh and backup-volume-v0.85.0.sh helpers.
  • The init helper preserves secrets and atomically updates only GATEWAY_VERSION during upgrades.
  • If the container restarts and 8080 never opens with 'readonly database' in docker logs, /data was written by another user: run the repair-data-dir command above once, then verify with: docker run --rm --mount source=proxy-gateway-data,target=/data ai-coding-proxy-gateway:v0.85.0 check-data-dir

v0.84.1 - AI Proxy Gateway

Choose a tag to compare

@hkjang hkjang released this 07 Sep 09:03

AI Proxy Gateway v0.84.1

주요 변경 사항

  • 조회만 해도 기록되던 관리 API를 읽기 전용으로 수정 (v0.84.1): GET /admin/anomalies 가 응답을 만드는 김에 이상 이벤트를 저장하고 알림까지 보내던 문제를 수정했다. 대시보드를 새로 고칠 때마다 같은 구간이 다시 채점되어, 급증을 지켜보던 운영자가 중복 이벤트와 알림을 스스로 만들어 내고 있었다. 이제 기록과 알림은 게이트웨이 내부 워커가 5분마다 수행하며(기준선 7일, 최근 1시간, z=3, 최소 15분 중복 억제), 엔드포인트는 읽기만 한다. GET /admin/personalization/profiles/{user_id}?snapshot=1 이 스냅샷을 기록하던 문제도 수정했다. 크롤러·프리페치·브라우저 재시도만으로 스냅샷 이력이 조용히 늘어날 수 있었으므로, 기록은 같은 경로의 POST 에서만 일어나고 GET 은 어떤 형태로 호출해도 상태를 바꾸지 않는다. 레거시 콘솔은 POST 로 스냅샷을 남기고, React 콘솔은 이상 징후를 안전하게 조회하려고 붙이던 record=0 우회를 제거했다. 두 결함을 각각 되살려 회귀 테스트가 실제로 실패하는지 확인했다.

배포 파일

파일 설명
ai-coding-proxy-gateway-v0.84.1.tar.gz Docker 이미지 패키지 (linux/amd64)
ai-coding-proxy-gateway-v0.84.1.tar.gz.sha256 SHA256 체크섬
README-offline-v0.84.1.md 오프라인 배포 가이드
SBOM-v0.84.1.spdx.json Go+npm 통합 SPDX SBOM
THIRD_PARTY_LICENSES-v0.84.1.md Go·Frontend 제3자 라이선스 목록
init-deployment-env-v0.84.1.sh 운영 env 원자 생성·검증 helper
backup-volume-v0.84.1.sh named volume·env 백업·복구 helper

빠른 시작

# 이미지 로드
gunzip -c ai-coding-proxy-gateway-v0.84.1.tar.gz | docker load

# 최초 1회 비밀값 파일과 nonroot 호환 named volume 준비
ENV_FILE=/opt/proxy-gateway/gateway.env
install -d -m 0700 "$(dirname "$ENV_FILE")" || exit 1
command -v openssl >/dev/null 2>&1 || { echo "openssl이 필요합니다." >&2; exit 1; }
if [ ! -e "$ENV_FILE" ]; then
  umask 077
  ADMIN_TOKEN_VALUE="$(openssl rand -hex 32)" || exit 1
  GATEWAY_SECRET_VALUE="$(openssl rand -hex 32)" || exit 1
  [ "${#ADMIN_TOKEN_VALUE}" -eq 64 ] && [ "${#GATEWAY_SECRET_VALUE}" -eq 64 ] || exit 1
  printf '%s\n' "$ADMIN_TOKEN_VALUE" | grep -Eq '^[0-9A-Fa-f]{64}$' && 
    printf '%s\n' "$GATEWAY_SECRET_VALUE" | grep -Eq '^[0-9A-Fa-f]{64}$' || exit 1
  UPSTREAM_API_KEY_VALUE="${UPSTREAM_API_KEY:-}"
  if [ -z "$UPSTREAM_API_KEY_VALUE" ]; then
    read -r -s -p 'Upstream API key: ' UPSTREAM_API_KEY_VALUE || exit 1
    echo
  fi
  case "$UPSTREAM_API_KEY_VALUE" in
    ''|*[!A-Za-z0-9._~:/+=-]*) echo 'UPSTREAM_API_KEY 형식이 안전하지 않습니다.' >&2; exit 1 ;;
  esac
  ENV_TMP="$(mktemp "${ENV_FILE}.tmp.XXXXXX")" || exit 1
  trap 'rm -f -- "$ENV_TMP"' EXIT HUP INT TERM
  {
    echo 'UPSTREAM_BASE_URL=https://api.openai.com'
    echo "UPSTREAM_API_KEY=${UPSTREAM_API_KEY_VALUE}"
    echo 'GATEWAY_VERSION=v0.84.1'
    echo "ADMIN_TOKEN=${ADMIN_TOKEN_VALUE}"
    echo "GATEWAY_SECRET=${GATEWAY_SECRET_VALUE}"
    echo 'UI_APP_ENABLED=false'
  } > "$ENV_TMP" || exit 1
  chmod 0600 "$ENV_TMP" && mv -f -- "$ENV_TMP" "$ENV_FILE" || exit 1
  trap - EXIT HUP INT TERM
fi
chmod 0600 "$ENV_FILE" || exit 1
[ "$(grep -Ec '^ADMIN_TOKEN=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^ADMIN_TOKEN=[0-9A-Fa-f]{64}$' "$ENV_FILE" && 
  [ "$(grep -Ec '^GATEWAY_SECRET=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^GATEWAY_SECRET=[0-9A-Fa-f]{64}$' "$ENV_FILE" && 
  [ "$(grep -Ec '^UPSTREAM_API_KEY=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^UPSTREAM_API_KEY=[A-Za-z0-9._~:/+=-]+$' "$ENV_FILE" && 
  ! grep -q '^UPSTREAM_API_KEY=replace-before-start$' "$ENV_FILE" && 
  [ "$(grep -Ec '^GATEWAY_VERSION=' "$ENV_FILE")" -eq 1 ] && 
  grep -qxF 'GATEWAY_VERSION=v0.84.1' "$ENV_FILE" || 
  { echo "gateway.env의 필수 비밀값이 유효하지 않습니다." >&2; exit 1; }
docker volume create proxy-gateway-data >/dev/null || exit 1

# 기존 볼륨·바인드 마운트 재사용 시 nonroot(65532) 소유권 복구 (새 볼륨은 변경 없음)
docker run --rm --user 0:0 --mount source=proxy-gateway-data,target=/data ai-coding-proxy-gateway:v0.84.1 repair-data-dir || exit 1

docker run -d --name proxy-gateway --restart=always \
  -p 8080:8080 \
  --mount source=proxy-gateway-data,target=/data \
  --env-file "$ENV_FILE" \
  ai-coding-proxy-gateway:v0.84.1
  • Legacy Stable Console: http://localhost:8080/admin
  • Next Console Preview: http://localhost:8080/app/ (/app is OFF unless UI_APP_ENABLED=true)
  • React assets are embedded in the Go binary; the runtime image does not contain Node.js.
  • Reuse and back up the same 0600 env file; rotating GATEWAY_SECRET without migration makes stored Provider Secrets unreadable.
  • Transfer, checksum, and chmod 0700 the bundled init-deployment-env-v0.84.1.sh and backup-volume-v0.84.1.sh helpers.
  • The init helper preserves secrets and atomically updates only GATEWAY_VERSION during upgrades.
  • If the container restarts and 8080 never opens with 'readonly database' in docker logs, /data was written by another user: run the repair-data-dir command above once, then verify with: docker run --rm --mount source=proxy-gateway-data,target=/data ai-coding-proxy-gateway:v0.84.1 check-data-dir

v0.84.0 - AI Proxy Gateway

Choose a tag to compare

@hkjang hkjang released this 07 Sep 07:12

AI Proxy Gateway v0.84.0

주요 변경 사항

  • Legacy 콘솔의 모든 화면을 신규 /app 콘솔로 이식 (v0.84.0): 읽기 전용 미리보기 7개뿐이던 React 콘솔이 등록된 36개 기능 전부를 소유한다. 13개 도메인을 레거시 자바스크립트가 아니라 Go 핸들러를 근거로 이식해, 조회뿐 아니라 /admin이 제공하던 생성·수정·삭제·실행·내보내기를 동일하게 제공한다. 사용자·팀·API 키·IP·할당량·역할, 내 홈과 팀 포털, Chat 테스트(SSE 스트리밍·멀티 모델 비교·평가·승격·Golden)와 프롬프트 실험실, 공급자·모델·모델 계약·지원 종료 관리, 라우팅 규칙·미리보기·결정 이력·장애 전환·학습 엔진·회로 차단기, 세션 비행기록·XView 실시간 산점도·LLM 관측·진단 프로브, 프롬프트 검색과 자산 검토·승인·롤백·부채, 안전 정책·Kill Switch·알림 규칙·모델 일몰·정책 어드바이저·자동 조치, 팀 성숙도·운영 보고서·AI 업무성과·SBOM·개인화, MCP 업스트림·도구·정책·요청 워터폴과 에이전트 라우트·워크플로·앱·Skill, Text2SQL 전 영역, DW 대시보드·ClickHouse·데이터 상품, 비용 대시보드·배부·예산, 보안 대시보드·프라이버시 원장·Red Team·샌드박스, 시스템 설정·런타임 설정·변경 세트·SSO·감사 이력과 /app 전환 설정을 포함한다. 화면이 자기 라우트와 URL 쿼리 키를 직접 선언하는 도메인 등록부를 도입해 라우터·쿼리 허용 목록·구현 판정이 한 곳에서 갈라지며, 선언하지 않은 쿼리 키는 제거되어 비밀값과 프롬프트가 주소창에 남지 않는다. 정적 쿼리 허용 목록이 화면 선언을 가려 라우팅 화면의 필터 6개가 조용히 제거되던 기반 버그를 수정. 핸들러와 어긋나던 OpenAPI 카탈로그 29건을 정정했다 — 문서대로 호출하면 405가 나던 경로(할당량·알림 규칙·라우팅 규칙·MCP 업스트림·템플릿·변경 세트·내 키·멀티 실행), 서버에 구현되어 있으나 문서에 없어 호출할 수 없던 조작(템플릿 검토·승인·롤백·이력, 변경 세트 승인 워크플로, 역할 삭제, 팀 리포트 승인, 키 회전, Skill 접근 신청·평가·적합성 기록, 요청 원인 설명·메모·분석·재실행, DW 지표 삭제·검증, Text2SQL 연결 삭제, MCP 도구 위험등급·연결 진단, 프롬프트 실험 수정·삭제·테스트 실행), 그리고 서버 경로와 철자가 달라 404가 나던 문서 오류 1건. 역할로만 결정되어 클라이언트가 알 수 없던 프롬프트 원문 열람 권한을 부트스트랩이 능력으로 알려 주도록 해 버튼을 사유와 함께 비활성화하고, 변경 세트의 적용·롤백·삭제가 운영자 사유를 감사 이력에 남기도록 수정(삭제는 감사 기록이 전혀 없었음). Mattermost 알림 설정 조회가 채널 게시 권한을 가진 웹훅 토큰을 원문으로 반환하던 문제를 마스킹으로 수정

배포 파일

파일 설명
ai-coding-proxy-gateway-v0.84.0.tar.gz Docker 이미지 패키지 (linux/amd64)
ai-coding-proxy-gateway-v0.84.0.tar.gz.sha256 SHA256 체크섬
README-offline-v0.84.0.md 오프라인 배포 가이드
SBOM-v0.84.0.spdx.json Go+npm 통합 SPDX SBOM
THIRD_PARTY_LICENSES-v0.84.0.md Go·Frontend 제3자 라이선스 목록
init-deployment-env-v0.84.0.sh 운영 env 원자 생성·검증 helper
backup-volume-v0.84.0.sh named volume·env 백업·복구 helper

빠른 시작

# 이미지 로드
gunzip -c ai-coding-proxy-gateway-v0.84.0.tar.gz | docker load

# 최초 1회 비밀값 파일과 nonroot 호환 named volume 준비
ENV_FILE=/opt/proxy-gateway/gateway.env
install -d -m 0700 "$(dirname "$ENV_FILE")" || exit 1
command -v openssl >/dev/null 2>&1 || { echo "openssl이 필요합니다." >&2; exit 1; }
if [ ! -e "$ENV_FILE" ]; then
  umask 077
  ADMIN_TOKEN_VALUE="$(openssl rand -hex 32)" || exit 1
  GATEWAY_SECRET_VALUE="$(openssl rand -hex 32)" || exit 1
  [ "${#ADMIN_TOKEN_VALUE}" -eq 64 ] && [ "${#GATEWAY_SECRET_VALUE}" -eq 64 ] || exit 1
  printf '%s\n' "$ADMIN_TOKEN_VALUE" | grep -Eq '^[0-9A-Fa-f]{64}$' && 
    printf '%s\n' "$GATEWAY_SECRET_VALUE" | grep -Eq '^[0-9A-Fa-f]{64}$' || exit 1
  UPSTREAM_API_KEY_VALUE="${UPSTREAM_API_KEY:-}"
  if [ -z "$UPSTREAM_API_KEY_VALUE" ]; then
    read -r -s -p 'Upstream API key: ' UPSTREAM_API_KEY_VALUE || exit 1
    echo
  fi
  case "$UPSTREAM_API_KEY_VALUE" in
    ''|*[!A-Za-z0-9._~:/+=-]*) echo 'UPSTREAM_API_KEY 형식이 안전하지 않습니다.' >&2; exit 1 ;;
  esac
  ENV_TMP="$(mktemp "${ENV_FILE}.tmp.XXXXXX")" || exit 1
  trap 'rm -f -- "$ENV_TMP"' EXIT HUP INT TERM
  {
    echo 'UPSTREAM_BASE_URL=https://api.openai.com'
    echo "UPSTREAM_API_KEY=${UPSTREAM_API_KEY_VALUE}"
    echo 'GATEWAY_VERSION=v0.84.0'
    echo "ADMIN_TOKEN=${ADMIN_TOKEN_VALUE}"
    echo "GATEWAY_SECRET=${GATEWAY_SECRET_VALUE}"
    echo 'UI_APP_ENABLED=false'
  } > "$ENV_TMP" || exit 1
  chmod 0600 "$ENV_TMP" && mv -f -- "$ENV_TMP" "$ENV_FILE" || exit 1
  trap - EXIT HUP INT TERM
fi
chmod 0600 "$ENV_FILE" || exit 1
[ "$(grep -Ec '^ADMIN_TOKEN=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^ADMIN_TOKEN=[0-9A-Fa-f]{64}$' "$ENV_FILE" && 
  [ "$(grep -Ec '^GATEWAY_SECRET=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^GATEWAY_SECRET=[0-9A-Fa-f]{64}$' "$ENV_FILE" && 
  [ "$(grep -Ec '^UPSTREAM_API_KEY=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^UPSTREAM_API_KEY=[A-Za-z0-9._~:/+=-]+$' "$ENV_FILE" && 
  ! grep -q '^UPSTREAM_API_KEY=replace-before-start$' "$ENV_FILE" && 
  [ "$(grep -Ec '^GATEWAY_VERSION=' "$ENV_FILE")" -eq 1 ] && 
  grep -qxF 'GATEWAY_VERSION=v0.84.0' "$ENV_FILE" || 
  { echo "gateway.env의 필수 비밀값이 유효하지 않습니다." >&2; exit 1; }
docker volume create proxy-gateway-data >/dev/null || exit 1

# 기존 볼륨·바인드 마운트 재사용 시 nonroot(65532) 소유권 복구 (새 볼륨은 변경 없음)
docker run --rm --user 0:0 --mount source=proxy-gateway-data,target=/data ai-coding-proxy-gateway:v0.84.0 repair-data-dir || exit 1

docker run -d --name proxy-gateway --restart=always \
  -p 8080:8080 \
  --mount source=proxy-gateway-data,target=/data \
  --env-file "$ENV_FILE" \
  ai-coding-proxy-gateway:v0.84.0
  • Legacy Stable Console: http://localhost:8080/admin
  • Next Console Preview: http://localhost:8080/app/ (/app is OFF unless UI_APP_ENABLED=true)
  • React assets are embedded in the Go binary; the runtime image does not contain Node.js.
  • Reuse and back up the same 0600 env file; rotating GATEWAY_SECRET without migration makes stored Provider Secrets unreadable.
  • Transfer, checksum, and chmod 0700 the bundled init-deployment-env-v0.84.0.sh and backup-volume-v0.84.0.sh helpers.
  • The init helper preserves secrets and atomically updates only GATEWAY_VERSION during upgrades.
  • If the container restarts and 8080 never opens with 'readonly database' in docker logs, /data was written by another user: run the repair-data-dir command above once, then verify with: docker run --rm --mount source=proxy-gateway-data,target=/data ai-coding-proxy-gateway:v0.84.0 check-data-dir

v0.83.2 - AI Proxy Gateway

Choose a tag to compare

@hkjang hkjang released this 07 Sep 01:59

AI Proxy Gateway v0.83.2

주요 변경 사항

  • SSO 로그인 시 로컬 지정 역할·팀 강등 방지와 계정 복구 명령 (v0.83.2): v0.82.1~v0.83.1은 Keycloak 로그인마다 저장된 역할·팀을 클레임 계산 결과로 덮어써, 토큰의 역할이 역할 매핑에 걸리지 않으면 콘솔에서 승격한 super_admin도 기본 역할로 강등되고 groups 클레임이 없으면 팀이 비워져 로그인 직후 운영·보안·설정 메뉴가 거의 사라지던 문제를 해결. 외부 신원(auth_identities)에 IdP가 직전 로그인에서 직접 부여한 역할·팀(idp_role/idp_team)을 기록하고, 명시적 매핑은 상향·하향 모두 적용하되 매핑이 없을 때는 IdP가 부여했던 것만 철회하고 관리자가 지정한 역할·팀은 유지하도록 변경(Keycloak에서 역할을 제거한 경우의 회수는 유지). 이미 강등돼 남은 관리자가 없는 경우를 위해 데이터 볼륨에 대해 실행하는 set-user-role --email --role 보조 명령을 추가(내장·커스텀 역할 검증, 기존 세션 폐기, role_repaired 감사 기록)하고 운영 가이드 8.7 런북을 추가

배포 파일

파일 설명
ai-coding-proxy-gateway-v0.83.2.tar.gz Docker 이미지 패키지 (linux/amd64)
ai-coding-proxy-gateway-v0.83.2.tar.gz.sha256 SHA256 체크섬
README-offline-v0.83.2.md 오프라인 배포 가이드
SBOM-v0.83.2.spdx.json Go+npm 통합 SPDX SBOM
THIRD_PARTY_LICENSES-v0.83.2.md Go·Frontend 제3자 라이선스 목록
init-deployment-env-v0.83.2.sh 운영 env 원자 생성·검증 helper
backup-volume-v0.83.2.sh named volume·env 백업·복구 helper

빠른 시작

# 이미지 로드
gunzip -c ai-coding-proxy-gateway-v0.83.2.tar.gz | docker load

# 최초 1회 비밀값 파일과 nonroot 호환 named volume 준비
ENV_FILE=/opt/proxy-gateway/gateway.env
install -d -m 0700 "$(dirname "$ENV_FILE")" || exit 1
command -v openssl >/dev/null 2>&1 || { echo "openssl이 필요합니다." >&2; exit 1; }
if [ ! -e "$ENV_FILE" ]; then
  umask 077
  ADMIN_TOKEN_VALUE="$(openssl rand -hex 32)" || exit 1
  GATEWAY_SECRET_VALUE="$(openssl rand -hex 32)" || exit 1
  [ "${#ADMIN_TOKEN_VALUE}" -eq 64 ] && [ "${#GATEWAY_SECRET_VALUE}" -eq 64 ] || exit 1
  printf '%s\n' "$ADMIN_TOKEN_VALUE" | grep -Eq '^[0-9A-Fa-f]{64}$' && 
    printf '%s\n' "$GATEWAY_SECRET_VALUE" | grep -Eq '^[0-9A-Fa-f]{64}$' || exit 1
  UPSTREAM_API_KEY_VALUE="${UPSTREAM_API_KEY:-}"
  if [ -z "$UPSTREAM_API_KEY_VALUE" ]; then
    read -r -s -p 'Upstream API key: ' UPSTREAM_API_KEY_VALUE || exit 1
    echo
  fi
  case "$UPSTREAM_API_KEY_VALUE" in
    ''|*[!A-Za-z0-9._~:/+=-]*) echo 'UPSTREAM_API_KEY 형식이 안전하지 않습니다.' >&2; exit 1 ;;
  esac
  ENV_TMP="$(mktemp "${ENV_FILE}.tmp.XXXXXX")" || exit 1
  trap 'rm -f -- "$ENV_TMP"' EXIT HUP INT TERM
  {
    echo 'UPSTREAM_BASE_URL=https://api.openai.com'
    echo "UPSTREAM_API_KEY=${UPSTREAM_API_KEY_VALUE}"
    echo 'GATEWAY_VERSION=v0.83.2'
    echo "ADMIN_TOKEN=${ADMIN_TOKEN_VALUE}"
    echo "GATEWAY_SECRET=${GATEWAY_SECRET_VALUE}"
    echo 'UI_APP_ENABLED=false'
  } > "$ENV_TMP" || exit 1
  chmod 0600 "$ENV_TMP" && mv -f -- "$ENV_TMP" "$ENV_FILE" || exit 1
  trap - EXIT HUP INT TERM
fi
chmod 0600 "$ENV_FILE" || exit 1
[ "$(grep -Ec '^ADMIN_TOKEN=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^ADMIN_TOKEN=[0-9A-Fa-f]{64}$' "$ENV_FILE" && 
  [ "$(grep -Ec '^GATEWAY_SECRET=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^GATEWAY_SECRET=[0-9A-Fa-f]{64}$' "$ENV_FILE" && 
  [ "$(grep -Ec '^UPSTREAM_API_KEY=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^UPSTREAM_API_KEY=[A-Za-z0-9._~:/+=-]+$' "$ENV_FILE" && 
  ! grep -q '^UPSTREAM_API_KEY=replace-before-start$' "$ENV_FILE" && 
  [ "$(grep -Ec '^GATEWAY_VERSION=' "$ENV_FILE")" -eq 1 ] && 
  grep -qxF 'GATEWAY_VERSION=v0.83.2' "$ENV_FILE" || 
  { echo "gateway.env의 필수 비밀값이 유효하지 않습니다." >&2; exit 1; }
docker volume create proxy-gateway-data >/dev/null || exit 1

# 기존 볼륨·바인드 마운트 재사용 시 nonroot(65532) 소유권 복구 (새 볼륨은 변경 없음)
docker run --rm --user 0:0 --mount source=proxy-gateway-data,target=/data ai-coding-proxy-gateway:v0.83.2 repair-data-dir || exit 1

docker run -d --name proxy-gateway --restart=always \
  -p 8080:8080 \
  --mount source=proxy-gateway-data,target=/data \
  --env-file "$ENV_FILE" \
  ai-coding-proxy-gateway:v0.83.2
  • Legacy Stable Console: http://localhost:8080/admin
  • Next Console Preview: http://localhost:8080/app/ (/app is OFF unless UI_APP_ENABLED=true)
  • React assets are embedded in the Go binary; the runtime image does not contain Node.js.
  • Reuse and back up the same 0600 env file; rotating GATEWAY_SECRET without migration makes stored Provider Secrets unreadable.
  • Transfer, checksum, and chmod 0700 the bundled init-deployment-env-v0.83.2.sh and backup-volume-v0.83.2.sh helpers.
  • The init helper preserves secrets and atomically updates only GATEWAY_VERSION during upgrades.
  • If the container restarts and 8080 never opens with 'readonly database' in docker logs, /data was written by another user: run the repair-data-dir command above once, then verify with: docker run --rm --mount source=proxy-gateway-data,target=/data ai-coding-proxy-gateway:v0.83.2 check-data-dir

v0.83.1 - AI Proxy Gateway

Choose a tag to compare

@hkjang hkjang released this 07 Sep 01:05

AI Proxy Gateway v0.83.1

주요 변경 사항

  • nonroot 데이터 디렉터리 권한 진단·복구로 8080 미기동 해결 (v0.83.1): 운영 이미지는 distroless nonroot(uid 65532)로 실행되는데, root가 만든 바인드 마운트·이전 배포의 볼륨·fsGroup 없는 Kubernetes PVC처럼 다른 사용자가 기록한 /data를 이어받으면 SQLite의 attempt to write a readonly database만 남기고 종료해 컨테이너가 재시작을 반복하고 8080이 열리지 않던 문제를 해결. 기동 시 데이터 디렉터리·DB 파일·WAL/SHM 사이드카의 실제 쓰기 가능 여부를 먼저 검사해 실패 경로마다 소유자·권한·원인과 복구 명령을 로그에 남기고, Fallback 로그 디렉터리가 쓰기 불가하면 WARN으로 알림. 이미지에 셸이 없어도 같은 이미지로 진단·복구할 수 있도록 게이트웨이 바이너리에 check-data-dir(nonroot, 변경 없음, 종료 코드로 판정)·repair-data-dir(root 1회, /data 이하 65532:65532 재소유와 소유자 읽기·쓰기 비트 복원, 멱등, 심볼릭 링크 미추적, --uid/--gid 지정 가능)·version 보조 명령을 추가. 컨테이너 smoke가 root 소유 볼륨에서 nonroot 기동 거부·오류 메시지·check-data-dir 실패·repair-data-dir 복구·재기동까지 검증하도록 확장했고, 오프라인 README·릴리즈 노트·README·운영 가이드(8.6 런북)·릴리즈 가이드·compose에 볼륨 재사용 시 1회 복구 절차와 8080 미응답 진단 절차를 추가

배포 파일

파일 설명
ai-coding-proxy-gateway-v0.83.1.tar.gz Docker 이미지 패키지 (linux/amd64)
ai-coding-proxy-gateway-v0.83.1.tar.gz.sha256 SHA256 체크섬
README-offline-v0.83.1.md 오프라인 배포 가이드
SBOM-v0.83.1.spdx.json Go+npm 통합 SPDX SBOM
THIRD_PARTY_LICENSES-v0.83.1.md Go·Frontend 제3자 라이선스 목록
init-deployment-env-v0.83.1.sh 운영 env 원자 생성·검증 helper
backup-volume-v0.83.1.sh named volume·env 백업·복구 helper

빠른 시작

# 이미지 로드
gunzip -c ai-coding-proxy-gateway-v0.83.1.tar.gz | docker load

# 최초 1회 비밀값 파일과 nonroot 호환 named volume 준비
ENV_FILE=/opt/proxy-gateway/gateway.env
install -d -m 0700 "$(dirname "$ENV_FILE")" || exit 1
command -v openssl >/dev/null 2>&1 || { echo "openssl이 필요합니다." >&2; exit 1; }
if [ ! -e "$ENV_FILE" ]; then
  umask 077
  ADMIN_TOKEN_VALUE="$(openssl rand -hex 32)" || exit 1
  GATEWAY_SECRET_VALUE="$(openssl rand -hex 32)" || exit 1
  [ "${#ADMIN_TOKEN_VALUE}" -eq 64 ] && [ "${#GATEWAY_SECRET_VALUE}" -eq 64 ] || exit 1
  printf '%s\n' "$ADMIN_TOKEN_VALUE" | grep -Eq '^[0-9A-Fa-f]{64}$' && 
    printf '%s\n' "$GATEWAY_SECRET_VALUE" | grep -Eq '^[0-9A-Fa-f]{64}$' || exit 1
  UPSTREAM_API_KEY_VALUE="${UPSTREAM_API_KEY:-}"
  if [ -z "$UPSTREAM_API_KEY_VALUE" ]; then
    read -r -s -p 'Upstream API key: ' UPSTREAM_API_KEY_VALUE || exit 1
    echo
  fi
  case "$UPSTREAM_API_KEY_VALUE" in
    ''|*[!A-Za-z0-9._~:/+=-]*) echo 'UPSTREAM_API_KEY 형식이 안전하지 않습니다.' >&2; exit 1 ;;
  esac
  ENV_TMP="$(mktemp "${ENV_FILE}.tmp.XXXXXX")" || exit 1
  trap 'rm -f -- "$ENV_TMP"' EXIT HUP INT TERM
  {
    echo 'UPSTREAM_BASE_URL=https://api.openai.com'
    echo "UPSTREAM_API_KEY=${UPSTREAM_API_KEY_VALUE}"
    echo 'GATEWAY_VERSION=v0.83.1'
    echo "ADMIN_TOKEN=${ADMIN_TOKEN_VALUE}"
    echo "GATEWAY_SECRET=${GATEWAY_SECRET_VALUE}"
    echo 'UI_APP_ENABLED=false'
  } > "$ENV_TMP" || exit 1
  chmod 0600 "$ENV_TMP" && mv -f -- "$ENV_TMP" "$ENV_FILE" || exit 1
  trap - EXIT HUP INT TERM
fi
chmod 0600 "$ENV_FILE" || exit 1
[ "$(grep -Ec '^ADMIN_TOKEN=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^ADMIN_TOKEN=[0-9A-Fa-f]{64}$' "$ENV_FILE" && 
  [ "$(grep -Ec '^GATEWAY_SECRET=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^GATEWAY_SECRET=[0-9A-Fa-f]{64}$' "$ENV_FILE" && 
  [ "$(grep -Ec '^UPSTREAM_API_KEY=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^UPSTREAM_API_KEY=[A-Za-z0-9._~:/+=-]+$' "$ENV_FILE" && 
  ! grep -q '^UPSTREAM_API_KEY=replace-before-start$' "$ENV_FILE" && 
  [ "$(grep -Ec '^GATEWAY_VERSION=' "$ENV_FILE")" -eq 1 ] && 
  grep -qxF 'GATEWAY_VERSION=v0.83.1' "$ENV_FILE" || 
  { echo "gateway.env의 필수 비밀값이 유효하지 않습니다." >&2; exit 1; }
docker volume create proxy-gateway-data >/dev/null || exit 1

# 기존 볼륨·바인드 마운트 재사용 시 nonroot(65532) 소유권 복구 (새 볼륨은 변경 없음)
docker run --rm --user 0:0 --mount source=proxy-gateway-data,target=/data ai-coding-proxy-gateway:v0.83.1 repair-data-dir || exit 1

docker run -d --name proxy-gateway --restart=always \
  -p 8080:8080 \
  --mount source=proxy-gateway-data,target=/data \
  --env-file "$ENV_FILE" \
  ai-coding-proxy-gateway:v0.83.1
  • Legacy Stable Console: http://localhost:8080/admin
  • Next Console Preview: http://localhost:8080/app/ (/app is OFF unless UI_APP_ENABLED=true)
  • React assets are embedded in the Go binary; the runtime image does not contain Node.js.
  • Reuse and back up the same 0600 env file; rotating GATEWAY_SECRET without migration makes stored Provider Secrets unreadable.
  • Transfer, checksum, and chmod 0700 the bundled init-deployment-env-v0.83.1.sh and backup-volume-v0.83.1.sh helpers.
  • The init helper preserves secrets and atomically updates only GATEWAY_VERSION during upgrades.
  • If the container restarts and 8080 never opens with 'readonly database' in docker logs, /data was written by another user: run the repair-data-dir command above once, then verify with: docker run --rm --mount source=proxy-gateway-data,target=/data ai-coding-proxy-gateway:v0.83.1 check-data-dir

v0.83.0 - AI Proxy Gateway

Choose a tag to compare

@hkjang hkjang released this 05 Sep 00:12

AI Proxy Gateway v0.83.0

주요 변경 사항

  • 요청 단위 추적 탐색기·추적 조회 권한 및 성능 강화 (v0.83.0): /app/observability/traces 읽기 전용 미리보기를 추가해 같은 추적 ID로 연결된 요청을 시작 시각·지연 구간·HTTP 상태·모델·안전 공급자 표시명·토큰·비용 기준의 시간축과 표로 비교하고, URL 필터 복원·필터 결합 암호화/서명 양방향 커서·자동 갱신·마지막 정상 데이터·재시도·요청 탐색기 및 기존 화면 연결을 제공. 메뉴·버튼·상태·안내 문구는 한글을 우선하며 키보드와 스크린리더용 의미 구조, 상세 포커스 이동·복원을 유지. 신규 화면은 기존 /admin/requestsX-Vibe-UI: app 안전 투영만 재사용해 프롬프트·응답 본문·원시 오류·사용자 에이전트·도구 인자·SQL을 브라우저로 내려보내지 않고, 원문 오류나 Text2SQL 거절 사유가 포함될 수 있는 레거시 상세 추적 API는 호출하지 않음. 안전한 요청 ID는 원문 딥링크로 유지해 GATEWAY_SECRET 교체에도 안정적으로 복원하고, 비공개 처리된 중복 표시 ID는 비밀 탐지 규칙과 충돌하지 않는 분절 HMAC 참조와 별도 selected_ref URL 공간으로 정확히 구분하며 새로고침 회귀를 검증. 정확한 trace_id 조회용 복합 부분 인덱스를 SQLite와 PostgreSQL에 추가하고 20만 행 자연 계획에서 범위 탐색을 검증했으며, 과대한 레거시 식별자를 인덱스에서 제외해 업그레이드 안전성을 유지. 저장된 표기 그대로의 유효한 레거시 IPv6 필터도 정규화로 놓치지 않게 했고, X-Vibe-App-Requests-Version을 추가해 헤더 미지정 또는 1은 v0.82 안전 투영의 정확한 형태를, 2는 신규 HMAC 참조·필터 가능 여부를 반환하며 잘못되거나 중복된 버전은 거부하고 두 변형을 Vary와 OpenAPI에 명시. 요청 탐색기와 추적 탐색기의 최소 백엔드 계약을 v0.83.0으로 고정하며 서버가 내려주는 더 낮은 런타임 버전으로 하한이 완화되지 않게 해 롤링 배포 중에는 안전하게 기존 화면으로 전환. 기존 요청 추적과 LLM 추적 상세/목록에는 GET 전용 메서드·길이·UTF-8·경로 구분자 검증, 조회 실패 시 안정 오류, exact 팀 소유권 검사, 하위 권한 오류·대체 사유·거절 사유 감사 마스킹, 특수문자 요청 ID 링크 인코딩을 적용해 다른 팀 데이터와 내부 오류가 새지 않도록 강화. 릴리스 파이프라인은 체크섬으로 고정한 Grype 0.117.0으로 실제 Distroless 최종 이미지의 High·Critical 취약점을 패키징 전에 차단하고 /admin Legacy 본문도 컨테이너 smoke에서 확인. Text2SQL 검증기의 LIMIT 규칙이 중첩을 고려하지 않고 문장 전체를 훑어 서브쿼리·CTE 본문의 LIMIT이 바깥 쿼리를 대신 대답하던 문제를 수정. 상한 검사는 텍스트 순서상 첫 매치만 보던 방식을 버리고 모든 LIMIT을 MaxLimit과 비교해 (SELECT ... LIMIT 5) ... LIMIT 999999 형태가 통과하지 못하게 하고, 기본 LIMIT 주입은 괄호 밖 최상위 LIMIT 유무로만 판단해 서브쿼리에만 LIMIT이 있는 무제한 쿼리에도 기본 상한이 붙도록 했으며, 값 파싱은 개행이 섞인 LIMIT\n999999나 오버플로 리터럴을 0으로 읽어 상한을 무력화하지 않도록 정규식 캡처와 정수 변환으로 바꾸고 해석할 수 없는 값은 거부

배포 파일

파일 설명
ai-coding-proxy-gateway-v0.83.0.tar.gz Docker 이미지 패키지 (linux/amd64)
ai-coding-proxy-gateway-v0.83.0.tar.gz.sha256 SHA256 체크섬
README-offline-v0.83.0.md 오프라인 배포 가이드
SBOM-v0.83.0.spdx.json Go+npm 통합 SPDX SBOM
THIRD_PARTY_LICENSES-v0.83.0.md Go·Frontend 제3자 라이선스 목록
init-deployment-env-v0.83.0.sh 운영 env 원자 생성·검증 helper
backup-volume-v0.83.0.sh named volume·env 백업·복구 helper

빠른 시작

# 이미지 로드
gunzip -c ai-coding-proxy-gateway-v0.83.0.tar.gz | docker load

# 최초 1회 비밀값 파일과 nonroot 호환 named volume 준비
ENV_FILE=/opt/proxy-gateway/gateway.env
install -d -m 0700 "$(dirname "$ENV_FILE")" || exit 1
command -v openssl >/dev/null 2>&1 || { echo "openssl이 필요합니다." >&2; exit 1; }
if [ ! -e "$ENV_FILE" ]; then
  umask 077
  ADMIN_TOKEN_VALUE="$(openssl rand -hex 32)" || exit 1
  GATEWAY_SECRET_VALUE="$(openssl rand -hex 32)" || exit 1
  [ "${#ADMIN_TOKEN_VALUE}" -eq 64 ] && [ "${#GATEWAY_SECRET_VALUE}" -eq 64 ] || exit 1
  printf '%s\n' "$ADMIN_TOKEN_VALUE" | grep -Eq '^[0-9A-Fa-f]{64}$' && 
    printf '%s\n' "$GATEWAY_SECRET_VALUE" | grep -Eq '^[0-9A-Fa-f]{64}$' || exit 1
  UPSTREAM_API_KEY_VALUE="${UPSTREAM_API_KEY:-}"
  if [ -z "$UPSTREAM_API_KEY_VALUE" ]; then
    read -r -s -p 'Upstream API key: ' UPSTREAM_API_KEY_VALUE || exit 1
    echo
  fi
  case "$UPSTREAM_API_KEY_VALUE" in
    ''|*[!A-Za-z0-9._~:/+=-]*) echo 'UPSTREAM_API_KEY 형식이 안전하지 않습니다.' >&2; exit 1 ;;
  esac
  ENV_TMP="$(mktemp "${ENV_FILE}.tmp.XXXXXX")" || exit 1
  trap 'rm -f -- "$ENV_TMP"' EXIT HUP INT TERM
  {
    echo 'UPSTREAM_BASE_URL=https://api.openai.com'
    echo "UPSTREAM_API_KEY=${UPSTREAM_API_KEY_VALUE}"
    echo 'GATEWAY_VERSION=v0.83.0'
    echo "ADMIN_TOKEN=${ADMIN_TOKEN_VALUE}"
    echo "GATEWAY_SECRET=${GATEWAY_SECRET_VALUE}"
    echo 'UI_APP_ENABLED=false'
  } > "$ENV_TMP" || exit 1
  chmod 0600 "$ENV_TMP" && mv -f -- "$ENV_TMP" "$ENV_FILE" || exit 1
  trap - EXIT HUP INT TERM
fi
chmod 0600 "$ENV_FILE" || exit 1
[ "$(grep -Ec '^ADMIN_TOKEN=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^ADMIN_TOKEN=[0-9A-Fa-f]{64}$' "$ENV_FILE" && 
  [ "$(grep -Ec '^GATEWAY_SECRET=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^GATEWAY_SECRET=[0-9A-Fa-f]{64}$' "$ENV_FILE" && 
  [ "$(grep -Ec '^UPSTREAM_API_KEY=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^UPSTREAM_API_KEY=[A-Za-z0-9._~:/+=-]+$' "$ENV_FILE" && 
  ! grep -q '^UPSTREAM_API_KEY=replace-before-start$' "$ENV_FILE" && 
  [ "$(grep -Ec '^GATEWAY_VERSION=' "$ENV_FILE")" -eq 1 ] && 
  grep -qxF 'GATEWAY_VERSION=v0.83.0' "$ENV_FILE" || 
  { echo "gateway.env의 필수 비밀값이 유효하지 않습니다." >&2; exit 1; }
docker volume create proxy-gateway-data >/dev/null || exit 1

docker run -d --name proxy-gateway --restart=always \
  -p 8080:8080 \
  --mount source=proxy-gateway-data,target=/data \
  --env-file "$ENV_FILE" \
  ai-coding-proxy-gateway:v0.83.0
  • Legacy Stable Console: http://localhost:8080/admin
  • Next Console Preview: http://localhost:8080/app/ (/app is OFF unless UI_APP_ENABLED=true)
  • React assets are embedded in the Go binary; the runtime image does not contain Node.js.
  • Reuse and back up the same 0600 env file; rotating GATEWAY_SECRET without migration makes stored Provider Secrets unreadable.
  • Transfer, checksum, and chmod 0700 the bundled init-deployment-env-v0.83.0.sh and backup-volume-v0.83.0.sh helpers.
  • The init helper preserves secrets and atomically updates only GATEWAY_VERSION during upgrades.

v0.82.2 - AI Proxy Gateway

Choose a tag to compare

@hkjang hkjang released this 03 Sep 16:51

AI Proxy Gateway v0.82.2

주요 변경 사항

  • 모델 단가 음수 차단·구조화 응답 토큰 집계 정정 (v0.82.2): 운영자가 단가를 넣는 두 경로가 모두 음수 KRW를 그대로 받아들여 해당 모델의 비용이 음수로 계산되던 문제를 수정. POST /admin/pricing은 필드 존재 여부만 검사했고 MODEL_PRICING_KRW_PER_1M은 범위 검사 없이 적재되었는데, 음수 비용은 cost > limit 형태인 키별 예산·비용 가드를 무조건 통과시키고 일별·월별 쿼터 누적에서 요청분을 더하는 대신 빼므로 강제 자체가 무력화된다. 관리 API는 입력·출력·캐시 단가의 음수를 400으로 거부하고 잘못된 가격 버전을 기록하지 않으며, 환경변수 단가 맵에 음수가 있으면 기동을 차단. 과금하지 않는 모델을 표기하는 0은 계속 허용. 응답 분석기가 문자열 content만 평탄화해 [{"type":"text","text":"..."}] 구조화 content로 답하는 공급자의 응답에서 completion 텍스트가 비어, usage 블록이 없는 요청이 completion 토큰 0·비용 0으로 기록되던 문제를 함께 수정하고, 텍스트가 없는 파트는 원문 JSON 대신 아무것도 더하지 않아 추정치가 부풀지 않도록 유지. 스트리밍 tool call 이름을 누적 map 순회로 내보내 tool_invocations 행 순서가 실행마다 달라지던 문제도 delta.tool_calls의 index 순 정렬로 안정화

배포 파일

파일 설명
ai-coding-proxy-gateway-v0.82.2.tar.gz Docker 이미지 패키지 (linux/amd64)
ai-coding-proxy-gateway-v0.82.2.tar.gz.sha256 SHA256 체크섬
README-offline-v0.82.2.md 오프라인 배포 가이드
SBOM-v0.82.2.spdx.json Go+npm 통합 SPDX SBOM
THIRD_PARTY_LICENSES-v0.82.2.md Go·Frontend 제3자 라이선스 목록
init-deployment-env-v0.82.2.sh 운영 env 원자 생성·검증 helper
backup-volume-v0.82.2.sh named volume·env 백업·복구 helper

빠른 시작

# 이미지 로드
gunzip -c ai-coding-proxy-gateway-v0.82.2.tar.gz | docker load

# 최초 1회 비밀값 파일과 nonroot 호환 named volume 준비
ENV_FILE=/opt/proxy-gateway/gateway.env
install -d -m 0700 "$(dirname "$ENV_FILE")" || exit 1
command -v openssl >/dev/null 2>&1 || { echo "openssl이 필요합니다." >&2; exit 1; }
if [ ! -e "$ENV_FILE" ]; then
  umask 077
  ADMIN_TOKEN_VALUE="$(openssl rand -hex 32)" || exit 1
  GATEWAY_SECRET_VALUE="$(openssl rand -hex 32)" || exit 1
  [ "${#ADMIN_TOKEN_VALUE}" -eq 64 ] && [ "${#GATEWAY_SECRET_VALUE}" -eq 64 ] || exit 1
  printf '%s\n' "$ADMIN_TOKEN_VALUE" | grep -Eq '^[0-9A-Fa-f]{64}$' && 
    printf '%s\n' "$GATEWAY_SECRET_VALUE" | grep -Eq '^[0-9A-Fa-f]{64}$' || exit 1
  UPSTREAM_API_KEY_VALUE="${UPSTREAM_API_KEY:-}"
  if [ -z "$UPSTREAM_API_KEY_VALUE" ]; then
    read -r -s -p 'Upstream API key: ' UPSTREAM_API_KEY_VALUE || exit 1
    echo
  fi
  case "$UPSTREAM_API_KEY_VALUE" in
    ''|*[!A-Za-z0-9._~:/+=-]*) echo 'UPSTREAM_API_KEY 형식이 안전하지 않습니다.' >&2; exit 1 ;;
  esac
  ENV_TMP="$(mktemp "${ENV_FILE}.tmp.XXXXXX")" || exit 1
  trap 'rm -f -- "$ENV_TMP"' EXIT HUP INT TERM
  {
    echo 'UPSTREAM_BASE_URL=https://api.openai.com'
    echo "UPSTREAM_API_KEY=${UPSTREAM_API_KEY_VALUE}"
    echo 'GATEWAY_VERSION=v0.82.2'
    echo "ADMIN_TOKEN=${ADMIN_TOKEN_VALUE}"
    echo "GATEWAY_SECRET=${GATEWAY_SECRET_VALUE}"
    echo 'UI_APP_ENABLED=false'
  } > "$ENV_TMP" || exit 1
  chmod 0600 "$ENV_TMP" && mv -f -- "$ENV_TMP" "$ENV_FILE" || exit 1
  trap - EXIT HUP INT TERM
fi
chmod 0600 "$ENV_FILE" || exit 1
[ "$(grep -Ec '^ADMIN_TOKEN=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^ADMIN_TOKEN=[0-9A-Fa-f]{64}$' "$ENV_FILE" && 
  [ "$(grep -Ec '^GATEWAY_SECRET=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^GATEWAY_SECRET=[0-9A-Fa-f]{64}$' "$ENV_FILE" && 
  [ "$(grep -Ec '^UPSTREAM_API_KEY=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^UPSTREAM_API_KEY=[A-Za-z0-9._~:/+=-]+$' "$ENV_FILE" && 
  ! grep -q '^UPSTREAM_API_KEY=replace-before-start$' "$ENV_FILE" && 
  [ "$(grep -Ec '^GATEWAY_VERSION=' "$ENV_FILE")" -eq 1 ] && 
  grep -qxF 'GATEWAY_VERSION=v0.82.2' "$ENV_FILE" || 
  { echo "gateway.env의 필수 비밀값이 유효하지 않습니다." >&2; exit 1; }
docker volume create proxy-gateway-data >/dev/null || exit 1

docker run -d --name proxy-gateway --restart=always \
  -p 8080:8080 \
  --mount source=proxy-gateway-data,target=/data \
  --env-file "$ENV_FILE" \
  ai-coding-proxy-gateway:v0.82.2
  • Legacy Stable Console: http://localhost:8080/admin
  • Next Console Preview: http://localhost:8080/app/ (/app is OFF unless UI_APP_ENABLED=true)
  • React assets are embedded in the Go binary; the runtime image does not contain Node.js.
  • Reuse and back up the same 0600 env file; rotating GATEWAY_SECRET without migration makes stored Provider Secrets unreadable.
  • Transfer, checksum, and chmod 0700 the bundled init-deployment-env-v0.82.2.sh and backup-volume-v0.82.2.sh helpers.
  • The init helper preserves secrets and atomically updates only GATEWAY_VERSION during upgrades.

v0.82.1 - AI Proxy Gateway

Choose a tag to compare

@hkjang hkjang released this 03 Sep 05:20
c9f2096

AI Proxy Gateway v0.82.1

주요 변경 사항

  • Keycloak SSO 복구·한글 우선 UI·요청 탐색기 (v0.82.1): Keycloak 그룹명이 기존 팀 표시명과 같지만 내부 팀 ID가 다른 경우 발생하던 user_provisioning_failed를 표준 팀 ID 해석으로 해결하고, 사용자·외부 식별자·팀 멤버십을 단일 트랜잭션으로 저장해 부분 생성과 동시 첫 로그인 중복을 방지. 검증되지 않은 이메일은 계정 연결에 사용하지 않으며 로컬 비밀번호·특권 계정과 충돌하면 권한을 상속하지 않는 별도 SSO 전용 계정으로 격리하고, 브라우저·감사 로그에는 안정된 비민감 오류만 제공. 로컬 로그인을 끄는 SSO 전용 구성에서도 해당 오류와 진단 코드를 접근 가능한 알림으로 표시. /app의 메뉴·버튼·기능명과 주요 상태·오류를 한글 우선으로 정리하고, 접근 거부 사유도 실제 필요 권한·역할·점진 배포·숨김 상태로 구분. /app/observability/requests 읽기 전용 미리보기는 기존 /admin/requests를 공동 사용하면서 엄격한 기간·상태·모델·공급자·요청·추적·세션·키·IP·언어 필터, 팀 권한 범위, 필터 결합 암호화·서명 양방향 커서, URL 상태 복원, 로딩·빈 화면·오류·마지막 정상 데이터·재시도·접근 가능한 상세 대화상자·기존 화면 연결을 제공. 시각 정규화 부분 인덱스와 PostgreSQL 표현식 통계, SQLite 시간순 권한 조회로 기존 행을 재작성하지 않고 정확한 커서 순서를 유지하며, 부모 페이지를 먼저 제한한 뒤 요청별 최신 사용량·응답만 결정적으로 조회. 과대한 레거시 식별자는 신규 복합 인덱스에서 제외해 PostgreSQL 기동 실패를 방지. 신규 React 투영은 프롬프트·응답 본문·원시 오류·사용자 에이전트를 제외하고 공급자 원본 대신 안전 라벨과 불투명 참조만 반환하며 기존 /admin JSON 계약은 유지

배포 파일

파일 설명
ai-coding-proxy-gateway-v0.82.1.tar.gz Docker 이미지 패키지 (linux/amd64)
ai-coding-proxy-gateway-v0.82.1.tar.gz.sha256 SHA256 체크섬
README-offline-v0.82.1.md 오프라인 배포 가이드
SBOM-v0.82.1.spdx.json Go+npm 통합 SPDX SBOM
THIRD_PARTY_LICENSES-v0.82.1.md Go·Frontend 제3자 라이선스 목록
init-deployment-env-v0.82.1.sh 운영 env 원자 생성·검증 helper
backup-volume-v0.82.1.sh named volume·env 백업·복구 helper

빠른 시작

# 이미지 로드
gunzip -c ai-coding-proxy-gateway-v0.82.1.tar.gz | docker load

# 최초 1회 비밀값 파일과 nonroot 호환 named volume 준비
ENV_FILE=/opt/proxy-gateway/gateway.env
install -d -m 0700 "$(dirname "$ENV_FILE")" || exit 1
command -v openssl >/dev/null 2>&1 || { echo "openssl이 필요합니다." >&2; exit 1; }
if [ ! -e "$ENV_FILE" ]; then
  umask 077
  ADMIN_TOKEN_VALUE="$(openssl rand -hex 32)" || exit 1
  GATEWAY_SECRET_VALUE="$(openssl rand -hex 32)" || exit 1
  [ "${#ADMIN_TOKEN_VALUE}" -eq 64 ] && [ "${#GATEWAY_SECRET_VALUE}" -eq 64 ] || exit 1
  printf '%s\n' "$ADMIN_TOKEN_VALUE" | grep -Eq '^[0-9A-Fa-f]{64}$' && 
    printf '%s\n' "$GATEWAY_SECRET_VALUE" | grep -Eq '^[0-9A-Fa-f]{64}$' || exit 1
  UPSTREAM_API_KEY_VALUE="${UPSTREAM_API_KEY:-}"
  if [ -z "$UPSTREAM_API_KEY_VALUE" ]; then
    read -r -s -p 'Upstream API key: ' UPSTREAM_API_KEY_VALUE || exit 1
    echo
  fi
  case "$UPSTREAM_API_KEY_VALUE" in
    ''|*[!A-Za-z0-9._~:/+=-]*) echo 'UPSTREAM_API_KEY 형식이 안전하지 않습니다.' >&2; exit 1 ;;
  esac
  ENV_TMP="$(mktemp "${ENV_FILE}.tmp.XXXXXX")" || exit 1
  trap 'rm -f -- "$ENV_TMP"' EXIT HUP INT TERM
  {
    echo 'UPSTREAM_BASE_URL=https://api.openai.com'
    echo "UPSTREAM_API_KEY=${UPSTREAM_API_KEY_VALUE}"
    echo 'GATEWAY_VERSION=v0.82.1'
    echo "ADMIN_TOKEN=${ADMIN_TOKEN_VALUE}"
    echo "GATEWAY_SECRET=${GATEWAY_SECRET_VALUE}"
    echo 'UI_APP_ENABLED=false'
  } > "$ENV_TMP" || exit 1
  chmod 0600 "$ENV_TMP" && mv -f -- "$ENV_TMP" "$ENV_FILE" || exit 1
  trap - EXIT HUP INT TERM
fi
chmod 0600 "$ENV_FILE" || exit 1
[ "$(grep -Ec '^ADMIN_TOKEN=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^ADMIN_TOKEN=[0-9A-Fa-f]{64}$' "$ENV_FILE" && 
  [ "$(grep -Ec '^GATEWAY_SECRET=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^GATEWAY_SECRET=[0-9A-Fa-f]{64}$' "$ENV_FILE" && 
  [ "$(grep -Ec '^UPSTREAM_API_KEY=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^UPSTREAM_API_KEY=[A-Za-z0-9._~:/+=-]+$' "$ENV_FILE" && 
  ! grep -q '^UPSTREAM_API_KEY=replace-before-start$' "$ENV_FILE" && 
  [ "$(grep -Ec '^GATEWAY_VERSION=' "$ENV_FILE")" -eq 1 ] && 
  grep -qxF 'GATEWAY_VERSION=v0.82.1' "$ENV_FILE" || 
  { echo "gateway.env의 필수 비밀값이 유효하지 않습니다." >&2; exit 1; }
docker volume create proxy-gateway-data >/dev/null || exit 1

docker run -d --name proxy-gateway --restart=always \
  -p 8080:8080 \
  --mount source=proxy-gateway-data,target=/data \
  --env-file "$ENV_FILE" \
  ai-coding-proxy-gateway:v0.82.1
  • Legacy Stable Console: http://localhost:8080/admin
  • Next Console Preview: http://localhost:8080/app/ (/app is OFF unless UI_APP_ENABLED=true)
  • React assets are embedded in the Go binary; the runtime image does not contain Node.js.
  • Reuse and back up the same 0600 env file; rotating GATEWAY_SECRET without migration makes stored Provider Secrets unreadable.
  • Transfer, checksum, and chmod 0700 the bundled init-deployment-env-v0.82.1.sh and backup-volume-v0.82.1.sh helpers.
  • The init helper preserves secrets and atomically updates only GATEWAY_VERSION during upgrades.

v0.82.0 - AI Proxy Gateway

Choose a tag to compare

@hkjang hkjang released this 02 Sep 22:07
0ee15b0

AI Proxy Gateway v0.82.0

주요 변경 사항

  • Next Admin Console Phase 1 Provider·Model Preview (v0.82.0): /app/gateway/providers, /app/gateway/models 읽기 전용 Preview를 추가해 URL 필터·페이지 복원, 안정 정렬, 상세 Dialog, Loading·부분 실패·last-known-good·Request ID·Retry, 키보드/접근성, Legacy Bridge를 제공. 기존 Provider·Model 관리 API를 그대로 공동 사용하고, /admin/models 정규화 카탈로그와 익명 /v1/models 집계·호환 fallback에 Provider fan-out cache·singleflight·공유 동시성/시간/행/압축 해제 후 응답 크기 상한, bounded Provider·Agent Route projection, 안전한 부분 실패·메타데이터를 적용. Provider URL의 credential·민감 query 노출을 차단하고 Agent Route 모델 shadow/deprecation 조회를 fail-closed로 강화. /app redirect에서 query를 폐기하고 React bootstrap 전 query·hash·history state·return_to의 Secret을 제거하되 브라우저 바인딩된 Keycloak 1회 교환 코드는 유지하며, 민감 Provider 딥링크를 제거한 뒤에도 원문 없이 일반 거부 안내 상태를 보존하고 Keycloak callback의 브라우저·감사 오류는 안정된 코드로 마스킹. Provider·MCP의 내부 원본 식별자는 집계 정확도를 위해 유지하면서 외부 응답·SSE·사용자 receipt·ClickHouse fact에는 opaque ref·안전 라벨·안정 오류만 노출하고, 과거 ClickHouse retry payload는 configured-table allowlist와 크기·행·스키마 검증 후 재투영하며 잘못된 batch를 보존 격리. MCP discovery 실패는 데이터베이스 오류 문자열 대신 안정된 mcp_discovery_failed 코드만 반환하고, PROXY_API_KEYSname:key:owner:team 각 필드를 트림하며 빈 시크릿 항목은 건너뛰되 설정이 비어 있지 않은데 유효 키가 0개면 시작을 차단해 조용한 인증 실패와 인증 fail-open을 막아 /admin과 Gateway API의 안전한 동작을 유지

배포 파일

파일 설명
ai-coding-proxy-gateway-v0.82.0.tar.gz Docker 이미지 패키지 (linux/amd64)
ai-coding-proxy-gateway-v0.82.0.tar.gz.sha256 SHA256 체크섬
README-offline-v0.82.0.md 오프라인 배포 가이드
SBOM-v0.82.0.spdx.json Go+npm 통합 SPDX SBOM
THIRD_PARTY_LICENSES-v0.82.0.md Go·Frontend 제3자 라이선스 목록
init-deployment-env-v0.82.0.sh 운영 env 원자 생성·검증 helper
backup-volume-v0.82.0.sh named volume·env 백업·복구 helper

빠른 시작

# 이미지 로드
gunzip -c ai-coding-proxy-gateway-v0.82.0.tar.gz | docker load

# 최초 1회 비밀값 파일과 nonroot 호환 named volume 준비
ENV_FILE=/opt/proxy-gateway/gateway.env
install -d -m 0700 "$(dirname "$ENV_FILE")" || exit 1
command -v openssl >/dev/null 2>&1 || { echo "openssl이 필요합니다." >&2; exit 1; }
if [ ! -e "$ENV_FILE" ]; then
  umask 077
  ADMIN_TOKEN_VALUE="$(openssl rand -hex 32)" || exit 1
  GATEWAY_SECRET_VALUE="$(openssl rand -hex 32)" || exit 1
  [ "${#ADMIN_TOKEN_VALUE}" -eq 64 ] && [ "${#GATEWAY_SECRET_VALUE}" -eq 64 ] || exit 1
  printf '%s\n' "$ADMIN_TOKEN_VALUE" | grep -Eq '^[0-9A-Fa-f]{64}$' && 
    printf '%s\n' "$GATEWAY_SECRET_VALUE" | grep -Eq '^[0-9A-Fa-f]{64}$' || exit 1
  UPSTREAM_API_KEY_VALUE="${UPSTREAM_API_KEY:-}"
  if [ -z "$UPSTREAM_API_KEY_VALUE" ]; then
    read -r -s -p 'Upstream API key: ' UPSTREAM_API_KEY_VALUE || exit 1
    echo
  fi
  case "$UPSTREAM_API_KEY_VALUE" in
    ''|*[!A-Za-z0-9._~:/+=-]*) echo 'UPSTREAM_API_KEY 형식이 안전하지 않습니다.' >&2; exit 1 ;;
  esac
  ENV_TMP="$(mktemp "${ENV_FILE}.tmp.XXXXXX")" || exit 1
  trap 'rm -f -- "$ENV_TMP"' EXIT HUP INT TERM
  {
    echo 'UPSTREAM_BASE_URL=https://api.openai.com'
    echo "UPSTREAM_API_KEY=${UPSTREAM_API_KEY_VALUE}"
    echo 'GATEWAY_VERSION=v0.82.0'
    echo "ADMIN_TOKEN=${ADMIN_TOKEN_VALUE}"
    echo "GATEWAY_SECRET=${GATEWAY_SECRET_VALUE}"
    echo 'UI_APP_ENABLED=false'
  } > "$ENV_TMP" || exit 1
  chmod 0600 "$ENV_TMP" && mv -f -- "$ENV_TMP" "$ENV_FILE" || exit 1
  trap - EXIT HUP INT TERM
fi
chmod 0600 "$ENV_FILE" || exit 1
[ "$(grep -Ec '^ADMIN_TOKEN=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^ADMIN_TOKEN=[0-9A-Fa-f]{64}$' "$ENV_FILE" && 
  [ "$(grep -Ec '^GATEWAY_SECRET=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^GATEWAY_SECRET=[0-9A-Fa-f]{64}$' "$ENV_FILE" && 
  [ "$(grep -Ec '^UPSTREAM_API_KEY=' "$ENV_FILE")" -eq 1 ] && grep -Eq '^UPSTREAM_API_KEY=[A-Za-z0-9._~:/+=-]+$' "$ENV_FILE" && 
  ! grep -q '^UPSTREAM_API_KEY=replace-before-start$' "$ENV_FILE" && 
  [ "$(grep -Ec '^GATEWAY_VERSION=' "$ENV_FILE")" -eq 1 ] && 
  grep -qxF 'GATEWAY_VERSION=v0.82.0' "$ENV_FILE" || 
  { echo "gateway.env의 필수 비밀값이 유효하지 않습니다." >&2; exit 1; }
docker volume create proxy-gateway-data >/dev/null || exit 1

docker run -d --name proxy-gateway --restart=always \
  -p 8080:8080 \
  --mount source=proxy-gateway-data,target=/data \
  --env-file "$ENV_FILE" \
  ai-coding-proxy-gateway:v0.82.0
  • Legacy Stable Console: http://localhost:8080/admin
  • Next Console Preview: http://localhost:8080/app/ (/app is OFF unless UI_APP_ENABLED=true)
  • React assets are embedded in the Go binary; the runtime image does not contain Node.js.
  • Reuse and back up the same 0600 env file; rotating GATEWAY_SECRET without migration makes stored Provider Secrets unreadable.
  • Transfer, checksum, and chmod 0700 the bundled init-deployment-env-v0.82.0.sh and backup-volume-v0.82.0.sh helpers.
  • The init helper preserves secrets and atomically updates only GATEWAY_VERSION during upgrades.