Sign inSign up

gusgh13900/api-discovery-nginx

By gusgh13900

โ€ขUpdated about 1 month ago

Real-time API discovery, Shadow API detection & ML anomaly detection dashboard for NGINX

Image
Security
API management
Monitoring & observability
0

260

gusgh13900/api-discovery-nginx repository overview

โ API Discovery for NGINX โ€” Dashboard

๐Ÿ‡ฐ๐Ÿ‡ท ํ•œ๊ตญ์–ด ๋ฌธ์„œ๋Š” ์ด ํŽ˜์ด์ง€ ์•„๋ž˜์ชฝ์— ์žˆ์Šต๋‹ˆ๋‹ค. ยท Korean documentation follows below.

Find every API endpoint behind your NGINX โ€” including the ones nobody documented.

This image reads your existing NGINX / NGINX Plus access logs and turns them into a live API inventory: which endpoints actually receive traffic, which ones are missing from your OpenAPI spec (shadow APIs), which ones answer without an Authorization header, and which ones are behaving abnormally. No application changes, no instrumentation, no SDK.

This is the collector server + web dashboard (:8080). It needs a collection agent to send it logs:

๐Ÿ”— Agent image: gusgh13900/api-discovery-agentโ  โ€” runs on your NGINX host. Keep it on the same version tag as this image.

ImageRoleDownloadOn diskRuns on
api-discovery-nginx (this image)Collector server + web dashboard (:8080)~288 MB~1 GBDashboard host
api-discovery-agentNGINX log collector~21 MB~56 MBNGINX host
  • Source: open source under Apache-2.0 โ€” github.com/VEEP09/api-discovery-for-nginxโ 
  • Architecture: linux/amd64 (no ARM build)
  • Configuration: entirely through environment variables. No config file to mount โ€” pull and run. Secrets are never baked into the image.

โ Quick start

docker run -d --name api-discovery-nginx \
  -p 8080:8080 \
  -e INGEST_TOKEN=<a shared secret you choose> \
  -v $PWD/output:/app/output \
  gusgh13900/api-discovery-nginx:1.2.1

Open http://<dashboard-host>:8080.

โš ๏ธ Change the default password. The dashboard requires a session login and creates a default administrator admin / admin1234 on first start. Log in and change it immediately. Accounts live in output/auth_users.json on your volume, so they survive restarts and upgrades.

Then deploy gusgh13900/api-discovery-agentโ  on your NGINX host with the same INGEST_TOKEN. Data starts arriving within one poll interval (30s by default).

If the dashboard shows "no agent connected", the cause is almost always an INGEST_TOKEN that does not match on both sides.


โ What you get

  • Automatic API inventory โ€” path parameters are normalized (/users/{id}, /orders/{uuid}) so raw URIs collapse into real endpoints.
  • Shadow API detection โ€” endpoints receiving live traffic that are absent from your OpenAPI spec.
  • ML / DL anomaly detection โ€” autoencoder + LSTM models flag abnormal traffic patterns.
  • Off-hours and suspicious-IP detection.
  • Latency percentiles โ€” p50 / p95 / p99 per endpoint.
  • Unauthenticated endpoint flagging โ€” endpoints served without an Authorization header.
  • OpenAPI export โ€” download the discovered surface as a spec.
  • Try Request โ€” replay a discovered endpoint from the UI.
  • Connected agents view โ€” health and last-seen for every agent.
  • NGINX Plus metrics โ€” optional, when the Plus REST API is reachable.
  • Session login + RBAC โ€” admin and viewer roles.

โ Environment variables

VariableDefaultDescription
INGEST_TOKEN(empty)Shared secret the agent must present. Leaving it empty disables authentication on /api/ingest โ€” only acceptable on a trusted local network.
DASHBOARD_SECRET(generated)Session cookie signing key. Generated into output/auth_secret if unset. Set explicitly if you run more than one instance.
  • Port: 8080 (fixed inside the container)
  • Volume: /app/output โ€” SQLite database, analysis results, trained models, user accounts, signing key
  • Health check: GET /healthz

โ docker-compose

curl -O https://raw.githubusercontent.com/VEEP09/api-discovery-for-nginx/main/docker-compose.yml
INGEST_TOKEN=<token> docker compose up -d

