@growth-labs/conformance 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,51 @@
1
1
  # @growth-labs/conformance Changelog
2
2
 
3
+ ## 0.3.0 — 2026-07-17
4
+
5
+ - Add `buildAstroCspConfig()` for Astro 7.1+ native SHA-256 CSP generation with
6
+ exact external-origin validation and no wildcard or `unsafe-*` escape hatch.
7
+ Its return shape is compile-checked against Astro's exported CSP config type,
8
+ and a real Astro build proves the attribute-only directive is emitted.
9
+ - Allow Astro 7.1+ consumers with a proven inline-style-attribute inventory to
10
+ scope `'unsafe-inline'` to `style-src-attr` only. Script and style-element
11
+ execution remain hash-protected and fail closed. The runner requires the
12
+ inventory receipt to match the exact build commit. The policy API requires
13
+ that structured receipt rather than a boolean escape hatch, including a
14
+ versioned scanner identity and SHA-256 output hash.
15
+ - Require canonical lowercase commit SHAs, SHA-256 evidence hashes, and CSP
16
+ hash algorithm tokens in security evidence.
17
+ - Let consumers set `contentSecurityPolicy: false` on
18
+ `buildSharedPublicationHeaders()` when Astro owns the per-response hash CSP;
19
+ all other shared response headers remain package-owned.
20
+ - Add an explicit per-fixture frame policy contract. The default remains
21
+ `frame-ancestors 'none'` plus `X-Frame-Options: DENY`; deliberately embeddable
22
+ routes may declare only `'self'`, `https:`, or exact HTTPS origins and must
23
+ omit a conflicting legacy frame header. The runner validates the CSP sources
24
+ exactly rather than accepting a fleet-wide relaxation.
25
+
26
+ ## 0.2.0 — 2026-07-16
27
+
28
+ ### Added
29
+
30
+ - Added schema v2 security receipts for consumer-supplied enforced-CSP
31
+ functional probes and CSP reporting/canary evidence.
32
+ - Added required COOP/CORP response headers, conservative shared policy
33
+ defaults, and documented consumer overrides for verified auth/media/embed
34
+ constraints.
35
+ - Added required negative fixtures for missing COOP/CORP, HSTS below one year,
36
+ wildcard `default-src`, `unsafe-eval`, executable inline scripts without a
37
+ matching nonce or SHA-256 hash, conflicting duplicate security headers,
38
+ missing functional-probe receipts, and missing/failed CSP-report receipts.
39
+
40
+ ### Changed
41
+
42
+ - HSTS validation now requires `max-age >= 31536000`.
43
+ - `buildSharedPublicationHeaders()` now keeps `includeSubDomains` and `preload`
44
+ opt-in behind explicit host-inventory proof instead of emitting them by
45
+ default.
46
+ - CSP validation now parses directives instead of substring-matching the raw
47
+ header.
48
+
3
49
  ## 0.1.0 — 2026-07-15
4
50
 
5
51
  ### Added
