# HELMET > HELMET is a small PHP package that sends the security headers and a nonce-based CSP, hardens the session, checks the proxy, answers /up and writes JSON logs. Raw PHP, Laravel and PSR-15 apps all use the same core. GIF via [Tenor](https://tenor.com/view/helmet-band-wilmas-rainbow-helmet-band-music-gif-25658120) **Put it on before you ship.** Security headers, a hardened session and an honest proxy check, snapped on before the first page is served. Checks: `composer ci` (the same command runs on GitLab and GitHub). Two mirrors, one command: the only thing in this repo that plays both sides is the CI. Front page: [`site/index.html`](https://nougat.snu.gs/enterprise-apps/helmet/blob/HEAD/site/index.html), the playbook, as static files ([`site/README.md`](https://nougat.snu.gs/enterprise-apps/helmet/blob/HEAD/site/README.md)). On Citadel it is served by the raw-PHP deploy layer in [`deploy/`](https://nougat.snu.gs/enterprise-apps/helmet/blob/HEAD/deploy/): a Squire kit whose front controller serves `site/` behind HELMET's security headers. For local development, keep serving `site/` directly. Documentation: [helmet.apps.wayne.edu/docs/](https://helmet.apps.wayne.edu/docs/) carries the overview and the environment variables the package reads, with more pages on the way. HELMET is the Wayne State app stack's baseline runtime. One small framework-free PHP core, `Waynestate\Helmet`, does the five things every app on Citadel needs before it serves a single page: it sends the security headers, hardens the session, decides whether the request really arrived over HTTPS, answers the load balancer's `/up` ping, and writes structured logs. Every page below is Markdown. The HTML pages send the same Markdown to a client that asks for `text/markdown`. Written by Squire's agent-ready kit from the README and the pages; do not edit. ## Pages - [HELMET: Put it on before you ship.](https://helmet.apps.wayne.edu/index.md): HELMET is a small PHP package that sends the security headers and a nonce-based CSP, hardens the session, checks the proxy, answers /up and writes JSON logs. Raw PHP, Laravel and PSR-15 apps all use the same core. - [Changelog | HELMET docs](https://helmet.apps.wayne.edu/docs/changelog.md): All notable changes to this project. - [Cross-origin isolation and feature policy | HELMET docs](https://helmet.apps.wayne.edu/docs/guides/cross-origin-isolation.md): Three more headers round out the baseline: Cross-Origin-Opener-Policy and Permissions-Policy are on by default, Cross-Origin-Resource-Policy is opt-in. - [Customizing the CSP | HELMET docs](https://helmet.apps.wayne.edu/docs/guides/csp.md): A csp policy passed to helmet_boot() or the middleware is merged over the default, per directive. - [The request-forgery guard | HELMET docs](https://helmet.apps.wayne.edu/docs/guides/csrf.md): SameSite=Lax is a layer, not a wall: the optional request-forgery guard checks state-changing requests before they reach the app. - [The headers | HELMET docs](https://helmet.apps.wayne.edu/docs/guides/headers.md): Every response gets the same set of security headers, built by one shared function. - [Configuring HSTS | HELMET docs](https://helmet.apps.wayne.edu/docs/guides/hsts.md): The default HSTS is max-age=31536000 with includeSubDomains, sent on HTTPS responses only, and it rolls out in stages. - [HTTPS, and why the proxy list matters | HELMET docs](https://helmet.apps.wayne.edu/docs/guides/https-and-proxies.md): HELMET honors X-Forwarded-Proto only when the connection came from a trusted proxy, so a spoofed header is ignored and no HSTS goes out for a request that was not really secure. - [Strongly recommended: a git.wayne.edu instance runner | HELMET docs](https://helmet.apps.wayne.edu/docs/guides/instance-runner.md): git.wayne.edu has no runners today, so CI for this repo runs on the test GitLab instance, and every product in the stack strongly recommends a git.wayne.edu instance runner. - [Metrics | HELMET docs](https://helmet.apps.wayne.edu/docs/guides/metrics.md): HELMET can expose a Prometheus metrics endpoint, off by default and gated by a bearer token or an IP allow list. - [Platform presets | HELMET docs](https://helmet.apps.wayne.edu/docs/guides/platform-presets.md): A preset names a platform's trusted-proxy list, so an app does not hard-code an address that belongs to the platform, not the app. - [Quick start | HELMET docs](https://helmet.apps.wayne.edu/docs/guides/quick-start.md): A raw PHP app behind the HELMET baseline in four steps: require, boot, verify, nonce. - [Running off Citadel | HELMET docs](https://helmet.apps.wayne.edu/docs/guides/running-off-citadel.md): HELMET ships one package for every platform, so running off Citadel means changing configuration, not code. - [The session | HELMET docs](https://helmet.apps.wayne.edu/docs/guides/session.md): SessionHardening::apply() sets the session ini values, including a __Host- prefixed cookie name on HTTPS, before the session starts. - [Laravel | HELMET docs](https://helmet.apps.wayne.edu/docs/guides/usage-laravel.md): The Laravel adapter is a service provider, two always-on middlewares, an optional request-forgery guard, and a config file. - [PSR-15 middleware | HELMET docs](https://helmet.apps.wayne.edu/docs/guides/usage-psr15.md): The same core, mounted in a middleware pipeline, sends the identical headers. - [Raw PHP | HELMET docs](https://helmet.apps.wayne.edu/docs/guides/usage-raw-php.md): An app on raw PHP calls helmet_boot() once at the top of its front controller, before anything is echoed, and is done. - [WSU values (Playbook) | HELMET docs](https://helmet.apps.wayne.edu/docs/guides/wsu-values.md): The Laravel config reads HELMET_PRESET from the environment first and from the private waynestate/playbook package (Playbook) second, when the environment has no value. - [Overview | HELMET docs](https://helmet.apps.wayne.edu/docs/index.md): HELMET is the Wayne State app stack's baseline runtime: security headers, a hardened session, an honest proxy check, /up and structured logs. - [Install | HELMET docs](https://helmet.apps.wayne.edu/docs/install.md): Add waynestate/helmet with Composer, then verify the headers are on the wire. - [API | HELMET docs](https://helmet.apps.wayne.edu/docs/reference/api.md): The public entry points of the core, from helmet_boot() to helmet_metrics(), plus the middleware and guard around them. - [Environment variables | HELMET docs](https://helmet.apps.wayne.edu/docs/reference/configuration.md): Every HELMET_ environment variable the package reads, its meaning, its default, and the file that reads it. - [Proof | HELMET docs](https://helmet.apps.wayne.edu/docs/reference/proof.md): Proof runs against real Wayne State applications are on a private site, proof.apps.wayne.edu/helmet, behind a Wayne State employee sign-in. - [Troubleshooting | HELMET docs](https://helmet.apps.wayne.edu/docs/troubleshooting.md): What to look at when a header is missing, a proxy is not trusted, or the guard refuses a request that should pass. - [Upgrading | HELMET docs](https://helmet.apps.wayne.edu/docs/upgrading.md): How to move an app from one HELMET release to the next. ## Prompts - [Get started with HELMET](https://helmet.apps.wayne.edu/#prompt-get-started): The agent works out your app's shape and where it runs, then writes the smallest plan to add HELMET. It changes nothing yet. The prompt itself is in https://helmet.apps.wayne.edu/index.md. - [HELMET in a raw PHP app](https://helmet.apps.wayne.edu/#prompt-raw-php): Adds helmet_boot() to the front controller and the nonce to each inline script. If some pages skip the front controller, it adds public/up.php too. The prompt itself is in https://helmet.apps.wayne.edu/index.md. - [HELMET in a Laravel app with Blade](https://helmet.apps.wayne.edu/#prompt-laravel-blade): Publishes the config, sets the platform and puts the nonce on inline scripts in Blade. Laravel keeps its own /up and its own session settings. The prompt itself is in https://helmet.apps.wayne.edu/index.md. - [HELMET in a Laravel app with Inertia and Vue](https://helmet.apps.wayne.edu/#prompt-laravel-inertia): The Laravel setup, then a search for what the CSP will break: scripts in Inertia's Head, a second package that makes nonces, and HTML cached across requests. The prompt itself is in https://helmet.apps.wayne.edu/index.md. - [HELMET in a PSR-15 middleware pipeline](https://helmet.apps.wayne.edu/#prompt-psr15): Adds HealthCheck and SecurityHeadersMiddleware to your pipeline. Your handlers read the nonce from the helmet.csp_nonce attribute. The prompt itself is in https://helmet.apps.wayne.edu/index.md. ## Source - [README](https://nougat.snu.gs/enterprise-apps/helmet/blob/HEAD/README.md): the project's README, with install, commands and checks - [Everything in one file](https://helmet.apps.wayne.edu/llms-full.txt): the README and every page above, as one Markdown file ## Optional - [ADVISOR](https://advisor.apps.wayne.edu/llms.txt): the stack's MCP server: read-only tools that answer from CREED's policy and the parts' docs instead of from memory - [WELD](https://weld.apps.wayne.edu/llms.txt): the Wayne State application stack: every part, and the reference app