The agent has its own compose file โ€” see the agent image pageโ . Run it on your NGINX host, not here.


โ Required NGINX log format

The agent expects a JSON access log. Add this to your NGINX configuration:

# /etc/nginx/nginx.conf
http {
     log_format api_discovery escape=json
     '{'
         '"time":"$time_iso8601",'
         '"remote_addr":"$remote_addr",'
         '"method":"$request_method",'
         '"uri":"$uri",'
         '"query_string":"$query_string",'
         '"status":$status,'
         '"body_bytes_sent":$body_bytes_sent,'
         '"request_length":$request_length,'
         '"request_time":$request_time,'
         '"http_user_agent":"$http_user_agent",'
         '"http_referer":"$http_referer",'
         '"http_x_forwarded_for":"$http_x_forwarded_for",'
         '"http_authorization":"$http_authorization",'
         '"http_content_type":"$http_content_type",'
         '"http_accept":"$http_accept",'
         '"upstream_response_time":"$upstream_response_time",'
         '"host":"$host",'
         '"request_id":"$request_id"'
     '}';

    access_log /var/log/nginx/api_access.log api_discovery;
}

Works with open-source NGINX. NGINX Plus is optional and only adds the extra REST API metrics.


โ Versions

TagDescription
latestNewest stable release (currently 1.2.1)
1.2.1Fixes for the EN/KO switcher (help icons, re-render, 81 unkeyed strings). Release notesโ 
1.2.0English interface with an EN/KO switcher. Release notesโ 
1.1.0~288 MB to pull, down from ~2.8 GB. Release notesโ 
1.0.0Initial release (~2.8 GB โ€” superseded, use 1.1.0)

Pin a version tag in production rather than using latest, and keep the dashboard and agent on the same tag. Sizes above are compressed download sizes.



โ ํ•œ๊ตญ์–ด

โ API Discovery for NGINX โ€” ๋Œ€์‹œ๋ณด๋“œ

NGINX ๋’ค์— ์‹ค์ œ๋กœ ์‚ด์•„ ์žˆ๋Š” API๋ฅผ ์ „๋ถ€ ์ฐพ์•„๋ƒ…๋‹ˆ๋‹ค โ€” ์•„๋ฌด๋„ ๋ฌธ์„œํ™”ํ•˜์ง€ ์•Š์€ ๊ฒƒ๊นŒ์ง€.

์ด๋ฏธ ์Œ“์ด๊ณ  ์žˆ๋Š” NGINX / NGINX Plus ์•ก์„ธ์Šค ๋กœ๊ทธ๋ฅผ ์ฝ์–ด ์‹ค์‹œ๊ฐ„ API ์ธ๋ฒคํ† ๋ฆฌ๋ฅผ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์–ด๋–ค ์—”๋“œํฌ์ธํŠธ์— ์‹ค์ œ ํŠธ๋ž˜ํ”ฝ์ด ์˜ค๋Š”์ง€, OpenAPI ์ŠคํŽ™์— ์—†๋Š” ์—”๋“œํฌ์ธํŠธ(Shadow API)๋Š” ๋ฌด์—‡์ธ์ง€, Authorization ํ—ค๋” ์—†์ด ์‘๋‹ตํ•˜๋Š” ์—”๋“œํฌ์ธํŠธ๋Š” ์–ด๋””์ธ์ง€, ํ‰์†Œ์™€ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์€ ๋ฌด์—‡์ธ์ง€๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ˆ˜์ •๋„, ๊ณ„์ธก ์ฝ”๋“œ๋„, SDK๋„ ํ•„์š” ์—†์Šต๋‹ˆ๋‹ค.

์ด ์ด๋ฏธ์ง€๋Š” ์ˆ˜์ง‘ ์„œ๋ฒ„ + ์›น ๋Œ€์‹œ๋ณด๋“œ(:8080) ์ž…๋‹ˆ๋‹ค. ๋กœ๊ทธ๋ฅผ ๋ณด๋‚ด์ค„ ์ˆ˜์ง‘ ์—์ด์ „ํŠธ๊ฐ€ ํ•จ๊ป˜ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ”— ์—์ด์ „ํŠธ ์ด๋ฏธ์ง€: gusgh13900/api-discovery-agentโ  โ€” NGINX ์„œ๋ฒ„์—์„œ ์‹คํ–‰. ์ด ์ด๋ฏธ์ง€์™€ ๋™์ผํ•œ ๋ฒ„์ „ ํƒœ๊ทธ๋กœ ๋งž์ถฐ ์‚ฌ์šฉํ•˜์„ธ์š”.

