Skip to content

SecurityConfig

SecurityConfig is the central configuration object for all @guardcore adapters. It is validated at startup using a Zod schema. All fields have sensible defaults — you only need to specify what you want to change.

import { SecurityConfigSchema } from '@guardcore/core';
import type { SecurityConfig } from '@guardcore/core';
const config: SecurityConfig = {
rateLimit: 100,
rateLimitWindow: 60,
};
const resolved = SecurityConfigSchema.parse(config);
FieldTypeDefaultDescription
trustedProxiesstring[][]IP addresses or CIDR ranges of trusted reverse proxies
trustedProxyDepthnumber1How many X-Forwarded-For hops to trust
trustXForwardedProtobooleanfalseTrust X-Forwarded-Proto header for HTTPS detection
passiveModebooleanfalseLog violations without blocking requests
FieldTypeDefaultDescription
whiteliststring[] | nullnullIP/CIDR allowlist. When set, only these IPs are allowed
blackliststring[][]IP/CIDR blocklist. These IPs are always blocked
exemptIpsstring[][]IP/CIDR skip-list for trusted automation. Entries skip rate limiting, the user-agent check and per-route cloud-provider blocks
whitelistCountriesstring[][]Two-letter country codes to allow (requires geoIpHandler or geoResolver)
blockedCountriesstring[][]Two-letter country codes to block (requires geoIpHandler or geoResolver)

exemptIps is noise reduction for known-friendly automation (monitoring probes, VPN egress, a partner’s server), not immunity. A non-empty whitelist is also an allowlist: every IP not on it is denied by the global IP check, so it cannot be used to let a few clients skip throttling on a public API. exemptIps is not restrictive: every unlisted IP is checked exactly as usual, and a match only sets the same skip state a whitelist match sets (rate limiting, user-agent check, per-route cloud-provider blocks). Everything else still applies to listed IPs: penetration detection (attack payloads are still blocked and counted), the blacklist, dynamic IP bans, per-route requireIp/blockIp rules, the global blockCloudProviders list, HTTPS enforcement and security headers. Entries accept IPv4, IPv6 and CIDR forms, validated at config construction (an invalid entry fails closed). The two lists may coexist; an IP on both is simply a whitelist match.

FieldTypeDefaultDescription
rateLimitnumber10Max requests per window per IP
rateLimitWindownumber60Window duration in seconds
enableRateLimitingbooleantrueEnable/disable rate limiting globally
endpointRateLimitsRecord<string, [number, number]>{}Per-endpoint overrides: { "/api/search": [5, 60] }
FieldTypeDefaultDescription
enablePenetrationDetectionbooleantrueEnable the 75-pattern detection engine
detectionCompilerTimeoutnumber2.0Regex compilation timeout in seconds (0.1-10)
detectionMaxContentLengthnumber10000Max content length for scanning (1000-100000)
detectionPreserveAttackPatternsbooleantruePreserve attack regions when truncating long content
detectionSemanticThresholdnumber0.7Semantic analysis threat score threshold (0-1)
detectionAnomalyThresholdnumber3.0Z-score threshold for performance anomaly detection (1-10)
detectionSlowPatternThresholdnumber0.1Seconds before a pattern is considered slow (0.01-1)
detectionMonitorHistorySizenumber1000Number of recent metrics to keep (100-10000)
detectionMaxTrackedPatternsnumber1000Max patterns to track in performance monitor (100-5000)

Every penetration-detection violation increments the source IP’s counter for the matched detection category. When a threshold is crossed, the IP is banned and subsequent requests are blocked with 403 by the IP check. threatBanConfig entries fire at their own threshold and duration; everything else falls back to the flat autoBanThreshold/autoBanDuration pair measured against the IP’s total across categories.

