import { createHash } from "node:crypto"; import { isDeepStrictEqual } from "node:util"; import { unprocessable } from "../errors.js"; import { sanitizeRecord } from "../redaction.js"; export const CLAUDE_MANAGED_QUALIFICATION = { betaVersion: "managed-agents-2026-04-01", environmentPolicy: "limited_no_hosts_no_packages", agentCapabilities: "no_tools_no_mcp_no_skills_no_multiagent", } as const; export const CLAUDE_MANAGED_QUALIFIED_MODEL = "claude-sonnet-5" as const; export const AGENTCORE_QUALIFICATION_SUITE = "aws-agentcore-harness-context-v2" as const; export const AGENTCORE_QUALIFIED_MODEL = "global.anthropic.claude-sonnet-4-6" as const; const REVISION_PREFIX = "sha256:"; const SHA256_RE = /^sha256:[0-9a-f]{64}$/; const ISO_TIMESTAMP_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/; const SECRET_SHAPED_VALUE_PATTERNS = [ /^\s*(?:bearer|basic)\s+\S+/i, /^sk-[A-Za-z0-9_-]{8,}$/, /^(?:gh[opusr]_[A-Za-z0-9]{12,}|xox[baprs]-\S+)$/, /^AKIA[0-9A-Z]{16}$/, /^[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}(?:\.[A-Za-z0-9_-]{8,})?$/, /-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/, ] as const; function containsSecretShapedValue(value: unknown): boolean { if (typeof value === "string") { return SECRET_SHAPED_VALUE_PATTERNS.some((pattern) => pattern.test(value)); } if (Array.isArray(value)) return value.some(containsSecretShapedValue); if (!value || typeof value !== "object") return false; return Object.values(value as Record).some(containsSecretShapedValue); } function normalizeKnownPublicValues(value: unknown): unknown { if ( value === CLAUDE_MANAGED_QUALIFIED_MODEL || value === AGENTCORE_QUALIFIED_MODEL ) { return "paperclip-qualified-provider-model"; } if (Array.isArray(value)) return value.map(normalizeKnownPublicValues); if (!value || typeof value !== "object") return value; return Object.fromEntries( Object.entries(value as Record) .map(([key, entry]) => [key, normalizeKnownPublicValues(entry)]), ); } export function assertProfileMetadataContainsNoSecrets( value: Record, label: string, ): void { const publicValueNormalized = normalizeKnownPublicValues(value) as Record; if ( !isDeepStrictEqual(sanitizeRecord(publicValueNormalized), publicValueNormalized) || containsSecretShapedValue(value) ) { throw unprocessable(`${label} must not contain credential-shaped keys or values`); } } function assertExactKeys( value: Record, keys: readonly string[], label: string, ): void { const actual = Object.keys(value).sort(); const expected = [...keys].sort(); if (!isDeepStrictEqual(actual, expected)) { throw unprocessable(`${label} must contain the exact qualification attestation fields`); } } function assertIsoTimestamp(value: unknown, label: string): void { if ( typeof value !== "string" || !ISO_TIMESTAMP_RE.test(value) || !Number.isFinite(Date.parse(value)) ) { throw unprocessable(`${label} must be an ISO-8601 UTC timestamp`); } } export function assertClaudeManagedQualification( qualification: Record, options: { required: boolean }, ): boolean { if (Object.keys(qualification).length === 0) { if (options.required) { throw unprocessable("Claude Managed qualification attestation is required before enablement"); } return false; } assertProfileMetadataContainsNoSecrets(qualification, "Managed Agent qualification"); assertExactKeys( qualification, ["probedAt", "betaVersion", "environmentPolicy", "agentCapabilities"], "Claude Managed qualification", ); assertIsoTimestamp(qualification.probedAt, "qualification.probedAt"); if ( qualification.betaVersion !== CLAUDE_MANAGED_QUALIFICATION.betaVersion || qualification.environmentPolicy !== CLAUDE_MANAGED_QUALIFICATION.environmentPolicy || qualification.agentCapabilities !== CLAUDE_MANAGED_QUALIFICATION.agentCapabilities ) { throw unprocessable("Claude Managed qualification attestation does not match the qualified profile"); } return true; } export function assertAgentCoreQualification( configuration: Record, qualification: Record, options: { required: boolean }, ): boolean { if (Object.keys(qualification).length === 0) { if (options.required) { throw unprocessable("AWS AgentCore qualification attestation is required before enablement"); } return false; } assertProfileMetadataContainsNoSecrets(qualification, "Remote Agent qualification"); assertExactKeys(qualification, ["suite"], "AWS AgentCore qualification"); if ( configuration.qualificationRevision !== AGENTCORE_QUALIFICATION_SUITE || qualification.suite !== AGENTCORE_QUALIFICATION_SUITE ) { throw unprocessable("AWS AgentCore qualification attestation does not match the qualified harness suite"); } return true; } type CanonicalJson = null | boolean | number | string | CanonicalJson[] | { [key: string]: CanonicalJson; }; function canonicalize(value: unknown, label: string): CanonicalJson { if (value === null || typeof value === "string" || typeof value === "boolean") return value; if (typeof value === "number" && Number.isFinite(value)) return value; if (Array.isArray(value)) return value.map((entry) => canonicalize(entry, label)); if (value && typeof value === "object") { return Object.fromEntries( Object.entries(value as Record) .filter(([, entry]) => entry !== undefined) .sort(([left], [right]) => left.localeCompare(right)) .map(([key, entry]) => [key, canonicalize(entry, label)]), ); } throw unprocessable(`${label} contains a value that cannot be revisioned`); } export function computeQualifiedProfileRevision( value: Record, ): string { const canonical = JSON.stringify(canonicalize(value, "Provider profile")); return `${REVISION_PREFIX}${createHash("sha256").update(canonical).digest("hex")}`; } export function isQualifiedProfileRevision(value: unknown): value is string { return typeof value === "string" && SHA256_RE.test(value); }