์ด๋ฏธ์ง€์—ญํ• ๋‹ค์šด๋กœ๋“œ๋””์Šคํฌ์‹คํ–‰ ์œ„์น˜
api-discovery-nginx (์ด ์ด๋ฏธ์ง€)์ˆ˜์ง‘ ์„œ๋ฒ„ + ์›น ๋Œ€์‹œ๋ณด๋“œ (:8080)~288 MB~1 GB๋Œ€์‹œ๋ณด๋“œ ์„œ๋ฒ„
api-discovery-agentNGINX ๋กœ๊ทธ ์ˆ˜์ง‘ ์—์ด์ „ํŠธ~21 MB~56 MBNGINX ์„œ๋ฒ„
  • ์†Œ์Šค: Apache-2.0 ์˜คํ”ˆ์†Œ์Šค โ€” github.com/VEEP09/api-discovery-for-nginxโ 
  • ์•„ํ‚คํ…์ฒ˜: linux/amd64 (ARM ๋ฏธ์ง€์›)
  • ์„ค์ •: ์ „๋ถ€ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋กœ ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค. ์„ค์ • ํŒŒ์ผ ๋งˆ์šดํŠธ ์—†์ด pull ํ›„ ๋ฐ”๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ณ , ๋น„๋ฐ€๊ฐ’์€ ์ด๋ฏธ์ง€์— ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
โ ๋น ๋ฅธ ์‹œ์ž‘
docker run -d --name api-discovery-nginx \
  -p 8080:8080 \
  -e INGEST_TOKEN=<์ง์ ‘ ์ •ํ•œ ๊ณต์œ  ํ† ํฐ> \
  -v $PWD/output:/app/output \
  gusgh13900/api-discovery-nginx:1.2.1

๋ธŒ๋ผ์šฐ์ €์—์„œ http://<๋Œ€์‹œ๋ณด๋“œ-์„œ๋ฒ„>:8080 ์ ‘์†.

โš ๏ธ ๊ธฐ๋ณธ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋ฐ˜๋“œ์‹œ ๋ณ€๊ฒฝํ•˜์„ธ์š”. ๋Œ€์‹œ๋ณด๋“œ๋Š” ์„ธ์…˜ ๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•˜๋ฉฐ ์ตœ์ดˆ ๊ธฐ๋™ ์‹œ ๊ธฐ๋ณธ ๊ด€๋ฆฌ์ž admin / admin1234 ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ๋กœ๊ทธ์ธ ํ›„ ์ฆ‰์‹œ ๋ณ€๊ฒฝํ•˜์„ธ์š”. ๊ณ„์ •์€ ๋ณผ๋ฅจ์˜ output/auth_users.json ์— ์ €์žฅ๋˜์–ด ์žฌ์‹œ์ž‘ยท์—…๊ทธ๋ ˆ์ด๋“œ์—๋„ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.

์ดํ›„ gusgh13900/api-discovery-agentโ  ๋ฅผ NGINX ์„œ๋ฒ„์— ๋™์ผํ•œ INGEST_TOKEN ์œผ๋กœ ๋„์šฐ๋ฉด ํด๋ง ์ฃผ๊ธฐ(๊ธฐ๋ณธ 30์ดˆ) ๋‚ด์— ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์˜ค๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

๋Œ€์‹œ๋ณด๋“œ์— "์—์ด์ „ํŠธ๊ฐ€ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค" ๊ฐ€ ๊ณ„์† ๋ณด์ธ๋‹ค๋ฉด, ์›์ธ์€ ๋Œ€๋ถ€๋ถ„ ์–‘์ชฝ INGEST_TOKEN ๋ถˆ์ผ์น˜์ž…๋‹ˆ๋‹ค.

