Skip to content

Fixing The First Run

Fabrizio Salmi edited this page Sep 6, 2026 · 1 revision

Fixing the first run

Point it at an existing site and it will be non-conformant. That is expected: the standard describes a property almost nobody has by accident.

The queue is severity-ranked, which is the right order to fix in. What follows is what those first items usually are.

The CRITICAL ones, which are usually the same two

AG-NET-01 Self-host every runtime dependency. A font from a CDN, a script from a package host, an icon set from somewhere else. Each of them is a third party that sees every visitor's IP and could change what it serves.

The fix is mechanical and boring: download the asset, serve it from your own origin, update the reference. It is also the single highest-value change in the whole standard, because it removes the exfiltration path rather than constraining it.

AG-NET-04 Constrain connect-src. Without a CSP, fetch directives fall back to the browser's wildcard-open defaults, which is why a missing CSP shows up as a CRITICAL egress finding and not only as a CSP one.

Then the CSP family

AG-CSP-01 Ship a CSP. Once assets are self-hosted this becomes easy, because there is nothing external left to allow.

AG-CSP-02 Deny by default, enumerate, forbid bypass primitives. default-src 'none', then enumerate what you actually need. No unsafe-inline, no unsafe-eval, no wildcards.

AG-CSP-03 Clickjacking control must be header-delivered. A <meta> tag does not count: frame-ancestors has to arrive as a header, which means configuring the host rather than the HTML.

AG-CSP-04 Stage report-only before enforcing is a SHOULD, and it is the one worth honouring rather than waiving. A CSP that breaks the site teaches everyone that CSPs break sites.

Headers and links

AG-HDR is nine rules and mostly host configuration rather than code: HSTS, content-type options, referrer policy, permissions policy. On a static host these are often one config block.

AG-NET-09, external _blank links severing the opener and privacy surfaces severing the referrer, is a Bronze MUST and is one attribute per link. Cheap, and easy to regress every time someone adds a link.

The ones that need your environment, not your site

AG-SUP and parts of AG-CI need scanners on PATH. If they come back INCONCLUSIVE, that is not a finding about your surface: install gitleaks and osv-scanner and rerun before treating them as work.

Same for the dynamic plane: without a headless browser the runtime egress proofs cannot run.

An order that works

  1. Self-host every asset. Removes the CRITICAL, and makes the CSP writable
  2. Write the CSP, report-only first, then enforce
  3. Set the headers at the host
  4. Fix the link attributes
  5. Install the scanners and rerun, so the Could not assess list empties
  6. Only then consider raising the profile or tightening the level

Steps 1 and 2 usually take a non-conformant Bronze surface to conformant on their own.

Keeping it green

Gate every push. The Action runs from a prebuilt image, so there is no per-run rebuild:

- uses: fabriziosalmi/agssh@v1     # pin to a SHA in production
  with: { config: .airgap.yml }

The README says to pin to a SHA in production, which is the same supply-chain argument the tool makes about your own site. A moving tag on the thing that verifies your supply chain would be an odd exception.