FieldTypeDefaultDescription
enableIpBanningbooleantrueEnable automatic IP banning. false disables ban creation entirely; enforcement of already-active bans is unaffected
autoBanThresholdnumber10Total violations across categories before auto-ban (fallback when no threatBanConfig entry matched)
autoBanDurationnumber3600Fallback ban duration in seconds
threatBanConfigRecord<string, { threshold: number; duration: number }>{}Per-category ban thresholds and durations. Keys are the detection categories (xss, sqli, dir_traversal, cmd_injection, …) plus the rate_limit pseudo-category; unknown keys fail validation
enableRateLimitAutoBanbooleanfalseFeed rate-limit violations into the same autoban engine: each active-mode (non-passive) violation increments the rate_limit category, with a threatBanConfig['rate_limit'] override or the flat threshold fallback. Requires enableIpBanning to actually ban
FieldTypeDefaultDescription
blockedUserAgentsstring[][]Substring patterns to match against User-Agent header
FieldTypeDefaultDescription
securityHeadersobject | nullSee Security HeadersSecurity headers configuration object
enforceHttpsbooleanfalseRedirect HTTP requests to HTTPS
FieldTypeDefaultDescription
enableCorsbooleanfalseEnable CORS handling
corsAllowOriginsstring[]['*']Allowed origins
corsAllowMethodsstring[]['GET','POST','PUT','PATCH','DELETE','OPTIONS']Allowed methods
corsAllowHeadersstring[]['*']Allowed headers
corsAllowCredentialsbooleanfalseAllow credentials
corsExposeHeadersstring[][]Headers exposed to the browser
corsMaxAgenumber600Preflight cache duration in seconds
FieldTypeDefaultDescription
blockCloudProviders('AWS' | 'GCP' | 'Azure')[][]Cloud providers to block. Requests whose IP falls in a selected provider’s refreshed ranges get 403; routes can override the list per-route via the blockCloudProviders route selector, and whitelist/exempt IPs skip the check
cloudIpRefreshIntervalnumber3600Seconds between cloud IP range refreshes (60-86400)
FieldTypeDefaultDescription
geoIpHandlerGeoIPHandlerundefinedGeoIP handler instance (e.g., IPInfoManager)
geoResolver(ip: string) => string | nullundefinedSimple function returning 2-letter country code
FieldTypeDefaultDescription
enableAgentbooleanfalseEnable telemetry agent
agentApiKeystring | nullnullAPI key (required when enableAgent is true)
agentEndpointstring'https://api.fastapi-guard.com'Agent endpoint URL
agentProjectIdstring | nullnullProject identifier
agentBufferSizenumber100Events buffered before flush
agentFlushIntervalnumber30Flush interval in seconds
agentEnableEventsbooleantrueSend security events
agentEnableMetricsbooleantrueSend performance metrics
agentTimeoutnumber30Request timeout in seconds
agentRetryAttemptsnumber3Retry count on failure
FieldTypeDefaultDescription
enableDynamicRulesbooleanfalseEnable agent-driven rule updates (requires enableAgent)
dynamicRuleIntervalnumber300Polling interval in seconds
FieldTypeDefaultDescription
enableRedisbooleantrueEnable Redis for distributed state
redisUrlstring'redis://localhost:6379'Redis connection URL
redisPrefixstring'guard_core:'Prefix for all Redis keys
FieldTypeDefaultDescription
loggerLoggerdefaultLoggerCustom logger instance
customLogFilestring | nullnullPath to a log file
logSuspiciousLevelstring | null'WARNING'Log level for suspicious requests
logRequestLevelstring | nullnullLog level for all requests (null = disabled)
logFormat'text' | 'json''text'Log output format
FieldTypeDefaultDescription
emergencyModebooleanfalseBlock all traffic except whitelisted IPs
emergencyWhiteliststring[][]IPs allowed during emergency mode
FieldTypeDefaultDescription
excludePathsstring[][]URL paths to skip all security checks
customErrorResponsesRecord<number, string>{}Custom error messages by status code
customRequestCheck(req: GuardRequest) => Promise<GuardResponse | null>undefinedCustom check function run at the end of the pipeline
customResponseModifier(res: GuardResponse) => Promise<GuardResponse>undefinedModify responses before sending

The schema enforces these constraints:

  • agentApiKey is required when enableAgent is true
  • enableAgent must be true when enableDynamicRules is true
  • geoIpHandler or geoResolver is required when using blockedCountries or whitelistCountries
import type { SecurityConfig } from '@guardcore/core';
const config: SecurityConfig = {
trustedProxies: ['10.0.0.0/8'],
trustedProxyDepth: 2,
trustXForwardedProto: true,
enableRedis: true,
redisUrl: process.env.REDIS_URL ?? 'redis://localhost:6379',
rateLimit: 100,
rateLimitWindow: 60,
endpointRateLimits: {
'/api/login': [5, 300],
'/api/search': [20, 60],
},
enablePenetrationDetection: true,
detectionSemanticThreshold: 0.7,
autoBanThreshold: 5,
autoBanDuration: 7200,
threatBanConfig: {
sqli: { threshold: 3, duration: 86400 },
rate_limit: { threshold: 3, duration: 1800 },
},
enableRateLimitAutoBan: true,
blockedUserAgents: ['sqlmap', 'nikto', 'nmap', 'masscan'],
enforceHttps: true,
enableCors: true,
corsAllowOrigins: ['https://app.example.com'],
corsAllowCredentials: true,
excludePaths: ['/health', '/metrics'],
customErrorResponses: {
403: 'Access denied',
429: 'Too many requests, slow down',
},
};