โ ์ฃผ์š” ๊ธฐ๋Šฅ
  • API ์ธ๋ฒคํ† ๋ฆฌ ์ž๋™ ๊ตฌ์„ฑ โ€” ๊ฒฝ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ •๊ทœํ™”(/users/{id}, /orders/{uuid})ํ•ด ์›์‹œ URI๋ฅผ ์‹ค์ œ ์—”๋“œํฌ์ธํŠธ ๋‹จ์œ„๋กœ ๋ฌถ์Šต๋‹ˆ๋‹ค.
  • Shadow API ํƒ์ง€ โ€” ํŠธ๋ž˜ํ”ฝ์€ ๋“ค์–ด์˜ค๋Š”๋ฐ OpenAPI ์ŠคํŽ™์—๋Š” ์—†๋Š” ์—”๋“œํฌ์ธํŠธ๋ฅผ ์ฐพ์•„๋ƒ…๋‹ˆ๋‹ค.
  • ML / DL ์ด์ƒ ํƒ์ง€ โ€” AutoEncoder + LSTM ๋ชจ๋ธ์ด ๋น„์ •์ƒ ํŠธ๋ž˜ํ”ฝ ํŒจํ„ด์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
  • Off-hour ํƒ์ง€ ยท Suspicious IP ํƒ์ง€
  • ๋ ˆ์ดํ„ด์‹œ ๋ฐฑ๋ถ„์œ„ โ€” ์—”๋“œํฌ์ธํŠธ๋ณ„ p50 / p95 / p99
  • ๋ฌด์ธ์ฆ ์—”๋“œํฌ์ธํŠธ ํ‘œ์‹œ โ€” Authorization ํ—ค๋” ์—†์ด ์‘๋‹ตํ•˜๋Š” ์—”๋“œํฌ์ธํŠธ
  • OpenAPI export โ€” ํƒ์ง€๋œ API ํ‘œ๋ฉด์„ ์ŠคํŽ™์œผ๋กœ ๋‚ด๋ ค๋ฐ›๊ธฐ
  • Try Request โ€” ํƒ์ง€๋œ ์—”๋“œํฌ์ธํŠธ๋ฅผ UI์—์„œ ๋ฐ”๋กœ ํ˜ธ์ถœ
  • Connected Agents โ€” ์—์ด์ „ํŠธ๋ณ„ ์ƒํƒœ์™€ ๋งˆ์ง€๋ง‰ ์ˆ˜์‹  ์‹œ๊ฐ
  • NGINX Plus ๋ฉ”ํŠธ๋ฆญ โ€” Plus REST API ์ ‘๊ทผ ๊ฐ€๋Šฅ ์‹œ ์„ ํƒ์ ์œผ๋กœ ์ˆ˜์ง‘
  • ์„ธ์…˜ ๋กœ๊ทธ์ธ + RBAC โ€” admin / viewer ์—ญํ• 
โ ํ™˜๊ฒฝ๋ณ€์ˆ˜
๋ณ€์ˆ˜๊ธฐ๋ณธ๊ฐ’์„ค๋ช…
INGEST_TOKEN(๋นˆ ๊ฐ’)์—์ด์ „ํŠธ๊ฐ€ ์ œ์‹œํ•ด์•ผ ํ•˜๋Š” ๊ณต์œ  ํ† ํฐ. ๋น„์šฐ๋ฉด /api/ingest ์ธ์ฆ์ด ๋น„ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค โ€” ์‹ ๋ขฐ๋œ ๋‚ด๋ถ€๋ง์—์„œ๋งŒ ์‚ฌ์šฉํ•˜์„ธ์š”.
DASHBOARD_SECRET(์ž๋™ ์ƒ์„ฑ)์„ธ์…˜ ์ฟ ํ‚ค ์„œ๋ช…ํ‚ค. ๋ฏธ์ง€์ • ์‹œ output/auth_secret ์— ์ƒ์„ฑยท๋ณด์กด. ์ธ์Šคํ„ด์Šค๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ์šด์˜ํ•˜๋ฉด ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜์„ธ์š”.
  • ํฌํŠธ: 8080 (์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€ ๊ณ ์ •)
  • ๋ณผ๋ฅจ: /app/output โ€” SQLite DB, ๋ถ„์„ ๊ฒฐ๊ณผ, ํ•™์Šต๋œ ๋ชจ๋ธ, ๊ณ„์ •, ์„œ๋ช…ํ‚ค
  • ํ—ฌ์Šค์ฒดํฌ: GET /healthz
