Security Headers
Sentinel automatically injects HTTP security headers into every response. The headers middleware is enabled by default when you call sentinel.Mount(), so your application gets a strong security baseline with zero configuration.
Enabled by Default
X-Frame-Options, X-Content-Type-Options, and Referrer-Policy headers without any configuration.Available Headers
The HeaderConfig struct controls which security headers are injected and their values. All fields are optional — sensible defaults are applied automatically.
| Header | Config Field | Type | Default |
|---|---|---|---|
Content-Security-Policy | ContentSecurityPolicy | string | (not set) |
Strict-Transport-Security | StrictTransportSecurity | bool | false |
X-Frame-Options | XFrameOptions | string | "DENY" |
X-Content-Type-Options | XContentTypeOptions | bool | true (emits "nosniff") |
Referrer-Policy | ReferrerPolicy | string | "strict-origin-when-cross-origin" |
Permissions-Policy | PermissionsPolicy | string | (not set) |
Configuration
Pass a HeaderConfig inside your sentinel.Config to customise the headers. Fields you omit keep their defaults.
1package main23import (4 sentinel "github.com/MUKE-coder/sentinel"5 "github.com/gin-gonic/gin"6)78func main() {9 r := gin.Default()1011 sentinel.Mount(r, nil, sentinel.Config{12 Headers: sentinel.HeaderConfig{13 ContentSecurityPolicy: "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'",14 StrictTransportSecurity: true,15 XFrameOptions: "SAMEORIGIN",16 XContentTypeOptions: true,17 ReferrerPolicy: "strict-origin-when-cross-origin",18 PermissionsPolicy: "camera=(), microphone=(), geolocation=()",19 },20 })2122 r.GET("/api/data", func(c *gin.Context) {23 c.JSON(200, gin.H{"status": "ok"})24 })2526 r.Run(":8080")27}
To use only the defaults (X-Frame-Options, X-Content-Type-Options, and Referrer-Policy), you do not need to set the Headers field at all:
// Defaults are applied automatically — these three headers are set:// X-Frame-Options: DENY// X-Content-Type-Options: nosniff// Referrer-Policy: strict-origin-when-cross-originsentinel.Mount(r, nil, sentinel.Config{})
Disabling Security Headers
Enabled as a false pointer:disabled := falsesentinel.Mount(r, nil, sentinel.Config{Headers: sentinel.HeaderConfig{Enabled: &disabled,},})
What Each Header Does
Content-Security-Policy (CSP)
Controls which resources (scripts, styles, images, fonts, etc.) the browser is allowed to load. A well-configured CSP is one of the most effective defenses against cross-site scripting (XSS) attacks because it prevents the browser from executing injected scripts even if they make it into the HTML.
ContentSecurityPolicy: "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"
CSP Not Set by Default
Strict-Transport-Security (HSTS)
Tells browsers to only access your site over HTTPS for a specified duration. This prevents protocol downgrade attacks and cookie hijacking. When enabled, Sentinel sets:
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
The max-age=63072000 value (2 years) with includeSubDomains and preload follows current best practices. Only enable this when your site is fully served over HTTPS.
HSTS Is Sticky
max-age duration. Only set StrictTransportSecurity: true when you are certain your site and all subdomains support HTTPS.X-Frame-Options
Prevents your pages from being embedded in <iframe>, <frame>, or <object> elements on other sites. This is the primary defense against clickjacking attacks, where an attacker overlays your UI with a transparent iframe to trick users into clicking hidden elements.
| Value | Behavior |
|---|---|
"DENY" | Page cannot be framed by any site, including your own. (Default) |
"SAMEORIGIN" | Page can only be framed by pages on the same origin. |
X-Content-Type-Options
Prevents browsers from MIME-sniffing a response away from the declared Content-Type. Without this header, a browser might interpret a text file as JavaScript or HTML, enabling attacks where an attacker uploads a file with a misleading extension. The only valid value is "nosniff", which is always set when this option is true.
Referrer-Policy
Controls how much referrer information is sent when navigating away from your site. The default "strict-origin-when-cross-origin" sends the full URL for same-origin requests but only the origin (no path or query string) for cross-origin requests, and nothing when downgrading from HTTPS to HTTP. This protects sensitive URL parameters from leaking to third parties.
| Value | Behavior |
|---|---|
"no-referrer" | Never send referrer information. |
"same-origin" | Only send referrer for same-origin requests. |
"strict-origin-when-cross-origin" | Full URL for same-origin, origin only for cross-origin, nothing on downgrade. (Default) |
Permissions-Policy
Controls which browser features and APIs your site can use (camera, microphone, geolocation, payment, etc.). This limits the damage if an attacker injects code into your page — even injected scripts cannot access restricted APIs.
// Disable camera, microphone, and geolocation for all originsPermissionsPolicy: "camera=(), microphone=(), geolocation=()"// Allow geolocation only from your own originPermissionsPolicy: "camera=(), microphone=(), geolocation=(self)"
Testing with curl
Use curl -v to verify that security headers are present on responses from your application.
# Inspect response headerscurl -v http://localhost:8080/api/data 2>&1 | grep -i "x-frame\|x-content\|referrer\|content-security\|strict-transport\|permissions-policy"# Expected output (with full configuration):# < X-Frame-Options: SAMEORIGIN# < X-Content-Type-Options: nosniff# < Referrer-Policy: strict-origin-when-cross-origin# < Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'# < Strict-Transport-Security: max-age=63072000; includeSubDomains; preload# < Permissions-Policy: camera=(), microphone=(), geolocation=()
# With default configuration (no Headers config), you will see:curl -v http://localhost:8080/api/data 2>&1 | grep -i "x-frame\|x-content\|referrer"# < X-Frame-Options: DENY# < X-Content-Type-Options: nosniff# < Referrer-Policy: strict-origin-when-cross-origin
Check All Headers at Once
curl -I http://localhost:8080/api/data to see all response headers in a compact format. The -I flag sends a HEAD request and prints only the headers.Next Steps
- WAF -- Protect against SQL injection, XSS, and other attacks at the request level
- Rate Limiting -- Throttle abusive traffic before it reaches your handlers
- Configuration Reference -- Full list of all Sentinel configuration options