ax-audit 4.2.1 → 6.0.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 +19 -0
- package/README.md +39 -4
- package/dist/baseline.js +1 -1
- package/dist/baseline.js.map +1 -1
- package/dist/check-ids.js +1 -1
- package/dist/check-ids.js.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/constants.d.ts +1 -85
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +0 -135
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/license.d.ts +8 -0
- package/dist/license.d.ts.map +1 -0
- package/dist/license.js +18 -0
- package/dist/license.js.map +1 -0
- package/dist/metadata.d.ts +6 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +205 -0
- package/dist/metadata.js.map +1 -0
- package/dist/orchestrator.d.ts +1 -0
- package/dist/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator.js +134 -56
- package/dist/orchestrator.js.map +1 -1
- package/dist/scorer.js +2 -2
- package/dist/scorer.js.map +1 -1
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/docs/api.md +14 -3
- package/docs/architecture.md +9 -98
- package/docs/ci.md +19 -0
- package/docs/cli.md +11 -0
- package/docs/faq.md +18 -0
- package/docs/getting-started.md +33 -1
- package/package.json +5 -5
- package/dist/checks/agent-access.d.ts +0 -33
- package/dist/checks/agent-access.d.ts.map +0 -1
- package/dist/checks/agent-access.js +0 -256
- package/dist/checks/agent-access.js.map +0 -1
- package/dist/checks/agent-card.d.ts +0 -37
- package/dist/checks/agent-card.d.ts.map +0 -1
- package/dist/checks/agent-card.js +0 -352
- package/dist/checks/agent-card.js.map +0 -1
- package/dist/checks/agent-operability.d.ts +0 -66
- package/dist/checks/agent-operability.d.ts.map +0 -1
- package/dist/checks/agent-operability.js +0 -383
- package/dist/checks/agent-operability.js.map +0 -1
- package/dist/checks/agent-skills.d.ts +0 -24
- package/dist/checks/agent-skills.d.ts.map +0 -1
- package/dist/checks/agent-skills.js +0 -316
- package/dist/checks/agent-skills.js.map +0 -1
- package/dist/checks/ai-catalog.d.ts +0 -28
- package/dist/checks/ai-catalog.d.ts.map +0 -1
- package/dist/checks/ai-catalog.js +0 -254
- package/dist/checks/ai-catalog.js.map +0 -1
- package/dist/checks/ai-directives.d.ts +0 -57
- package/dist/checks/ai-directives.d.ts.map +0 -1
- package/dist/checks/ai-directives.js +0 -263
- package/dist/checks/ai-directives.js.map +0 -1
- package/dist/checks/api-discovery.d.ts +0 -26
- package/dist/checks/api-discovery.d.ts.map +0 -1
- package/dist/checks/api-discovery.js +0 -432
- package/dist/checks/api-discovery.js.map +0 -1
- package/dist/checks/auth-discovery.d.ts +0 -28
- package/dist/checks/auth-discovery.d.ts.map +0 -1
- package/dist/checks/auth-discovery.js +0 -302
- package/dist/checks/auth-discovery.js.map +0 -1
- package/dist/checks/commerce-discovery.d.ts +0 -40
- package/dist/checks/commerce-discovery.d.ts.map +0 -1
- package/dist/checks/commerce-discovery.js +0 -295
- package/dist/checks/commerce-discovery.js.map +0 -1
- package/dist/checks/content-negotiation.d.ts +0 -4
- package/dist/checks/content-negotiation.d.ts.map +0 -1
- package/dist/checks/content-negotiation.js +0 -253
- package/dist/checks/content-negotiation.js.map +0 -1
- package/dist/checks/crawl-efficiency.d.ts +0 -16
- package/dist/checks/crawl-efficiency.d.ts.map +0 -1
- package/dist/checks/crawl-efficiency.js +0 -186
- package/dist/checks/crawl-efficiency.js.map +0 -1
- package/dist/checks/frontmatter.d.ts +0 -34
- package/dist/checks/frontmatter.d.ts.map +0 -1
- package/dist/checks/frontmatter.js +0 -100
- package/dist/checks/frontmatter.js.map +0 -1
- package/dist/checks/html-rendering.d.ts +0 -21
- package/dist/checks/html-rendering.d.ts.map +0 -1
- package/dist/checks/html-rendering.js +0 -221
- package/dist/checks/html-rendering.js.map +0 -1
- package/dist/checks/html-utils.d.ts +0 -66
- package/dist/checks/html-utils.d.ts.map +0 -1
- package/dist/checks/html-utils.js +0 -139
- package/dist/checks/html-utils.js.map +0 -1
- package/dist/checks/http-headers.d.ts +0 -11
- package/dist/checks/http-headers.d.ts.map +0 -1
- package/dist/checks/http-headers.js +0 -249
- package/dist/checks/http-headers.js.map +0 -1
- package/dist/checks/http-hygiene.d.ts +0 -26
- package/dist/checks/http-hygiene.d.ts.map +0 -1
- package/dist/checks/http-hygiene.js +0 -257
- package/dist/checks/http-hygiene.js.map +0 -1
- package/dist/checks/index.d.ts +0 -3
- package/dist/checks/index.d.ts.map +0 -1
- package/dist/checks/index.js +0 -55
- package/dist/checks/index.js.map +0 -1
- package/dist/checks/llms-txt.d.ts +0 -19
- package/dist/checks/llms-txt.d.ts.map +0 -1
- package/dist/checks/llms-txt.js +0 -281
- package/dist/checks/llms-txt.js.map +0 -1
- package/dist/checks/mcp-discovery.d.ts +0 -30
- package/dist/checks/mcp-discovery.d.ts.map +0 -1
- package/dist/checks/mcp-discovery.js +0 -523
- package/dist/checks/mcp-discovery.js.map +0 -1
- package/dist/checks/meta-tags.d.ts +0 -17
- package/dist/checks/meta-tags.d.ts.map +0 -1
- package/dist/checks/meta-tags.js +0 -188
- package/dist/checks/meta-tags.js.map +0 -1
- package/dist/checks/robots-parser.d.ts +0 -110
- package/dist/checks/robots-parser.d.ts.map +0 -1
- package/dist/checks/robots-parser.js +0 -277
- package/dist/checks/robots-parser.js.map +0 -1
- package/dist/checks/robots-txt.d.ts +0 -6
- package/dist/checks/robots-txt.d.ts.map +0 -1
- package/dist/checks/robots-txt.js +0 -367
- package/dist/checks/robots-txt.js.map +0 -1
- package/dist/checks/rsl.d.ts +0 -4
- package/dist/checks/rsl.d.ts.map +0 -1
- package/dist/checks/rsl.js +0 -242
- package/dist/checks/rsl.js.map +0 -1
- package/dist/checks/security-txt.d.ts +0 -4
- package/dist/checks/security-txt.d.ts.map +0 -1
- package/dist/checks/security-txt.js +0 -81
- package/dist/checks/security-txt.js.map +0 -1
- package/dist/checks/seo-basics.d.ts +0 -13
- package/dist/checks/seo-basics.d.ts.map +0 -1
- package/dist/checks/seo-basics.js +0 -221
- package/dist/checks/seo-basics.js.map +0 -1
- package/dist/checks/sitemap.d.ts +0 -12
- package/dist/checks/sitemap.d.ts.map +0 -1
- package/dist/checks/sitemap.js +0 -240
- package/dist/checks/sitemap.js.map +0 -1
- package/dist/checks/structured-data.d.ts +0 -4
- package/dist/checks/structured-data.d.ts.map +0 -1
- package/dist/checks/structured-data.js +0 -408
- package/dist/checks/structured-data.js.map +0 -1
- package/dist/checks/structured-fields.d.ts +0 -46
- package/dist/checks/structured-fields.d.ts.map +0 -1
- package/dist/checks/structured-fields.js +0 -112
- package/dist/checks/structured-fields.js.map +0 -1
- package/dist/checks/surface.d.ts +0 -59
- package/dist/checks/surface.d.ts.map +0 -1
- package/dist/checks/surface.js +0 -106
- package/dist/checks/surface.js.map +0 -1
- package/dist/checks/tls-https.d.ts +0 -13
- package/dist/checks/tls-https.d.ts.map +0 -1
- package/dist/checks/tls-https.js +0 -163
- package/dist/checks/tls-https.js.map +0 -1
- package/dist/checks/usage-policy.d.ts +0 -53
- package/dist/checks/usage-policy.d.ts.map +0 -1
- package/dist/checks/usage-policy.js +0 -339
- package/dist/checks/usage-policy.js.map +0 -1
- package/dist/checks/utils.d.ts +0 -40
- package/dist/checks/utils.d.ts.map +0 -1
- package/dist/checks/utils.js +0 -74
- package/dist/checks/utils.js.map +0 -1
- package/dist/checks/waf.d.ts +0 -75
- package/dist/checks/waf.d.ts.map +0 -1
- package/dist/checks/waf.js +0 -203
- package/dist/checks/waf.js.map +0 -1
- package/dist/checks/webmcp.d.ts +0 -55
- package/dist/checks/webmcp.d.ts.map +0 -1
- package/dist/checks/webmcp.js +0 -209
- package/dist/checks/webmcp.js.map +0 -1
- package/dist/checks/well-known.d.ts +0 -38
- package/dist/checks/well-known.d.ts.map +0 -1
- package/dist/checks/well-known.js +0 -202
- package/dist/checks/well-known.js.map +0 -1
- package/dist/fetcher.d.ts +0 -15
- package/dist/fetcher.d.ts.map +0 -1
- package/dist/fetcher.js +0 -127
- package/dist/fetcher.js.map +0 -1
- package/dist/guide-urls.d.ts +0 -2
- package/dist/guide-urls.d.ts.map +0 -1
- package/dist/guide-urls.js +0 -5
- package/dist/guide-urls.js.map +0 -1
- package/docs/roadmap.md +0 -367
package/dist/checks/surface.d.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Does this site have the surface a protocol check is about?
|
|
3
|
-
*
|
|
4
|
-
* From 4.0, protocol checks carry weight. That is only defensible if they apply
|
|
5
|
-
* to the site being audited. A blog has no API to describe and is not an agent;
|
|
6
|
-
* scoring it zero for publishing no OpenAPI document or Agent Card would say
|
|
7
|
-
* something false about the blog and make the overall number useless as a
|
|
8
|
-
* signal.
|
|
9
|
-
*
|
|
10
|
-
* So each protocol check asks first whether the site has the corresponding
|
|
11
|
-
* surface. When it does not, the check reports N/A — visible in the report,
|
|
12
|
-
* excluded from the score — and says what publishing one would enable. When it
|
|
13
|
-
* does, a missing description is a real finding, because the capability exists
|
|
14
|
-
* and agents cannot find it.
|
|
15
|
-
*
|
|
16
|
-
* A `--profile` flag overrides the detection, so a site can be audited against
|
|
17
|
-
* what it intends to become rather than only what it already is.
|
|
18
|
-
*/
|
|
19
|
-
import type { CheckContext } from '../types.js';
|
|
20
|
-
/** Surfaces a site can have, each gating one or more protocol checks. */
|
|
21
|
-
export type Surface = 'api' | 'mcp' | 'agent' | 'docs' | 'commerce';
|
|
22
|
-
/**
|
|
23
|
-
* Profiles a user can force with `--profile`. `all` makes every protocol check
|
|
24
|
-
* applicable, which is what a site planning its agent integration wants.
|
|
25
|
-
*/
|
|
26
|
-
export type Profile = 'auto' | 'api' | 'mcp' | 'agent' | 'docs' | 'commerce' | 'all';
|
|
27
|
-
export interface SurfaceEvidence {
|
|
28
|
-
found: boolean;
|
|
29
|
-
/** What made the check applicable, for the report. */
|
|
30
|
-
reason: string;
|
|
31
|
-
}
|
|
32
|
-
/** Read the profile a run was invoked with, defaulting to automatic detection. */
|
|
33
|
-
export declare function profileFrom(ctx: CheckContext): Profile;
|
|
34
|
-
/** Whether the active profile forces this surface applicable. */
|
|
35
|
-
export declare function forcedBy(profile: Profile, surface: Surface): boolean;
|
|
36
|
-
/**
|
|
37
|
-
* Does this site offer an HTTP API?
|
|
38
|
-
*
|
|
39
|
-
* Evidence: a description at a conventional location, an RFC 9727 catalog, a
|
|
40
|
-
* `service-desc` relation, or navigation into an API or developer area. The
|
|
41
|
-
* last is the loosest and the most common: a site with a "Developers" link
|
|
42
|
-
* almost certainly has an API worth describing.
|
|
43
|
-
*/
|
|
44
|
-
export declare function hasApiSurface(ctx: CheckContext): Promise<SurfaceEvidence>;
|
|
45
|
-
/** Does this site run an MCP server? */
|
|
46
|
-
export declare function hasMcpSurface(ctx: CheckContext): Promise<SurfaceEvidence>;
|
|
47
|
-
/**
|
|
48
|
-
* Is this site agent-facing — something an agent would call rather than only
|
|
49
|
-
* read?
|
|
50
|
-
*
|
|
51
|
-
* An Agent Card describes capabilities another agent can invoke. Most sites do
|
|
52
|
-
* not have any, and asking a restaurant to publish one is noise. A site that
|
|
53
|
-
* runs an MCP server, offers an API, or already publishes a card is a different
|
|
54
|
-
* matter.
|
|
55
|
-
*/
|
|
56
|
-
export declare function hasAgentSurface(ctx: CheckContext): Promise<SurfaceEvidence>;
|
|
57
|
-
/** Does this site have documentation an agent could be taught to follow? */
|
|
58
|
-
export declare function hasDocsSurface(ctx: CheckContext): Promise<SurfaceEvidence>;
|
|
59
|
-
//# sourceMappingURL=surface.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"surface.d.ts","sourceRoot":"","sources":["../../src/checks/surface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIhD,yEAAyE;AACzE,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,CAAC;AAEpE;;;GAGG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,GAAG,KAAK,CAAC;AAErF,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;CAChB;AAID,kFAAkF;AAClF,wBAAgB,WAAW,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAEtD;AAED,iEAAiE;AACjE,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAEpE;AAaD;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,CAkB/E;AAED,wCAAwC;AACxC,wBAAsB,aAAa,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,CAiB/E;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,CAmBjF;AAED,4EAA4E;AAC5E,wBAAsB,cAAc,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,CAWhF"}
|
package/dist/checks/surface.js
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import { isHtmlDocument } from './utils.js';
|
|
2
|
-
import { parseLinkHeader } from './http-headers.js';
|
|
3
|
-
const NOT_FOUND = { found: false, reason: '' };
|
|
4
|
-
/** Read the profile a run was invoked with, defaulting to automatic detection. */
|
|
5
|
-
export function profileFrom(ctx) {
|
|
6
|
-
return ctx.profile ?? 'auto';
|
|
7
|
-
}
|
|
8
|
-
/** Whether the active profile forces this surface applicable. */
|
|
9
|
-
export function forcedBy(profile, surface) {
|
|
10
|
-
return profile === 'all' || profile === surface;
|
|
11
|
-
}
|
|
12
|
-
async function exists(ctx, path) {
|
|
13
|
-
const res = await ctx.fetch(`${ctx.url}${path}`);
|
|
14
|
-
return res.ok && res.body.trim().length > 0 && !isHtmlDocument(res.body);
|
|
15
|
-
}
|
|
16
|
-
/** Links and headers pointing at a named area of the site. */
|
|
17
|
-
function linksTo(ctx, pattern) {
|
|
18
|
-
if (pattern.test(ctx.html ?? ''))
|
|
19
|
-
return true;
|
|
20
|
-
return parseLinkHeader(ctx.headers?.['link'] ?? '').some((entry) => pattern.test(entry.url));
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Does this site offer an HTTP API?
|
|
24
|
-
*
|
|
25
|
-
* Evidence: a description at a conventional location, an RFC 9727 catalog, a
|
|
26
|
-
* `service-desc` relation, or navigation into an API or developer area. The
|
|
27
|
-
* last is the loosest and the most common: a site with a "Developers" link
|
|
28
|
-
* almost certainly has an API worth describing.
|
|
29
|
-
*/
|
|
30
|
-
export async function hasApiSurface(ctx) {
|
|
31
|
-
if (forcedBy(profileFrom(ctx), 'api'))
|
|
32
|
-
return { found: true, reason: '--profile api' };
|
|
33
|
-
for (const path of ['/openapi.json', '/.well-known/openapi.json', '/.well-known/api-catalog', '/swagger.json']) {
|
|
34
|
-
if (await exists(ctx, path))
|
|
35
|
-
return { found: true, reason: `a document at ${path}` };
|
|
36
|
-
}
|
|
37
|
-
if (linksTo(ctx, /rel\s*=\s*["'][^"']*service-desc/i)) {
|
|
38
|
-
return { found: true, reason: 'a service-desc link relation' };
|
|
39
|
-
}
|
|
40
|
-
if (linksTo(ctx, /href\s*=\s*["'][^"']*\/(api|developers?|api-docs|reference)\b/i)) {
|
|
41
|
-
return { found: true, reason: 'navigation into an API or developer area' };
|
|
42
|
-
}
|
|
43
|
-
if (/\bapi\.[a-z0-9-]+\.[a-z]{2,}/i.test(ctx.html ?? '')) {
|
|
44
|
-
return { found: true, reason: 'references to an API subdomain' };
|
|
45
|
-
}
|
|
46
|
-
return NOT_FOUND;
|
|
47
|
-
}
|
|
48
|
-
/** Does this site run an MCP server? */
|
|
49
|
-
export async function hasMcpSurface(ctx) {
|
|
50
|
-
if (forcedBy(profileFrom(ctx), 'mcp'))
|
|
51
|
-
return { found: true, reason: '--profile mcp' };
|
|
52
|
-
for (const path of ['/.well-known/mcp/server-card.json', '/mcp/server-card', '/.well-known/mcp.json']) {
|
|
53
|
-
if (await exists(ctx, path))
|
|
54
|
-
return { found: true, reason: `a document at ${path}` };
|
|
55
|
-
}
|
|
56
|
-
const catalog = await ctx.fetch(`${ctx.url}/.well-known/ai-catalog.json`);
|
|
57
|
-
if (catalog.ok && /application\/mcp-server-card\+json/.test(catalog.body)) {
|
|
58
|
-
return { found: true, reason: 'an MCP entry in the AI catalog' };
|
|
59
|
-
}
|
|
60
|
-
if (linksTo(ctx, /href\s*=\s*["'][^"']*\/mcp\b/i)) {
|
|
61
|
-
return { found: true, reason: 'navigation referencing an MCP endpoint' };
|
|
62
|
-
}
|
|
63
|
-
return NOT_FOUND;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Is this site agent-facing — something an agent would call rather than only
|
|
67
|
-
* read?
|
|
68
|
-
*
|
|
69
|
-
* An Agent Card describes capabilities another agent can invoke. Most sites do
|
|
70
|
-
* not have any, and asking a restaurant to publish one is noise. A site that
|
|
71
|
-
* runs an MCP server, offers an API, or already publishes a card is a different
|
|
72
|
-
* matter.
|
|
73
|
-
*/
|
|
74
|
-
export async function hasAgentSurface(ctx) {
|
|
75
|
-
if (forcedBy(profileFrom(ctx), 'agent'))
|
|
76
|
-
return { found: true, reason: '--profile agent' };
|
|
77
|
-
for (const path of ['/.well-known/agent-card.json', '/.well-known/agent.json']) {
|
|
78
|
-
if (await exists(ctx, path))
|
|
79
|
-
return { found: true, reason: `a document at ${path}` };
|
|
80
|
-
}
|
|
81
|
-
const catalog = await ctx.fetch(`${ctx.url}/.well-known/ai-catalog.json`);
|
|
82
|
-
if (catalog.ok && /application\/a2a-agent-card\+json/.test(catalog.body)) {
|
|
83
|
-
return { found: true, reason: 'an A2A entry in the AI catalog' };
|
|
84
|
-
}
|
|
85
|
-
const mcp = await hasMcpSurface(ctx);
|
|
86
|
-
if (mcp.found)
|
|
87
|
-
return { found: true, reason: `an MCP surface (${mcp.reason})` };
|
|
88
|
-
const api = await hasApiSurface(ctx);
|
|
89
|
-
if (api.found)
|
|
90
|
-
return { found: true, reason: `an API surface (${api.reason})` };
|
|
91
|
-
return NOT_FOUND;
|
|
92
|
-
}
|
|
93
|
-
/** Does this site have documentation an agent could be taught to follow? */
|
|
94
|
-
export async function hasDocsSurface(ctx) {
|
|
95
|
-
if (forcedBy(profileFrom(ctx), 'docs'))
|
|
96
|
-
return { found: true, reason: '--profile docs' };
|
|
97
|
-
if (linksTo(ctx, /href\s*=\s*["'][^"']*\/(docs|documentation|guides?|reference|developers?)\b/i)) {
|
|
98
|
-
return { found: true, reason: 'navigation into a documentation area' };
|
|
99
|
-
}
|
|
100
|
-
for (const path of ['/llms.txt', '/openapi.json']) {
|
|
101
|
-
if (await exists(ctx, path))
|
|
102
|
-
return { found: true, reason: `a document at ${path}` };
|
|
103
|
-
}
|
|
104
|
-
return NOT_FOUND;
|
|
105
|
-
}
|
|
106
|
-
//# sourceMappingURL=surface.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"surface.js","sourceRoot":"","sources":["../../src/checks/surface.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { CheckContext, CheckResult, CheckMeta } from '../types.js';
|
|
2
|
-
/**
|
|
3
|
-
* "tls-https" — verify the site is served over HTTPS, that bare HTTP redirects to HTTPS,
|
|
4
|
-
* and that HSTS is properly configured (with `preload` + `includeSubDomains` for full
|
|
5
|
-
* coverage). Many AI agents refuse to fetch plaintext HTTP and downgrade trust on
|
|
6
|
-
* misconfigured TLS.
|
|
7
|
-
*
|
|
8
|
-
* The check intentionally avoids verifying the certificate chain — Node's `fetch` already
|
|
9
|
-
* fails on invalid certificates, so a successful HTTPS fetch is itself a positive signal.
|
|
10
|
-
*/
|
|
11
|
-
export declare const meta: CheckMeta;
|
|
12
|
-
export default function check(ctx: CheckContext): Promise<CheckResult>;
|
|
13
|
-
//# sourceMappingURL=tls-https.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tls-https.d.ts","sourceRoot":"","sources":["../../src/checks/tls-https.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAW,MAAM,aAAa,CAAC;AAGjF;;;;;;;;GAQG;AACH,eAAO,MAAM,IAAI,EAAE,SAIlB,CAAC;AAKF,wBAA8B,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAqI3E"}
|
package/dist/checks/tls-https.js
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { guideUrl } from '../guide-urls.js';
|
|
2
|
-
import { buildResult } from './utils.js';
|
|
3
|
-
/**
|
|
4
|
-
* "tls-https" — verify the site is served over HTTPS, that bare HTTP redirects to HTTPS,
|
|
5
|
-
* and that HSTS is properly configured (with `preload` + `includeSubDomains` for full
|
|
6
|
-
* coverage). Many AI agents refuse to fetch plaintext HTTP and downgrade trust on
|
|
7
|
-
* misconfigured TLS.
|
|
8
|
-
*
|
|
9
|
-
* The check intentionally avoids verifying the certificate chain — Node's `fetch` already
|
|
10
|
-
* fails on invalid certificates, so a successful HTTPS fetch is itself a positive signal.
|
|
11
|
-
*/
|
|
12
|
-
export const meta = {
|
|
13
|
-
id: 'tls-https',
|
|
14
|
-
name: 'TLS / HTTPS',
|
|
15
|
-
description: 'Checks HTTPS, HTTP→HTTPS redirect, and HSTS configuration',
|
|
16
|
-
};
|
|
17
|
-
const HSTS_MIN_MAX_AGE = 15_768_000;
|
|
18
|
-
const HSTS_PRELOAD_MIN_MAX_AGE = 31_536_000;
|
|
19
|
-
export default async function check(ctx) {
|
|
20
|
-
const start = performance.now();
|
|
21
|
-
const findings = [];
|
|
22
|
-
let score = 100;
|
|
23
|
-
let parsed;
|
|
24
|
-
try {
|
|
25
|
-
parsed = new URL(ctx.url);
|
|
26
|
-
}
|
|
27
|
-
catch {
|
|
28
|
-
findings.push({
|
|
29
|
-
status: 'fail',
|
|
30
|
-
message: `Invalid URL: ${ctx.url}`,
|
|
31
|
-
hint: 'Provide a fully qualified URL including scheme (https://...).',
|
|
32
|
-
learnMoreUrl: guideUrl(meta.id, 'invalid-url'),
|
|
33
|
-
});
|
|
34
|
-
return buildResult(meta, 0, findings, start);
|
|
35
|
-
}
|
|
36
|
-
if (parsed.protocol === 'https:') {
|
|
37
|
-
findings.push({ status: 'pass', message: 'Site is served over HTTPS' });
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
findings.push({
|
|
41
|
-
status: 'fail',
|
|
42
|
-
message: `Site is served over ${parsed.protocol.replace(':', '').toUpperCase()} (not HTTPS)`,
|
|
43
|
-
hint: 'Serve the site over HTTPS. Most AI crawlers refuse plaintext HTTP and downgrade trust on insecure origins.',
|
|
44
|
-
learnMoreUrl: guideUrl(meta.id, 'no-https'),
|
|
45
|
-
});
|
|
46
|
-
score -= 50;
|
|
47
|
-
}
|
|
48
|
-
if (parsed.protocol === 'https:') {
|
|
49
|
-
const httpUrl = `http://${parsed.host}${parsed.pathname || ''}`;
|
|
50
|
-
const httpRes = await ctx.fetch(httpUrl);
|
|
51
|
-
const finalUrl = httpRes.url || '';
|
|
52
|
-
if (httpRes.ok && /^https:\/\//i.test(finalUrl)) {
|
|
53
|
-
findings.push({ status: 'pass', message: 'HTTP requests redirect to HTTPS' });
|
|
54
|
-
}
|
|
55
|
-
else if (!httpRes.ok && httpRes.status === 0) {
|
|
56
|
-
findings.push({
|
|
57
|
-
status: 'pass',
|
|
58
|
-
message: 'HTTP endpoint not reachable (HTTPS-only — acceptable)',
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
else if (httpRes.ok && /^http:\/\//i.test(finalUrl)) {
|
|
62
|
-
findings.push({
|
|
63
|
-
status: 'fail',
|
|
64
|
-
message: 'HTTP request did not redirect to HTTPS',
|
|
65
|
-
detail: `Final URL: ${finalUrl}`,
|
|
66
|
-
hint: 'Configure your server to 301-redirect every http:// request to https://. Otherwise agents may cache the insecure variant.',
|
|
67
|
-
learnMoreUrl: guideUrl(meta.id, 'no-redirect'),
|
|
68
|
-
});
|
|
69
|
-
score -= 15;
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
findings.push({
|
|
73
|
-
status: 'warn',
|
|
74
|
-
message: 'Could not verify HTTP→HTTPS redirect',
|
|
75
|
-
detail: `HTTP ${httpRes.status} on ${httpUrl}`,
|
|
76
|
-
hint: 'Test manually: a request to http://your-site.com should respond with 301 → https://your-site.com.',
|
|
77
|
-
learnMoreUrl: guideUrl(meta.id, 'redirect-unknown'),
|
|
78
|
-
});
|
|
79
|
-
score -= 5;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
const hsts = ctx.headers['strict-transport-security'];
|
|
83
|
-
if (!hsts) {
|
|
84
|
-
findings.push({
|
|
85
|
-
status: 'warn',
|
|
86
|
-
message: 'No Strict-Transport-Security header',
|
|
87
|
-
hint: 'Add: Strict-Transport-Security: max-age=31536000; includeSubDomains; preload. This locks browsers and many agents to HTTPS for 1 year.',
|
|
88
|
-
learnMoreUrl: guideUrl(meta.id, 'no-hsts'),
|
|
89
|
-
});
|
|
90
|
-
score -= 15;
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
const maxAge = parseHstsMaxAge(hsts);
|
|
94
|
-
const includesSubDomains = /includeSubDomains/i.test(hsts);
|
|
95
|
-
const preload = /preload/i.test(hsts);
|
|
96
|
-
if (maxAge === null) {
|
|
97
|
-
findings.push({
|
|
98
|
-
status: 'warn',
|
|
99
|
-
message: 'HSTS header has no max-age directive',
|
|
100
|
-
detail: hsts,
|
|
101
|
-
hint: 'Set a numeric max-age, e.g., max-age=31536000.',
|
|
102
|
-
learnMoreUrl: guideUrl(meta.id, 'hsts-no-maxage'),
|
|
103
|
-
});
|
|
104
|
-
score -= 10;
|
|
105
|
-
}
|
|
106
|
-
else if (maxAge < HSTS_MIN_MAX_AGE) {
|
|
107
|
-
findings.push({
|
|
108
|
-
status: 'warn',
|
|
109
|
-
message: `HSTS max-age is short (${maxAge}s = ~${Math.round(maxAge / 86400)} days)`,
|
|
110
|
-
hint: `Use at least max-age=${HSTS_MIN_MAX_AGE} (~6 months); preload list submission requires max-age=${HSTS_PRELOAD_MIN_MAX_AGE} (1 year).`,
|
|
111
|
-
learnMoreUrl: guideUrl(meta.id, 'hsts-short'),
|
|
112
|
-
});
|
|
113
|
-
score -= 5;
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
findings.push({ status: 'pass', message: `HSTS max-age=${maxAge}` });
|
|
117
|
-
}
|
|
118
|
-
if (includesSubDomains) {
|
|
119
|
-
findings.push({ status: 'pass', message: 'HSTS includes subdomains' });
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
findings.push({
|
|
123
|
-
status: 'warn',
|
|
124
|
-
message: 'HSTS does not include subdomains',
|
|
125
|
-
hint: 'Add includeSubDomains to apply HSTS across api., docs., etc. Required for preload list submission.',
|
|
126
|
-
learnMoreUrl: guideUrl(meta.id, 'hsts-no-subdomains'),
|
|
127
|
-
});
|
|
128
|
-
score -= 5;
|
|
129
|
-
}
|
|
130
|
-
if (preload) {
|
|
131
|
-
if (maxAge !== null && maxAge >= HSTS_PRELOAD_MIN_MAX_AGE && includesSubDomains) {
|
|
132
|
-
findings.push({ status: 'pass', message: 'HSTS preload-eligible' });
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
findings.push({
|
|
136
|
-
status: 'warn',
|
|
137
|
-
message: 'HSTS has preload directive but does not satisfy preload-list requirements',
|
|
138
|
-
hint: `Preload requires max-age >= ${HSTS_PRELOAD_MIN_MAX_AGE} and includeSubDomains. See https://hstspreload.org.`,
|
|
139
|
-
learnMoreUrl: guideUrl(meta.id, 'hsts-preload-invalid'),
|
|
140
|
-
});
|
|
141
|
-
score -= 5;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
else {
|
|
145
|
-
findings.push({
|
|
146
|
-
status: 'warn',
|
|
147
|
-
message: 'HSTS lacks the preload directive',
|
|
148
|
-
hint: 'Add preload (and ensure max-age >= 31536000 + includeSubDomains) and submit the domain at https://hstspreload.org for browser-built-in HTTPS enforcement.',
|
|
149
|
-
learnMoreUrl: guideUrl(meta.id, 'hsts-no-preload'),
|
|
150
|
-
});
|
|
151
|
-
score -= 3;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
return buildResult(meta, score, findings, start);
|
|
155
|
-
}
|
|
156
|
-
function parseHstsMaxAge(value) {
|
|
157
|
-
const m = value.match(/max-age\s*=\s*"?(\d+)"?/i);
|
|
158
|
-
if (!m)
|
|
159
|
-
return null;
|
|
160
|
-
const n = Number(m[1]);
|
|
161
|
-
return Number.isFinite(n) ? n : null;
|
|
162
|
-
}
|
|
163
|
-
//# sourceMappingURL=tls-https.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tls-https.js","sourceRoot":"","sources":["../../src/checks/tls-https.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import type { CheckContext, CheckResult, CheckMeta } from '../types.js';
|
|
2
|
-
/**
|
|
3
|
-
* "usage-policy" — do your machine-readable usage signals agree with each other?
|
|
4
|
-
*
|
|
5
|
-
* A site can now state its AI usage terms in at least five places, written in
|
|
6
|
-
* vocabularies that mirror each other without matching:
|
|
7
|
-
*
|
|
8
|
-
* | Mechanism | Training | Grounding / RAG | Search |
|
|
9
|
-
* | --- | --- | --- | --- |
|
|
10
|
-
* | Content Signals (robots.txt) | `ai-train=yes\|no` | `ai-input=yes\|no` | `search=yes\|no` |
|
|
11
|
-
* | IETF AIPREF (robots.txt or header) | `train-ai=y\|n` | *(no category yet)* | `search=y\|n` |
|
|
12
|
-
* | RSL licence | `ai-train` | `ai-input` | `ai-index`, `search` |
|
|
13
|
-
* | TDMRep | `tdm-reservation: 0\|1` | — | — |
|
|
14
|
-
* | robots meta | `noai` | — | — |
|
|
15
|
-
*
|
|
16
|
-
* Nobody maintains five documents by hand without them drifting. This check
|
|
17
|
-
* normalises every signal onto three questions — may you train on it, may you
|
|
18
|
-
* ground an answer in it, may you index it — and reports where the answers
|
|
19
|
-
* disagree. A site whose robots.txt says `ai-train=no` while its RSL licence
|
|
20
|
-
* permits `ai-train` has published two contradictory legal positions, and which
|
|
21
|
-
* one a crawler honors is then a matter of which file it happened to read.
|
|
22
|
-
*
|
|
23
|
-
* On enforcement, the check is blunt: only robots.txt access rules are
|
|
24
|
-
* documented as honored by Google, OpenAI, Anthropic and Microsoft. Content
|
|
25
|
-
* Signals, AIPREF, RSL and TDMRep are declarations. Their weight is legal — the
|
|
26
|
-
* EU AI Act's opt-out provisions and the GPAI Code of Practice reference several
|
|
27
|
-
* of them — rather than technical, and reports say so rather than implying a
|
|
28
|
-
* crawler will obey.
|
|
29
|
-
*/
|
|
30
|
-
export declare const meta: CheckMeta;
|
|
31
|
-
/** The three questions every usage vocabulary answers, or declines to answer. */
|
|
32
|
-
export type Dimension = 'train' | 'ground' | 'index';
|
|
33
|
-
export type Stance = 'allow' | 'deny' | 'unstated';
|
|
34
|
-
export interface Declaration {
|
|
35
|
-
/** Human name of the mechanism and where it was found. */
|
|
36
|
-
source: string;
|
|
37
|
-
/** Whether the mechanism has any documented honorer among major AI operators. */
|
|
38
|
-
enforceable: boolean;
|
|
39
|
-
train: Stance;
|
|
40
|
-
ground: Stance;
|
|
41
|
-
index: Stance;
|
|
42
|
-
}
|
|
43
|
-
/** Read a Content-Signal value into a declaration. */
|
|
44
|
-
export declare function fromContentSignal(raw: string, source: string): Declaration;
|
|
45
|
-
/** Read an AIPREF Content-Usage value into a declaration. AIPREF has no grounding category yet. */
|
|
46
|
-
export declare function fromContentUsage(raw: string, source: string): Declaration;
|
|
47
|
-
/**
|
|
48
|
-
* Read RSL `permits` / `prohibits` usage tokens into a declaration.
|
|
49
|
-
* `all` and `ai-all` set several dimensions at once.
|
|
50
|
-
*/
|
|
51
|
-
export declare function fromRsl(document: string, source: string): Declaration;
|
|
52
|
-
export default function check(ctx: CheckContext): Promise<CheckResult>;
|
|
53
|
-
//# sourceMappingURL=usage-policy.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"usage-policy.d.ts","sourceRoot":"","sources":["../../src/checks/usage-policy.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAW,MAAM,aAAa,CAAC;AAQjF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,IAAI,EAAE,SAKlB,CAAC;AAEF,iFAAiF;AACjF,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAErD,MAAM,MAAM,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,CAAC;AAEnD,MAAM,WAAW,WAAW;IAC1B,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,WAAW,EAAE,OAAO,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAcD,sDAAsD;AACtD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAc1E;AAED,mGAAmG;AACnG,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAczE;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAqCrE;AA6ID,wBAA8B,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CA2C3E"}
|