package/README.md CHANGED
@@ -30,7 +30,9 @@ const fixture = {
30
30
  status: 200,
31
31
  headers: {
32
32
  'content-security-policy': "default-src 'self'; script-src 'self' 'nonce-runtime'",
33
- 'strict-transport-security': 'max-age=31536000; includeSubDomains; preload',
33
+ 'strict-transport-security': 'max-age=31536000',
34
+ 'cross-origin-opener-policy': 'same-origin',
35
+ 'cross-origin-resource-policy': 'same-origin',
34
36
  'x-frame-options': 'DENY',
35
37
  'x-content-type-options': 'nosniff',
36
38
  'referrer-policy': 'strict-origin-when-cross-origin',
@@ -43,6 +45,10 @@ const fixture = {
43
45
  canonicalUrl: 'https://fronts.co/example',
44
46
  schemaTypes: ['NewsArticle'],
45
47
  discoverEligible: true,
48
+ framePolicy: {
49
+ ancestors: ["'none'"],
50
+ legacyHeader: 'DENY',
51
+ },
46
52
  },
47
53
  publicationSurfaces: [
48
54
  { name: 'sitemap', status: 'present', httpStatus: 200, bodyBytes: 1024 },
@@ -53,9 +59,35 @@ const fixture = {
53
59
  { audience: 'public', cacheKey: 'fronts:public:/example' },
54
60
  { audience: 'crawler', cacheKey: 'fronts:crawler:/example' },
55
61
  ],
62
+ securityReceipts: {
63
+ functionalProbes: [
64
+ { name: 'oauth', status: 'pass', evidence: 'sanitized consumer probe receipt' },
65
+ { name: 'media', status: 'pass', evidence: 'sanitized consumer probe receipt' },
66
+ { name: 'images', status: 'pass', evidence: 'sanitized consumer probe receipt' },
67
+ { name: 'analytics', status: 'pass', evidence: 'sanitized consumer probe receipt' },
68
+ { name: 'embeds', status: 'pass', evidence: 'sanitized consumer probe receipt' },
69
+ { name: 'error-pages', status: 'pass', evidence: 'sanitized consumer probe receipt' },
70
+ ],
71
+ cspReports: [
72
+ {
73
+ name: 'csp-report-canary',
74
+ status: 'pass',
75
+ endpoint: 'consumer-owned-report-endpoint',
76
+ evidence: 'sanitized CSP report or blocked-canary receipt',
77
+ },
78
+ ],
79
+ inlineStyleAttributes: {
80
+ commitSha: 'bd39d718f6a5b0df9a249e11638a8b430050941e',
81
+ occurrenceCount: 4,
82
+ evidence: {
83
+ tool: 'platform-foundations:inline-style-inventory@1',
84
+ outputHash: 'sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
85
+ },
86
+ },
87
+ },
56
88
  buildEvidence: {
57
89
  commitSha: 'bd39d718f6a5b0df9a249e11638a8b430050941e',
58
- packageVersions: { '@growth-labs/seo': '0.9.0' },
90
+ packageVersions: { '@growth-labs/conformance': '0.3.0', '@growth-labs/seo': '0.9.0' },
59
91
  staticHeaderPolicy: true,
60
92
  ssrHeaderPolicy: true,
61
93
  },
@@ -68,25 +100,81 @@ const fleetBundle = runFleetConformance([fixture])
68
100
  ## Shared Header Policy
69
101
 
70
102
  Use `buildSharedPublicationHeaders()` when a site wants the package-owned
71
- baseline for SSR and static response headers:
103
+ baseline for SSR and static response headers. Astro 7.1+ sites should let Astro
104
+ own the per-route hash CSP and retain the remaining shared headers. The helper's
105
+ peer contract is intentionally pinned to the first Astro release that supports
106
+ attribute-scoped style resources:
72
107
 
73
108
  ```ts
74
- import { buildSharedPublicationHeaders } from '@growth-labs/conformance/policy'
109
+ import {
110
+ buildAstroCspConfig,
111
+ buildSharedPublicationHeaders,
112
+ } from '@growth-labs/conformance/policy'
113
+
114
+ const csp = buildAstroCspConfig({
115
+ scriptSources: ['https://challenges.cloudflare.com'],
116
+ styleSources: ['https://fonts.googleapis.com'],
117
+ inlineStyleAttributes: {
118
+ commitSha: 'bd39d718f6a5b0df9a249e11638a8b430050941e',
119
+ occurrenceCount: 4,
120
+ evidence: {
121
+ tool: 'platform-foundations:inline-style-inventory@1',
122
+ outputHash: 'sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
123
+ },
124
+ },
125
+ })
75
126
 
76
127
  const headers = buildSharedPublicationHeaders({
77
128
  renderMode: 'ssr',
78
129
  audience: 'public',
79
- nonce: runtimeNonce,
130
+ contentSecurityPolicy: false,
80
131
  markdownTwinUrl: 'https://example.com/article.md',
81
132
  })
82
133
  ```
83
134
 
135
+ The fixture default is the non-embeddable policy above. For a deliberately
136
+ embeddable route, declare its exact response class and omit a conflicting
137
+ `X-Frame-Options` header:
138
+
139
+ ```ts
140
+ expected: {
141
+ framePolicy: {
142
+ ancestors: ['https://trusted.example'],
143
+ legacyHeader: 'omit',
144
+ },
145
+ }
146
+ ```
147
+
148
+ Accepted ancestors are `'none'`, `'self'`, `https:`, and exact HTTPS origins;
149
+ wildcards, paths, credentials, query strings, and fragments are rejected.
150
+ `DENY` is valid only with `'none'`, and `SAMEORIGIN` only with `'self'`; broader
151
+ embeddable policies must use `legacyHeader: 'omit'` to avoid contradictory
152
+ browser behavior.
153
+
154
+ Astro 7.1+ consumers that prove they still emit HTML `style` attributes may set
155
+ `inlineStyleAttributes` to the validated inventory receipt. There is no boolean
156
+ escape hatch. The helper then scopes `'unsafe-inline'` to `style-src-attr`
157
+ while preserving hash protection for scripts and `<style>` elements. The
158
+ receipt requires the exact lowercase 40-character build commit SHA, a positive
159
+ occurrence count, the versioned scanner identity, and the lowercase SHA-256
160
+ content hash of its machine output. The same receipt must appear in the
161
+ conformance fixture and its commit must match `buildEvidence.commitSha`. Do not
162
+ enable this option as a generic compatibility fix.
163
+
84
164
  The policy emits CSP, HSTS, frame protection, MIME sniffing protection,
85
- referrer policy, permissions policy, cache semantics, and optional markdown
86
- twin `Link` metadata. Private audiences use `private, no-store`; public SSR
87
- uses short shared-cache semantics; public static surfaces get longer
165
+ COOP, CORP, referrer policy, permissions policy, cache semantics, and optional
166
+ markdown twin `Link` metadata. Private audiences use `private, no-store`;
167
+ public SSR uses short shared-cache semantics; public static surfaces get longer
88
168
  shared-cache semantics.
89
169
 
170
+ HSTS defaults to `max-age=31536000` only. Add `includeSubDomains` and `preload`
171
+ through `strictTransportSecurity: { includeSubDomains: true, preload: true }`
172
+ only after the consumer has separately verified the full host inventory can
173
+ enforce HTTPS. COOP defaults to `same-origin` and CORP defaults to
174
+ `same-origin`; consumers may override them only when verified OAuth popup,
175
+ media, or embed constraints require a looser policy and the receipt proves the
176
+ result under enforced CSP.
177
+
90
178
  ## Fixture Commands
91
179
 
92
180
  The root repo exposes:
@@ -100,6 +188,16 @@ The fixture command proves the required negative fixtures fail loudly with
100
188
  stable finding codes:
101
189
 
102
190
  - `csp-unsafe-inline`
191
+ - `missing-coop`
192
+ - `missing-corp`
193
+ - `hsts-below-one-year`
194
+ - `csp-wildcard-default-src`
195
+ - `csp-unsafe-eval`
196
+ - `csp-inline-executable-without-nonce-or-hash`
197
+ - `conflicting-duplicate-security-header`
198
+ - `missing-functional-probe-receipt`
199
+ - `missing-csp-report-receipt`
200
+ - `failed-csp-report-receipt`
103
201
  - `headers-static-only-while-ssr-missing`
104
202
  - `undeclared-na`
105
203
  - `stringified-is-accessible-for-free`
@@ -114,5 +212,11 @@ stable finding codes:
114
212
 
115
213
  `runSiteConformance()` returns a `SiteEvidenceBundle`; `runFleetConformance()`
116
214
  returns a `FleetEvidenceBundle`. Both are validated by exported Zod schemas
117
- and carry `schemaVersion: "growth-labs.conformance.v1"` so downstream jobs can
215
+ and carry `schemaVersion: "growth-labs.conformance.v2"` so downstream jobs can
118
216
  parse them without relying on console text.
217
+
218
+ Schema v2 adds `securityReceipts` to fixtures and site evidence bundles. Existing
219
+ v1 fixtures must add explicit functional-probe receipts for `oauth`, `media`,
220
+ `images`, `analytics`, `embeds`, and `error-pages`, plus at least one passing CSP
221
+ reporting/canary receipt. The package does not perform those live probes itself;
222
+ consumer CI supplies sanitized pass/fail/NA receipts.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { buildCacheControl, buildContentSecurityPolicy, buildSharedPublicationHeaders, type CachePolicyOptions, type HeaderPolicyOptions, isPrivateAudience, normalizeHeaders, REQUIRED_SECURITY_HEADERS, } from './policy.js';
1
+ export { type AstroCspConfig, type AstroCspPolicyOptions, type AstroCspResource, buildAstroCspConfig, buildCacheControl, buildContentSecurityPolicy, buildSharedPublicationHeaders, buildStrictTransportSecurity, type CachePolicyOptions, type ContentSecurityPolicyOptions, type CrossOriginOpenerPolicy, type CrossOriginResourcePolicy, collectHeaders, type HeaderPolicyOptions, isPrivateAudience, normalizeHeaders, REQUIRED_SECURITY_HEADERS, type StrictTransportSecurityOptions, } from './policy.js';
2
2
  export { type RunConformanceOptions, runFleetConformance, runSiteConformance } from './runner.js';
3
- export { type Audience, audienceSchema, type BuildEvidence, buildEvidenceSchema, type CacheVariant, type ConformanceCheckReceipt, type ConformanceFinding, type ConformanceFixture, type ConformanceFixtureInput, cacheVariantSchema, checkStatusSchema, conformanceCheckReceiptSchema, conformanceExpectedSchema, conformanceFindingSchema, conformanceFixtureSchema, EVIDENCE_SCHEMA_VERSION, type EvidenceSummary, evidenceSummarySchema, type FleetEvidenceBundle, findingSeveritySchema, fleetEvidenceBundleSchema, type HeaderMap, headerMapSchema, headerValueSchema, type PublicationSurfaceEvidence, parseConformanceFixture, publicationSurfaceSchema, REQUIRED_NEGATIVE_FIXTURE_CODES, type RenderMode, type RequiredNegativeFindingCode, type RequiredNegativeFixtureId, renderModeSchema, type SiteEvidenceBundle, type SurfaceResponse, siteEvidenceBundleSchema, surfaceResponseSchema, validateFleetEvidenceBundle, validateSiteEvidenceBundle, } from './schema.js';
3
+ export { type Audience, audienceSchema, type BuildEvidence, buildEvidenceSchema, type CacheVariant, type ConformanceCheckReceipt, type ConformanceFinding, type ConformanceFixture, type ConformanceFixtureInput, type CspReportReceipt, cacheVariantSchema, checkStatusSchema, conformanceCheckReceiptSchema, conformanceExpectedSchema, conformanceFindingSchema, conformanceFixtureSchema, cspReportReceiptSchema, EVIDENCE_SCHEMA_VERSION, type EvidenceSummary, evidenceSummarySchema, type FleetEvidenceBundle, findingSeveritySchema, fleetEvidenceBundleSchema, type HeaderMap, headerMapSchema, headerValueSchema, type InlineStyleAttributeInventory, inlineStyleAttributeInventorySchema, type PublicationSurfaceEvidence, parseConformanceFixture, publicationSurfaceSchema, REQUIRED_FUNCTIONAL_PROBE_NAMES, REQUIRED_NEGATIVE_FIXTURE_CODES, type RenderMode, type RequiredNegativeFindingCode, type RequiredNegativeFixtureId, renderModeSchema, type SecurityFunctionalProbeReceipt, type SecurityReceipts, type SiteEvidenceBundle, type SurfaceResponse, securityFunctionalProbeReceiptSchema, securityReceiptsSchema, siteEvidenceBundleSchema, surfaceResponseSchema, validateFleetEvidenceBundle, validateSiteEvidenceBundle, } from './schema.js';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,iBAAiB,EACjB,0BAA0B,EAC1B,6BAA6B,EAC7B,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,iBAAiB,EACjB,gBAAgB,EAChB,yBAAyB,GACzB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,KAAK,qBAAqB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AACjG,OAAO,EACN,KAAK,QAAQ,EACb,cAAc,EACd,KAAK,aAAa,EAClB,mBAAmB,EACnB,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,kBAAkB,EAClB,iBAAiB,EACjB,6BAA6B,EAC7B,yBAAyB,EACzB,wBAAwB,EACxB,wBAAwB,EACxB,uBAAuB,EACvB,KAAK,eAAe,EACpB,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,qBAAqB,EACrB,yBAAyB,EACzB,KAAK,SAAS,EACd,eAAe,EACf,iBAAiB,EACjB,KAAK,0BAA0B,EAC/B,uBAAuB,EACvB,wBAAwB,EACxB,+BAA+B,EAC/B,KAAK,UAAU,EACf,KAAK,2BAA2B,EAChC,KAAK,yBAAyB,EAC9B,gBAAgB,EAChB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,2BAA2B,EAC3B,0BAA0B,GAC1B,MAAM,aAAa,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,mBAAmB,EACnB,iBAAiB,EACjB,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,EAC5B,KAAK,kBAAkB,EACvB,KAAK,4BAA4B,EACjC,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,cAAc,EACd,KAAK,mBAAmB,EACxB,iBAAiB,EACjB,gBAAgB,EAChB,yBAAyB,EACzB,KAAK,8BAA8B,GACnC,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,KAAK,qBAAqB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AACjG,OAAO,EACN,KAAK,QAAQ,EACb,cAAc,EACd,KAAK,aAAa,EAClB,mBAAmB,EACnB,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,6BAA6B,EAC7B,yBAAyB,EACzB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,EACvB,KAAK,eAAe,EACpB,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,qBAAqB,EACrB,yBAAyB,EACzB,KAAK,SAAS,EACd,eAAe,EACf,iBAAiB,EACjB,KAAK,6BAA6B,EAClC,mCAAmC,EACnC,KAAK,0BAA0B,EAC/B,uBAAuB,EACvB,wBAAwB,EACxB,+BAA+B,EAC/B,+BAA+B,EAC/B,KAAK,UAAU,EACf,KAAK,2BAA2B,EAChC,KAAK,yBAAyB,EAC9B,gBAAgB,EAChB,KAAK,8BAA8B,EACnC,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,oCAAoC,EACpC,sBAAsB,EACtB,wBAAwB,EACxB,qBAAqB,EACrB,2BAA2B,EAC3B,0BAA0B,GAC1B,MAAM,aAAa,CAAA"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { buildCacheControl, buildContentSecurityPolicy, buildSharedPublicationHeaders, isPrivateAudience, normalizeHeaders, REQUIRED_SECURITY_HEADERS, } from './policy.js';
1
+ export { buildAstroCspConfig, buildCacheControl, buildContentSecurityPolicy, buildSharedPublicationHeaders, buildStrictTransportSecurity, collectHeaders, isPrivateAudience, normalizeHeaders, REQUIRED_SECURITY_HEADERS, } from './policy.js';
2
2
  export { runFleetConformance, runSiteConformance } from './runner.js';
3
- export { audienceSchema, buildEvidenceSchema, cacheVariantSchema, checkStatusSchema, conformanceCheckReceiptSchema, conformanceExpectedSchema, conformanceFindingSchema, conformanceFixtureSchema, EVIDENCE_SCHEMA_VERSION, evidenceSummarySchema, findingSeveritySchema, fleetEvidenceBundleSchema, headerMapSchema, headerValueSchema, parseConformanceFixture, publicationSurfaceSchema, REQUIRED_NEGATIVE_FIXTURE_CODES, renderModeSchema, siteEvidenceBundleSchema, surfaceResponseSchema, validateFleetEvidenceBundle, validateSiteEvidenceBundle, } from './schema.js';
3
+ export { audienceSchema, buildEvidenceSchema, cacheVariantSchema, checkStatusSchema, conformanceCheckReceiptSchema, conformanceExpectedSchema, conformanceFindingSchema, conformanceFixtureSchema, cspReportReceiptSchema, EVIDENCE_SCHEMA_VERSION, evidenceSummarySchema, findingSeveritySchema, fleetEvidenceBundleSchema, headerMapSchema, headerValueSchema, inlineStyleAttributeInventorySchema, parseConformanceFixture, publicationSurfaceSchema, REQUIRED_FUNCTIONAL_PROBE_NAMES, REQUIRED_NEGATIVE_FIXTURE_CODES, renderModeSchema, securityFunctionalProbeReceiptSchema, securityReceiptsSchema, siteEvidenceBundleSchema, surfaceResponseSchema, validateFleetEvidenceBundle, validateSiteEvidenceBundle, } from './schema.js';
4
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,iBAAiB,EACjB,0BAA0B,EAC1B,6BAA6B,EAG7B,iBAAiB,EACjB,gBAAgB,EAChB,yBAAyB,GACzB,MAAM,aAAa,CAAA;AACpB,OAAO,EAA8B,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AACjG,OAAO,EAEN,cAAc,EAEd,mBAAmB,EAMnB,kBAAkB,EAClB,iBAAiB,EACjB,6BAA6B,EAC7B,yBAAyB,EACzB,wBAAwB,EACxB,wBAAwB,EACxB,uBAAuB,EAEvB,qBAAqB,EAErB,qBAAqB,EACrB,yBAAyB,EAEzB,eAAe,EACf,iBAAiB,EAEjB,uBAAuB,EACvB,wBAAwB,EACxB,+BAA+B,EAI/B,gBAAgB,EAGhB,wBAAwB,EACxB,qBAAqB,EACrB,2BAA2B,EAC3B,0BAA0B,GAC1B,MAAM,aAAa,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,mBAAmB,EACnB,iBAAiB,EACjB,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,EAK5B,cAAc,EAEd,iBAAiB,EACjB,gBAAgB,EAChB,yBAAyB,GAEzB,MAAM,aAAa,CAAA;AACpB,OAAO,EAA8B,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AACjG,OAAO,EAEN,cAAc,EAEd,mBAAmB,EAOnB,kBAAkB,EAClB,iBAAiB,EACjB,6BAA6B,EAC7B,yBAAyB,EACzB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,EAEvB,qBAAqB,EAErB,qBAAqB,EACrB,yBAAyB,EAEzB,eAAe,EACf,iBAAiB,EAEjB,mCAAmC,EAEnC,uBAAuB,EACvB,wBAAwB,EACxB,+BAA+B,EAC/B,+BAA+B,EAI/B,gBAAgB,EAKhB,oCAAoC,EACpC,sBAAsB,EACtB,wBAAwB,EACxB,qBAAqB,EACrB,2BAA2B,EAC3B,0BAA0B,GAC1B,MAAM,aAAa,CAAA"}
package/dist/policy.d.ts CHANGED
@@ -1,18 +1,69 @@
1
- import type { Audience, HeaderMap, RenderMode } from './schema.js';
2
- export declare const REQUIRED_SECURITY_HEADERS: readonly ["content-security-policy", "strict-transport-security", "x-frame-options", "x-content-type-options", "referrer-policy", "permissions-policy"];
1
+ import type { AstroConfig } from 'astro';
2
+ import { type Audience, type HeaderMap, type InlineStyleAttributeInventory, type RenderMode } from './schema.js';
3
+ export declare const REQUIRED_SECURITY_HEADERS: readonly ["content-security-policy", "strict-transport-security", "cross-origin-opener-policy", "cross-origin-resource-policy", "x-frame-options", "x-content-type-options", "referrer-policy", "permissions-policy"];
4
+ export type CrossOriginOpenerPolicy = 'same-origin' | 'same-origin-allow-popups' | 'unsafe-none';
5
+ export type CrossOriginResourcePolicy = 'same-origin' | 'same-site' | 'cross-origin';
6
+ export interface StrictTransportSecurityOptions {
7
+ maxAgeSeconds?: number;
8
+ includeSubDomains?: boolean;
9
+ preload?: boolean;
10
+ }
11
+ export interface ContentSecurityPolicyOptions {
12
+ nonce?: string;
13
+ reportUri?: string;
14
+ reportTo?: string;
15
+ }
3
16
  export interface HeaderPolicyOptions {
4
17
  renderMode: RenderMode;
5
18
  audience: Audience;
6
19
  nonce?: string;
20
+ cspReportUri?: string;
21
+ cspReportTo?: string;
22
+ contentSecurityPolicy?: false | ContentSecurityPolicyOptions;
23
+ strictTransportSecurity?: StrictTransportSecurityOptions;
24
+ crossOriginOpenerPolicy?: CrossOriginOpenerPolicy;
25
+ crossOriginResourcePolicy?: CrossOriginResourcePolicy;
7
26
  markdownTwinUrl?: string;
8
27
  }
28
+ export interface AstroCspPolicyOptions {
29
+ scriptSources?: readonly string[];
30
+ styleSources?: readonly string[];
31
+ inlineStyleAttributes?: InlineStyleAttributeInventory;
32
+ imgSources?: readonly string[];
33
+ fontSources?: readonly string[];
34
+ connectSources?: readonly string[];
35
+ mediaSources?: readonly string[];
36
+ frameSources?: readonly string[];
37
+ }
38
+ type AstroNativeCspConfig = Exclude<NonNullable<NonNullable<AstroConfig['security']>['csp']>, boolean>;
39
+ type AstroCspDirective = NonNullable<AstroNativeCspConfig['directives']>[number];
40
+ export type AstroCspResource = NonNullable<NonNullable<AstroNativeCspConfig['styleDirective']>['resources']>[number];
41
+ export interface AstroCspConfig {
42
+ algorithm: 'SHA-256';
43
+ directives: AstroCspDirective[];
44
+ scriptDirective: {
45
+ resources: string[];
46
+ };
47
+ styleDirective: {
48
+ resources: AstroCspResource[];
49
+ };
50
+ }
9
51
  export interface CachePolicyOptions {
10
52
  renderMode: RenderMode;
11
53
  audience: Audience;
12
54
  }
13
55
  export declare function buildSharedPublicationHeaders(options: HeaderPolicyOptions): Record<string, string>;
14
- export declare function buildContentSecurityPolicy(nonce?: string): string;
56
+ /**
57
+ * Build framework-owned CSP configuration for Astro 7.1+.
58
+ * Astro hashes every script and style it emits, while this helper keeps the
59
+ * consumer's external source inventory exact and fail-closed.
60
+ */
61
+ export declare function buildAstroCspConfig(options?: AstroCspPolicyOptions): AstroCspConfig;
62
+ export declare function buildContentSecurityPolicy(input?: string | ContentSecurityPolicyOptions): string;
63
+ export declare function buildStrictTransportSecurity(options?: StrictTransportSecurityOptions): string;
15
64
  export declare function buildCacheControl({ renderMode, audience }: CachePolicyOptions): string;
16
65
  export declare function normalizeHeaders(headers: HeaderMap | undefined): Record<string, string>;
66
+ export declare function collectHeaders(headers: HeaderMap | undefined): Record<string, string[]>;
17
67
  export declare function isPrivateAudience(audience: Audience): boolean;
68
+ export {};
18
69
  //# sourceMappingURL=policy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAElE,eAAO,MAAM,yBAAyB,yJAO5B,CAAA;AAEV,MAAM,WAAW,mBAAmB;IACnC,UAAU,EAAE,UAAU,CAAA;IACtB,QAAQ,EAAE,QAAQ,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,eAAe,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,kBAAkB;IAClC,UAAU,EAAE,UAAU,CAAA;IACtB,QAAQ,EAAE,QAAQ,CAAA;CAClB;AAED,wBAAgB,6BAA6B,CAC5C,OAAO,EAAE,mBAAmB,GAC1B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiBxB;AAED,wBAAgB,0BAA0B,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAoBjE;AAED,wBAAgB,iBAAiB,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,kBAAkB,GAAG,MAAM,CAMtF;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAavF;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAO7D"}
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"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"}
package/dist/policy.js CHANGED
@@ -1,6 +1,9 @@
1
+ import { inlineStyleAttributeInventorySchema, } from './schema.js';
1
2
  export const REQUIRED_SECURITY_HEADERS = [
2
3
  'content-security-policy',
3
4
  'strict-transport-security',
5
+ 'cross-origin-opener-policy',
6
+ 'cross-origin-resource-policy',
4
7
  'x-frame-options',
5
8
  'x-content-type-options',
6
9
  'referrer-policy',
@@ -8,27 +11,119 @@ export const REQUIRED_SECURITY_HEADERS = [
8
11
  ];
9
12
  export function buildSharedPublicationHeaders(options) {
10
13
  const headers = {
11
- 'Content-Security-Policy': buildContentSecurityPolicy(options.nonce),
12
- 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload',
14
+ 'Strict-Transport-Security': buildStrictTransportSecurity(options.strictTransportSecurity),
15
+ 'Cross-Origin-Opener-Policy': options.crossOriginOpenerPolicy ?? 'same-origin',
16
+ 'Cross-Origin-Resource-Policy': options.crossOriginResourcePolicy ?? 'same-origin',
13
17
  'X-Frame-Options': 'DENY',
14
18
  'X-Content-Type-Options': 'nosniff',
15
19
  'Referrer-Policy': 'strict-origin-when-cross-origin',
16
20
  'Permissions-Policy': 'accelerometer=(), camera=(), geolocation=(), gyroscope=(), microphone=(), payment=(), usb=()',
17
21
  'Cache-Control': buildCacheControl(options),
18
22
  };
23
+ if (options.contentSecurityPolicy !== false) {
24
+ headers['Content-Security-Policy'] = buildContentSecurityPolicy(options.contentSecurityPolicy ?? {
25
+ nonce: options.nonce,
26
+ reportUri: options.cspReportUri,
27
+ reportTo: options.cspReportTo,
28
+ });
29
+ }
19
30
  if (options.markdownTwinUrl) {
20
31
  headers.Link = `<${options.markdownTwinUrl}>; rel="alternate"; type="text/markdown"`;
21
32
  }
22
33
  return headers;
23
34
  }
24
- export function buildContentSecurityPolicy(nonce) {
35
+ /**
36
+ * Build framework-owned CSP configuration for Astro 7.1+.
37
+ * Astro hashes every script and style it emits, while this helper keeps the
38
+ * consumer's external source inventory exact and fail-closed.
39
+ */
40
+ export function buildAstroCspConfig(options = {}) {
41
+ const inlineStyleAttributes = options.inlineStyleAttributes
42
+ ? inlineStyleAttributeInventorySchema.parse(options.inlineStyleAttributes)
43
+ : undefined;
44
+ const scriptSources = exactCspSources(options.scriptSources);
45
+ const styleSources = exactCspSources(options.styleSources);
46
+ const imgSources = exactCspSources(options.imgSources);
47
+ const fontSources = exactCspSources(options.fontSources);
48
+ const connectSources = exactCspSources(options.connectSources);
49
+ const mediaSources = exactCspSources(options.mediaSources);
50
+ const frameSources = exactCspSources(options.frameSources);
51
+ return {
52
+ algorithm: 'SHA-256',
53
+ directives: [
54
+ "default-src 'self'",
55
+ cspDirective('img-src', ["'self'", 'data:', 'blob:', ...imgSources]),
56
+ cspDirective('font-src', ["'self'", 'data:', ...fontSources]),
57
+ cspDirective('connect-src', ["'self'", ...connectSources]),
58
+ cspDirective('media-src', ["'self'", 'blob:', ...mediaSources]),
59
+ cspDirective('frame-src', ["'self'", ...frameSources]),
60
+ "object-src 'none'",
61
+ "base-uri 'self'",
62
+ "frame-ancestors 'none'",
63
+ "form-action 'self'",
64
+ 'upgrade-insecure-requests',
65
+ ],
66
+ scriptDirective: {
67
+ resources: uniqueCspSources(["'self'", ...scriptSources]),
68
+ },
69
+ styleDirective: {
70
+ resources: inlineStyleAttributes
71
+ ? [
72
+ ...uniqueCspSources(["'self'", ...styleSources]).map((resource) => ({
73
+ resource,
74
+ kind: 'element',
75
+ })),
76
+ { resource: "'unsafe-inline'", kind: 'attribute' },
77
+ ]
78
+ : uniqueCspSources(["'self'", ...styleSources]),
79
+ },
80
+ };
81
+ }
82
+ function uniqueCspSources(sources) {
83
+ return [...new Set(sources)];
84
+ }
85
+ function cspDirective(name, sources) {
86
+ return `${name} ${[...new Set(sources)].join(' ')}`;
87
+ }
88
+ function exactCspSources(sources) {
89
+ return [...new Set(sources ?? [])].map((source) => {
90
+ const normalized = source.trim();
91
+ if (normalized === "'self'")
92
+ return normalized;
93
+ if (normalized === '' ||
94
+ normalized.includes('*') ||
95
+ normalized === 'https:' ||
96
+ normalized === 'http:' ||
97
+ normalized.startsWith("'unsafe-")) {
98
+ throw new Error(`Astro CSP sources must be exact and cannot use ${source}`);
99
+ }
100
+ let parsed;
101
+ try {
102
+ parsed = new URL(normalized);
103
+ }
104
+ catch {
105
+ throw new Error(`Astro CSP sources must be exact HTTPS/WSS origins: ${source}`);
106
+ }
107
+ if ((parsed.protocol !== 'https:' && parsed.protocol !== 'wss:') ||
108
+ parsed.username !== '' ||
109
+ parsed.password !== '' ||
110
+ parsed.search !== '' ||
111
+ parsed.hash !== '' ||
112
+ (parsed.pathname !== '' && parsed.pathname !== '/')) {
113
+ throw new Error(`Astro CSP sources must be exact HTTPS/WSS origins: ${source}`);
114
+ }
115
+ return parsed.origin;
116
+ });
117
+ }
118
+ export function buildContentSecurityPolicy(input) {
119
+ const options = typeof input === 'string' ? { nonce: input } : (input ?? {});
25
120
  const scriptSources = ["'self'"];
26
121
  const styleSources = ["'self'"];
27
- if (nonce) {
28
- scriptSources.push(`'nonce-${nonce}'`);
29
- styleSources.push(`'nonce-${nonce}'`);
122
+ if (options.nonce) {
123
+ scriptSources.push(`'nonce-${options.nonce}'`);
124
+ styleSources.push(`'nonce-${options.nonce}'`);
30
125
  }
31
- return [
126
+ const directives = [
32
127
  "default-src 'self'",
33
128
  `script-src ${scriptSources.join(' ')}`,
34
129
  `style-src ${styleSources.join(' ')}`,
@@ -39,7 +134,27 @@ export function buildContentSecurityPolicy(nonce) {
39
134
  "base-uri 'self'",
40
135
  "frame-ancestors 'none'",
41
136
  'upgrade-insecure-requests',
42
- ].join('; ');
137
+ ];
138
+ if (options.reportTo)
139
+ directives.push(`report-to ${options.reportTo}`);
140
+ if (options.reportUri)
141
+ directives.push(`report-uri ${options.reportUri}`);
142
+ return directives.join('; ');
143
+ }
144
+ export function buildStrictTransportSecurity(options = {}) {
145
+ const maxAgeSeconds = options.maxAgeSeconds ?? 31536000;
146
+ if (!Number.isInteger(maxAgeSeconds) || maxAgeSeconds < 31536000) {
147
+ throw new Error('Strict-Transport-Security maxAgeSeconds must be at least 31536000');
148
+ }
149
+ if (options.preload === true && options.includeSubDomains !== true) {
150
+ throw new Error('Strict-Transport-Security preload requires includeSubDomains after host inventory proof');
151
+ }
152
+ const directives = [`max-age=${maxAgeSeconds}`];
153
+ if (options.includeSubDomains === true)
154
+ directives.push('includeSubDomains');
155
+ if (options.preload === true)
156
+ directives.push('preload');
157
+ return directives.join('; ');
43
158
  }
44
159
  export function buildCacheControl({ renderMode, audience }) {
45
160
  if (isPrivateAudience(audience))
@@ -50,15 +165,24 @@ export function buildCacheControl({ renderMode, audience }) {
50
165
  return 'public, max-age=0, s-maxage=300, stale-while-revalidate=86400';
51
166
  }
52
167
  export function normalizeHeaders(headers) {
168
+ const entries = collectHeaders(headers);
169
+ const normalized = {};
170
+ for (const [name, values] of Object.entries(entries)) {
171
+ normalized[name] = values.join(', ');
172
+ }
173
+ return normalized;
174
+ }
175
+ export function collectHeaders(headers) {
53
176
  const normalized = {};
54
177
  if (!headers)
55
178
  return normalized;
56
179
  for (const [name, value] of Object.entries(headers)) {
180
+ const normalizedName = name.toLowerCase();
57
181
  if (typeof value === 'string') {
58
- normalized[name.toLowerCase()] = value;
182
+ normalized[normalizedName] = [...(normalized[normalizedName] ?? []), value];
59
183
  }
60
184
  else if (Array.isArray(value)) {
61
- normalized[name.toLowerCase()] = value.join(', ');
185
+ normalized[normalizedName] = [...(normalized[normalizedName] ?? []), ...value];
62
186
  }
63
187
  }
64
188
  return normalized;
@@ -1 +1 @@
1
- {"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACxC,yBAAyB;IACzB,2BAA2B;IAC3B,iBAAiB;IACjB,wBAAwB;IACxB,iBAAiB;IACjB,oBAAoB;CACX,CAAA;AAcV,MAAM,UAAU,6BAA6B,CAC5C,OAA4B;IAE5B,MAAM,OAAO,GAA2B;QACvC,yBAAyB,EAAE,0BAA0B,CAAC,OAAO,CAAC,KAAK,CAAC;QACpE,2BAA2B,EAAE,8CAA8C;QAC3E,iBAAiB,EAAE,MAAM;QACzB,wBAAwB,EAAE,SAAS;QACnC,iBAAiB,EAAE,iCAAiC;QACpD,oBAAoB,EACnB,8FAA8F;QAC/F,eAAe,EAAE,iBAAiB,CAAC,OAAO,CAAC;KAC3C,CAAA;IAED,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;QAC7B,OAAO,CAAC,IAAI,GAAG,IAAI,OAAO,CAAC,eAAe,0CAA0C,CAAA;IACrF,CAAC;IAED,OAAO,OAAO,CAAA;AACf,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,KAAc;IACxD,MAAM,aAAa,GAAG,CAAC,QAAQ,CAAC,CAAA;IAChC,MAAM,YAAY,GAAG,CAAC,QAAQ,CAAC,CAAA;IAC/B,IAAI,KAAK,EAAE,CAAC;QACX,aAAa,CAAC,IAAI,CAAC,UAAU,KAAK,GAAG,CAAC,CAAA;QACtC,YAAY,CAAC,IAAI,CAAC,UAAU,KAAK,GAAG,CAAC,CAAA;IACtC,CAAC;IAED,OAAO;QACN,oBAAoB;QACpB,cAAc,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QACvC,aAAa,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QACrC,6BAA6B;QAC7B,uBAAuB;QACvB,2BAA2B;QAC3B,mBAAmB;QACnB,iBAAiB;QACjB,wBAAwB;QACxB,2BAA2B;KAC3B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACb,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAsB;IAC7E,IAAI,iBAAiB,CAAC,QAAQ,CAAC;QAAE,OAAO,mBAAmB,CAAA;IAC3D,IAAI,UAAU,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,oEAAoE,CAAA;IAC5E,CAAC;IACD,OAAO,+DAA+D,CAAA;AACvE,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAA8B;IAC9D,MAAM,UAAU,GAA2B,EAAE,CAAA;IAC7C,IAAI,CAAC,OAAO;QAAE,OAAO,UAAU,CAAA;IAE/B,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACrD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC/B,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,KAAK,CAAA;QACvC,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACjC,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClD,CAAC;IACF,CAAC;IAED,OAAO,UAAU,CAAA;AAClB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,QAAkB;IACnD,OAAO,CACN,QAAQ,KAAK,YAAY;QACzB,QAAQ,KAAK,QAAQ;QACrB,QAAQ,KAAK,OAAO;QACpB,QAAQ,KAAK,SAAS,CACtB,CAAA;AACF,CAAC"}
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAEA,OAAO,EAKN,KAAK,uBAAuB,EAG5B,KAAK,mBAAmB,EAExB,KAAK,kBAAkB,EAEvB,MAAM,aAAa,CAAA;AAKpB,MAAM,WAAW,qBAAqB;IACrC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CAClB;AAED,wBAAgB,kBAAkB,CACjC,KAAK,EAAE,uBAAuB,EAC9B,OAAO,GAAE,qBAA0B,GACjC,kBAAkB,CA6BpB;AAED,wBAAgB,mBAAmB,CAClC,MAAM,EAAE,uBAAuB,EAAE,EACjC,OAAO,GAAE,qBAA0B,GACjC,mBAAmB,CAuBrB"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAOA,OAAO,EAKN,KAAK,uBAAuB,EAG5B,KAAK,mBAAmB,EAGxB,KAAK,kBAAkB,EAEvB,MAAM,aAAa,CAAA;AAuBpB,MAAM,WAAW,qBAAqB;IACrC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CAClB;AAED,wBAAgB,kBAAkB,CACjC,KAAK,EAAE,uBAAuB,EAC9B,OAAO,GAAE,qBAA0B,GACjC,kBAAkB,CA+BpB;AAED,wBAAgB,mBAAmB,CAClC,MAAM,EAAE,uBAAuB,EAAE,EACjC,OAAO,GAAE,qBAA0B,GACjC,mBAAmB,CAuBrB"}