How k-skill-proxy Provides Secure Access to Korean Government APIs
k-skill-proxy is a Fastify-based HTTP reverse proxy that normalizes client requests, injects authentication keys, and applies rate-limiting and caching to provide unified access to Korean public data services including AirKorea, KMA, and Seoul Open API.
The k-skill-proxy package within the NomaDamas/k-skill repository eliminates the complexity of directly integrating with Korean government APIs. It handles authentication, parameter validation, and error mapping so client applications can consume public data through a single, consistent interface mounted under /v1/<service>.
Configuration and Secret Isolation
On startup, the proxy builds a configuration object using buildConfig() defined in /packages/k-skill-proxy/src/server.js. This function extracts sensitive API keys from environment variables such as AIR_KOREA_OPEN_API_KEY, KMA_OPEN_API_KEY, and SEOUL_OPEN_API_KEY, keeping credentials out of source control and making the server portable across environments.
Request Validation and Normalization
Before forwarding traffic upstream, the proxy validates incoming queries through service-specific normalizer functions. These guarantee that only well-formed requests reach government endpoints.
normalizeFineDustQueryvalidatesregionHintandstationNameparameters for AirKorea requests in/packages/k-skill-proxy/src/server.jsnormalizeKmaForecastQuerysanitizes Korean Meteorological Administration forecast parametersnormalizeNeisSchoolMealQueryprocesses school meal queries for the NEIS system
This validation layer prevents malformed requests from consuming upstream quota or triggering errors.
Route Whitelisting and Security
The proxy implements strict route whitelisting to limit attack surface. For AirKorea integration, the allowed service-operation pairs are stored in ALLOWED_AIRKOREA_ROUTES and verified via isAllowedAirKoreaRoute() before any upstream call occurs.
Additionally, the redactSecretValue() function scrubs API keys from upstream responses. If a government service echoes the authentication key in its payload, the proxy replaces it with [REDACTED] to prevent accidental leakage in logs or client responses.
Caching and Rate Limiting
To protect upstream services and improve performance, k-skill-proxy implements dual protection layers:
In-Memory Caching: Responses are cached using createMemoryCache() with entries keyed by makeCacheKey(), which hashes the request payload. The LRU cache respects configurable TTL and size limits defined in the server configuration.
Rate Limiting: A per-IP token bucket algorithm implemented in buildRateLimiter() restricts the number of requests a single client can submit within a configurable time window, preventing abuse of expensive government API quotas.
Upstream Integration and Proxy Logic
When a validated request passes all guards, the proxy constructs the upstream URL in functions like proxyAirKoreaRequest(). The implementation in /packages/k-skill-proxy/src/server.js appends the appropriate serviceKey parameter and executes a fetch call with a 20-second timeout.
Each service module—such as airkorea.js, kma-weather.js, and neis-school-meal.js—registers its own Fastify route mounted under /v1/<service>. This creates clean endpoints like GET /v1/airkorea or GET /v1/kma-forecast that abstract away the underlying government API complexity.
Response Wrapping and Error Handling
All responses are wrapped in a uniform JSON envelope containing statusCode, contentType, and the (optionally redacted) body. Error handling maps upstream failures to standard HTTP status codes:
- Missing API keys return
503 Service Unavailablewith details like"AIR_KOREA_OPEN_API_KEY is not configured" - Disallowed routes return
403 Forbidden - Upstream timeouts or failures return
502 Bad Gateway
Practical Usage Examples
Call the proxy endpoints without handling API keys or complex authentication signatures:
# AirKorea real-time fine dust data
curl "http://localhost:4020/v1/airkorea?service=ArpltnInforInqireSvc&operation=getCtprvnRltmMesureDnsty®ionHint=Seoul"
# Korean Meteorological Administration forecast
curl "http://localhost:4020/v1/kma-forecast?nx=60&ny=127&baseDate=20240803&baseTime=0200"
// NEIS school meal information using Node.js
import fetch from 'node-fetch';
const resp = await fetch(
'http://localhost:4020/v1/neis/meal?atptOfcdcScCode=J10&sdSchulCode=7010569&mlsvYmd=20240803'
);
const data = await resp.json();
console.log(data);
Each request automatically receives parameter validation, API key injection, rate-limit checking, and cache lookup—completely transparent to the client.
Summary
- k-skill-proxy provides a unified Fastify-based interface to Korean government APIs including AirKorea, KMA, and NEIS
- Configuration management via
buildConfig()isolates API keys in environment variables - Security layers include route whitelisting (
ALLOWED_AIRKOREA_ROUTES), request normalization, and secret redaction (redactSecretValue()) - Performance protections implement LRU caching (
createMemoryCache) and per-IP rate limiting (buildRateLimiter) - Consistent interface exposes all services under
/v1/<service>endpoints with standardized error handling and response wrapping
Frequently Asked Questions
What government services does k-skill-proxy support?
The proxy currently wraps multiple Korean public data sources including AirKorea (environmental data), Korean Meteorological Administration (weather forecasts), Seoul Open API, Data.go.kr, NEIS (school information), and Korean legal information services. Each integration lives in its own module under /packages/k-skill-proxy/src/.
How does the proxy handle API key security?
API keys are never exposed to clients. The server stores them in environment variables loaded via buildConfig(), injects them into upstream requests internally, and scrubs them from responses using redactSecretValue(). If a key is missing, the proxy returns a 503 error before attempting the upstream call.
Can I deploy k-skill-proxy without rate limiting?
The rate limiter is configurable through environment variables during the buildRateLimiter() initialization. While you can adjust the token bucket settings to be permissive, removing protection entirely would require modifying the source code in /packages/k-skill-proxy/src/server.js, which is not recommended for production deployments.
What happens when a government API is down?
The proxy implements a 20-second timeout on all upstream fetch calls. If the upstream fails or times out, the proxy returns a 502 Bad Gateway or 504 Gateway Timeout with a descriptive error message, preventing client applications from hanging indefinitely.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →