You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# Development mode
iex -S mix
# Production mode
MIX_ENV=prod mix run --no-halt
Authentication Examples
API Key Authentication
# Using Authorization header
curl -H "Authorization: ApiKey demo-key-1" \
http://localhost:4000/api/v1/jobs
# Using query parameter
curl http://localhost:4000/api/v1/jobs?api_key=demo-key-1
JWT Token Authentication
# Generate a token (in IEx){:ok,token,claims}=NsaiGateway.Auth.JWT.generate("tenant-alpha","user-123",3600)# Use the tokencurl-H "Authorization: Bearer#{token}" \http://localhost:4000/api/v1/samples
# Example with real token
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
http://localhost:4000/api/v1/experiments
# Work service (jobs)
curl -H "Authorization: ApiKey demo-key-1" \
http://localhost:4000/api/v1/jobs/list
# Forge service (samples)
curl -H "Authorization: ApiKey demo-key-1" \
http://localhost:4000/api/v1/samples/create \
-X POST \
-H "Content-Type: application/json" \
-d '{"data": "example"}'# Anvil service (labels)
curl -H "Authorization: ApiKey demo-key-1" \
http://localhost:4000/api/v1/labels/123
# Crucible service (experiments)
curl -H "Authorization: ApiKey demo-key-1" \
http://localhost:4000/api/v1/experiments?status=running
Rate Limiting Examples
Hitting Rate Limits
# Generate many requests to hit the limitforiin {1..110};do
curl -H "Authorization: ApiKey demo-key-1" \
http://localhost:4000/api/v1/jobs &donewait# After 100 requests, you'll get:# HTTP/1.1 429 Too Many Requests# Retry-After: 60# {"error":"Rate Limit Exceeded","message":"Too many requests. Please try again later."}
Configuration Examples
Environment Variables
# Set portexport PORT=8080
# Set JWT secretexport JWT_SECRET="your-secure-random-secret-here"# Set service URLsexport WORK_SERVICE_URL="http://work-service:4001"export FORGE_SERVICE_URL="http://forge-service:4002"export ANVIL_SERVICE_URL="http://anvil-service:4003"export CRUCIBLE_SERVICE_URL="http://crucible-service:4004"# Start gateway
mix run --no-halt
Custom Configuration
# config/config.exsconfig:nsai_gateway,port: 4000,tenant_rate_limit: 2000,# 2000 requests per minuteendpoint_rate_limits: %{"jobs"=>200,"samples"=>300,"labels"=>150,"experiments"=>100}# Add new API keyconfig:nsai_gateway,:api_keys,%{"demo-key-1"=>"tenant-alpha","demo-key-2"=>"tenant-beta","prod-key-abc123"=>"production-tenant"}
Telemetry Examples
Attaching Custom Handlers
# In your application startupdefmoduleMyApp.TelemetryHandlerdorequireLoggerdefsetupdoevents=[[:nsai_gateway,:proxy,:success],[:nsai_gateway,:proxy,:error]]:telemetry.attach_many("my-app-gateway-handler",events,&handle_event/4,nil)enddefhandle_event([:nsai_gateway,:proxy,:success],measurements,metadata,_config)doduration_ms=System.convert_time_unit(measurements.duration,:native,:millisecond)# Send to your metrics systemMyApp.Metrics.record("gateway.proxy.duration",duration_ms,service: metadata.service,status: metadata.status)enddefhandle_event([:nsai_gateway,:proxy,:error],measurements,metadata,_config)do# Track errorsMyApp.Metrics.increment("gateway.proxy.errors",service: metadata.service,reason: metadata.reason)endend
# Test authentication
curl -v http://localhost:4000/api/v1/jobs
# Should return 401 Unauthorized
curl -v -H "Authorization: ApiKey demo-key-1" http://localhost:4000/api/v1/jobs
# Should proxy to work service# Test health check
curl http://localhost:4000/health
# Should return 200 with healthy status# Test rate limiting
./scripts/rate_limit_test.sh
Integration Testing
# test/integration/gateway_test.exsdefmoduleIntegration.GatewayTestdouseExUnit.Case@gateway_url"http://localhost:4000"@api_key"demo-key-1"test"can authenticate and proxy request"doresponse=Req.get!("#{@gateway_url}/api/v1/jobs",headers: [{"authorization","ApiKey #{@api_key}"}])assertresponse.status==200endtest"respects rate limits"do# Make 110 requests (limit is 100)results=for_<-1..110doReq.get("#{@gateway_url}/api/v1/jobs",headers: [{"authorization","ApiKey #{@api_key}"}])end# Count 429 responsesrate_limited=Enum.count(results,fn{:ok,%{status: 429}}->true_->falseend)assertrate_limited>0endend
Monitoring Examples
Prometheus Integration
# Add to your supervision treedefmoduleMyApp.MetricsdousePrometheus.PlugExporterdefsetupdo# Define metricsPrometheus.Gauge.declare(name: :gateway_requests_total,help: "Total gateway requests",labels: [:service,:status])Prometheus.Histogram.declare(name: :gateway_request_duration_seconds,help: "Gateway request duration",labels: [:service],buckets: [0.01,0.05,0.1,0.5,1,2,5])# Attach to telemetry:telemetry.attach("prometheus-gateway",[:nsai_gateway,:proxy,:success],&handle_metrics/4,nil)enddefhandle_metrics(_event,measurements,metadata,_config)doPrometheus.Gauge.inc(name: :gateway_requests_total,labels: [metadata.service,metadata.status])duration_seconds=System.convert_time_unit(measurements.duration,:native,:second)Prometheus.Histogram.observe([name: :gateway_request_duration_seconds,labels: [metadata.service]],duration_seconds)endend