โ docker-compose
curl -O https://raw.githubusercontent.com/VEEP09/api-discovery-for-nginx/main/docker-compose.yml
INGEST_TOKEN=<ํ† ํฐ> docker compose up -d

์—์ด์ „ํŠธ๋Š” ๋ณ„๋„ compose ํŒŒ์ผ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค โ€” ์—์ด์ „ํŠธ ์ด๋ฏธ์ง€ ํŽ˜์ด์ง€โ  ์ฐธ๊ณ . NGINX ์„œ๋ฒ„์—์„œ ์‹คํ–‰ํ•˜์„ธ์š”.

โ NGINX ๋กœ๊ทธ ํฌ๋งท

์—์ด์ „ํŠธ๋Š” JSON ์•ก์„ธ์Šค ๋กœ๊ทธ๋ฅผ ์ „์ œ๋กœ ํ•ฉ๋‹ˆ๋‹ค. ์œ„ ์˜๋ฌธ ์„น์…˜์˜ log_format api_discovery ๋ธ”๋ก์„ NGINX ์„ค์ •์— ์ถ”๊ฐ€ํ•˜๊ณ  access_log ๋ฅผ ์ง€์ •ํ•˜์„ธ์š”.

์˜คํ”ˆ์†Œ์Šค NGINX์—์„œ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. NGINX Plus๋Š” ์„ ํƒ์ด๋ฉฐ REST API ๋ฉ”ํŠธ๋ฆญ์ด ์ถ”๊ฐ€๋  ๋ฟ์ž…๋‹ˆ๋‹ค.

โ ๋ฒ„์ „
ํƒœ๊ทธ์„ค๋ช…
latest์ตœ์‹  ์•ˆ์ • ๋ฒ„์ „ (ํ˜„์žฌ 1.2.1)
1.2.1์–ธ์–ด ์ „ํ™˜ ๊ฒฐํ•จ ์ˆ˜์ • (๋„์›€๋ง ์•„์ด์ฝ˜ยท์žฌ๋ Œ๋”ยท๋ฏธ๋ถ€์—ฌ ํ‚ค 81๊ฑด). ๋ฆด๋ฆฌ์Šค ๋…ธํŠธโ 
1.2.0์˜์–ด UI + EN/KO ์–ธ์–ด ์ „ํ™˜. ๋ฆด๋ฆฌ์Šค ๋…ธํŠธโ 
1.1.0๋‹ค์šด๋กœ๋“œ ~288 MB (๊ธฐ์กด ~2.8 GB์—์„œ ์ถ•์†Œ). ๋ฆด๋ฆฌ์Šค ๋…ธํŠธโ 
1.0.0์ตœ์ดˆ ๋ฆด๋ฆฌ์Šค (~2.8 GB โ€” 1.1.0 ์‚ฌ์šฉ ๊ถŒ์žฅ)

ํ”„๋กœ๋•์…˜์—์„œ๋Š” latest ๋Œ€์‹  ๊ณ ์ • ๋ฒ„์ „ ํƒœ๊ทธ๋ฅผ ์“ฐ๊ณ , ๋Œ€์‹œ๋ณด๋“œ์™€ ์—์ด์ „ํŠธ๋ฅผ ๊ฐ™์€ ํƒœ๊ทธ๋กœ ๋งž์ถ”์„ธ์š”. ์œ„ ํฌ๊ธฐ๋Š” ์••์ถ•๋œ ๋‹ค์šด๋กœ๋“œ ๊ธฐ์ค€์ž…๋‹ˆ๋‹ค.

โ ๋งํฌ

NGINXยฎ is a registered trademark of F5, Inc. This project is an independent tool and is not affiliated with, endorsed by, or sponsored by F5 or NGINX. "NGINX" is used here only to describe compatibility.

Tag summary

Content type

Image

Digest

sha256:eb38b023eโ€ฆ

Size

275.2 MB

Last updated

about 1 month ago

docker pull gusgh13900/api-discovery-nginx