include api_backends.conf; include api_keys.conf; limit_req_zone $binary_remote_addr zone=client_ip_10rs:1m rate=1r/s; limit_req_zone $http_apikey zone=apikey_200rs:1m rate=200r/s; server { access_log /var/log/nginx/api_access.log main; # Each API may also log to a # separate file listen 443 ssl; server_name api.example.com; # TLS config ssl_certificate /etc/ssl/certs/api.example.com.crt; ssl_certificate_key /etc/ssl/private/api.example.com.key; ssl_session_cache shared:SSL:10m; ssl_session_timeout 5m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_protocols TLSv1.2 TLSv1.3; # API definitions, one per file include api_conf.d/*.conf; # Error responses error_page 404 = @400; # Invalid paths are treated as bad requests proxy_intercept_errors on; # Do not send backend errors to the client include api_json_errors.conf; # API client friendly JSON error responses default_type application/json; # If no content-type then assume JSON # API key validation location = /_validate_apikey { internal; if ($http_apikey = "") { return 401; # Unauthorized } if ($api_client_name = "") { return 403; # Forbidden } return 204; # OK (no content) } # Dummy location used to populate $request_body for JSON validation location /_get_request_body { return 204; } } js_import json_validation.js; js_set $json_validated json_validation.parseRequestBody; server { listen 127.0.0.1:10415; return 415; # Unsupported media type include api_json_errors.conf; } # Access to write operations is evaluated by JWT claim 'admin' map $request_method $admin_permitted_method { "GET" true; "HEAD" true; "OPTIONS" true; default $jwt_claim_admin; } # vim: syntax=nginx