feat(ql3): establish 3.0 incubation baseline

This commit is contained in:
whyour
2026-08-12 00:25:26 +08:00
parent 4bf92dcfeb
commit c699c32461
2817 changed files with 779642 additions and 653 deletions
@@ -0,0 +1,253 @@
// Authentication owns credential verification and bounded Principal issuance.
import { createHmac, timingSafeEqual } from 'node:crypto';
import {
ApiCredentialUnavailableError,
LEGACY_API_CREDENTIAL_PEPPER_KEY_ID,
assertApiCredentialPepperKeyId,
normalizeApiCredentialRecord,
type ApiCredentialRepository,
} from '@qinglong/runtime-core/api-credential';
import {
normalizeSecurityPrincipal,
type SecurityPrincipal,
} from '@qinglong/runtime-core/security';
import type { ClusterControlAdmissionMetadata } from '../transport/httpSurface';
import type { ClusterControlRequestAuthenticator } from '../transport/admissionPipeline';
export const CLUSTER_CONTROL_API_CREDENTIAL_LIMITS = Object.freeze({
principalTtlMs: 60_000,
maxPrincipalTtlMs: 300_000,
secretBytes: 32,
});
export class ClusterControlApiCredentialConfigurationError extends TypeError {
constructor(message: string) {
super(
`Cluster-control API credential configuration is invalid: ${message}`,
);
this.name = 'ClusterControlApiCredentialConfigurationError';
}
}
export class ClusterControlApiCredentialUnavailableError extends Error {
readonly code = 'CLUSTER_CONTROL_API_CREDENTIAL_UNAVAILABLE';
constructor() {
super('Cluster-control API credential authentication is unavailable');
this.name = 'ClusterControlApiCredentialUnavailableError';
}
}
export interface ClusterControlApiCredentialAuthenticatorOptions {
readonly principalTtlMs?: number;
readonly pepperKeyId?: string;
readonly now?: () => number;
}
const AUTHORIZATION_PATTERN =
/^Bearer ql3c_([A-Za-z0-9][A-Za-z0-9._:-]{0,63})_([A-Za-z0-9_-]{43})$/;
const PEPPER_PATTERN = /^[A-Za-z0-9_-]{43}$/;
const DIGEST_DOMAIN = Buffer.from('qinglong-api-credential-v1\0', 'utf8');
function decodeSecret(name: string, value: string): Buffer {
if (typeof value !== 'string' || !PEPPER_PATTERN.test(value)) {
throw new ClusterControlApiCredentialConfigurationError(
`${name} must be canonical base64url for 32 bytes`,
);
}
const decoded = Buffer.from(value, 'base64url');
if (
decoded.byteLength !== CLUSTER_CONTROL_API_CREDENTIAL_LIMITS.secretBytes ||
decoded.toString('base64url') !== value
) {
throw new ClusterControlApiCredentialConfigurationError(
`${name} must be canonical base64url for 32 bytes`,
);
}
return decoded;
}
export function assertClusterControlApiCredentialPepper(value: string): void {
const decoded = decodeSecret('pepper', value);
decoded.fill(0);
}
function principalTtl(value: number | undefined): number {
const resolved =
value ?? CLUSTER_CONTROL_API_CREDENTIAL_LIMITS.principalTtlMs;
if (
!Number.isSafeInteger(resolved) ||
resolved < 1_000 ||
resolved > CLUSTER_CONTROL_API_CREDENTIAL_LIMITS.maxPrincipalTtlMs
) {
throw new ClusterControlApiCredentialConfigurationError(
'principalTtlMs is invalid',
);
}
return resolved;
}
function digest(pepper: Buffer, credentialId: string, secret: Buffer): Buffer {
return createHmac('sha256', pepper)
.update(DIGEST_DOMAIN)
.update(credentialId, 'utf8')
.update('\0', 'utf8')
.update(secret)
.digest();
}
export function apiCredentialSecretDigest(
pepperBase64Url: string,
credentialId: string,
secretBase64Url: string,
): string {
if (!/^[A-Za-z0-9][A-Za-z0-9._:-]{0,63}$/.test(credentialId)) {
throw new ClusterControlApiCredentialConfigurationError(
'credentialId is invalid',
);
}
const pepper = decodeSecret('pepper', pepperBase64Url);
const secret = decodeSecret('secret', secretBase64Url);
let result: Buffer | undefined;
try {
result = digest(pepper, credentialId, secret);
return result.toString('hex');
} finally {
result?.fill(0);
pepper.fill(0);
secret.fill(0);
}
}
function parseAuthorization(
metadata: ClusterControlAdmissionMetadata,
): { readonly credentialId: string; readonly secret: Buffer } | null {
const value = metadata.headers.authorization;
if (typeof value !== 'string') return null;
const match = AUTHORIZATION_PATTERN.exec(value);
if (!match) return null;
let secret: Buffer;
try {
secret = decodeSecret('bearer secret', match[2]!);
} catch {
return null;
}
return Object.freeze({ credentialId: match[1]!, secret });
}
export function createClusterControlApiCredentialAuthenticator(
repository: ApiCredentialRepository,
pepperBase64Url: string,
options: ClusterControlApiCredentialAuthenticatorOptions = {},
): ClusterControlRequestAuthenticator {
if (!repository || typeof repository.resolve !== 'function') {
throw new ClusterControlApiCredentialConfigurationError(
'repository is invalid',
);
}
if (!options || typeof options !== 'object' || Array.isArray(options)) {
throw new ClusterControlApiCredentialConfigurationError(
'options are invalid',
);
}
const keys = Object.keys(options);
if (
keys.some(
(key) =>
key !== 'principalTtlMs' && key !== 'pepperKeyId' && key !== 'now',
)
) {
throw new ClusterControlApiCredentialConfigurationError(
'options shape is invalid',
);
}
if (options.now !== undefined && typeof options.now !== 'function') {
throw new ClusterControlApiCredentialConfigurationError('now is invalid');
}
const pepperKeyId =
options.pepperKeyId ?? LEGACY_API_CREDENTIAL_PEPPER_KEY_ID;
try {
assertApiCredentialPepperKeyId(pepperKeyId);
} catch {
throw new ClusterControlApiCredentialConfigurationError(
'pepperKeyId is invalid',
);
}
const pepper = decodeSecret('pepper', pepperBase64Url);
const ttlMs = principalTtl(options.principalTtlMs);
const now = options.now ?? Date.now;
return Object.freeze({
async authenticate(
metadata: ClusterControlAdmissionMetadata,
): Promise<Readonly<SecurityPrincipal> | null> {
const parsed = parseAuthorization(metadata);
if (!parsed) return null;
const presentedDigest = digest(
pepper,
parsed.credentialId,
parsed.secret,
);
parsed.secret.fill(0);
let candidate;
try {
candidate = await repository.resolve(parsed.credentialId);
} catch (error) {
presentedDigest.fill(0);
if (error instanceof ApiCredentialUnavailableError) {
throw new ClusterControlApiCredentialUnavailableError();
}
throw new ClusterControlApiCredentialUnavailableError();
}
if (metadata.signal.aborted) {
presentedDigest.fill(0);
throw new ClusterControlApiCredentialUnavailableError();
}
let record;
try {
record = candidate ? normalizeApiCredentialRecord(candidate) : null;
} catch {
presentedDigest.fill(0);
throw new ClusterControlApiCredentialUnavailableError();
}
if (record && record.pepperKeyId !== pepperKeyId) {
presentedDigest.fill(0);
throw new ClusterControlApiCredentialUnavailableError();
}
const storedDigest = record
? Buffer.from(record.secretDigest, 'hex')
: Buffer.alloc(32);
const matches = timingSafeEqual(presentedDigest, storedDigest);
presentedDigest.fill(0);
storedDigest.fill(0);
if (!record || !matches) return null;
const nowMs = now();
if (
!Number.isSafeInteger(nowMs) ||
nowMs < 0 ||
record.state !== 'active' ||
record.subjectStatus !== 'active' ||
record.notBeforeAtMs > nowMs ||
record.expiresAtMs <= nowMs
) {
return null;
}
const expiresAtMs = Math.min(record.expiresAtMs, nowMs + ttlMs);
try {
return normalizeSecurityPrincipal(
{
subject: record.subject,
authenticationId: `api_credential:${record.credentialId}:${record.version}`,
authenticatedAtMs: nowMs,
expiresAtMs,
assurance:
record.subject.type === 'user' ? 'single_factor' : 'service',
},
nowMs,
);
} catch {
throw new ClusterControlApiCredentialUnavailableError();
}
},
});
}
@@ -0,0 +1,244 @@
// Authentication owns its bounded pre-body overload shield.
import { createHmac, randomBytes } from 'node:crypto';
import { performance } from 'node:perf_hooks';
export interface ClusterControlAuthenticationShieldOptions {
readonly windowMs: number;
readonly maxRequestsPerPeer: number;
readonly maxRequestsGlobal: number;
readonly maxTrackedPeers: number;
readonly now?: () => number;
}
export type ClusterControlAuthenticationShieldRejectionReason =
| 'capacity'
| 'clock'
| 'global'
| 'peer';
export type ClusterControlAuthenticationShieldResult =
| {
readonly allowed: true;
/**
* Returns this provisional attempt budget after the pre-body admission
* preflight has succeeded. Idempotent and scoped to the exact windows
* consumed by this result.
*/
refund(): void;
}
| {
readonly allowed: false;
readonly reason: ClusterControlAuthenticationShieldRejectionReason;
readonly retryAfterMs: number;
};
export interface ClusterControlAuthenticationShield {
consume(
peerAddress: string | undefined,
): ClusterControlAuthenticationShieldResult;
close(): void;
}
interface PeerWindow {
readonly startedAt: number;
readonly count: number;
}
const FINGERPRINT_KEY_BYTES = 32;
const MAX_PEER_ADDRESS_BYTES = 128;
const MAX_PRUNE_PER_ATTEMPT = 64;
const UNKNOWN_PEER = '<unknown-transport-peer>';
function normalizedPeerAddress(peerAddress: string | undefined): string {
if (
typeof peerAddress !== 'string' ||
peerAddress.length === 0 ||
Buffer.byteLength(peerAddress) > MAX_PEER_ADDRESS_BYTES ||
/[\0\r\n]/.test(peerAddress)
) {
return UNKNOWN_PEER;
}
return peerAddress;
}
function remainingWindow(
now: number,
startedAt: number,
windowMs: number,
): number {
return Math.max(1, Math.ceil(windowMs - (now - startedAt)));
}
/**
* Creates a process-local overload shield for authentication attempts. It is
* deliberately not an authorization or distributed quota authority: every
* cluster-control replica owns a bounded, disposable window.
*/
export function createClusterControlAuthenticationShield(
options: ClusterControlAuthenticationShieldOptions,
): ClusterControlAuthenticationShield {
const now = options.now ?? (() => performance.now());
const fingerprintKey = randomBytes(FINGERPRINT_KEY_BYTES);
const peers = new Map<string, PeerWindow>();
let globalWindow: PeerWindow | undefined;
let lastNow = 0;
let closed = false;
const fingerprint = (peerAddress: string | undefined): string =>
createHmac('sha256', fingerprintKey)
.update('qinglong.cluster-control.authentication-peer\0')
.update(normalizedPeerAddress(peerAddress))
.digest('base64url');
const pruneExpired = (currentTime: number): void => {
let scanned = 0;
for (const [key, window] of peers) {
if (scanned >= MAX_PRUNE_PER_ATTEMPT) return;
scanned += 1;
if (currentTime - window.startedAt >= options.windowMs) {
peers.delete(key);
}
}
};
const accepted = (
peer: string,
peerStartedAt: number,
globalStartedAt: number,
): ClusterControlAuthenticationShieldResult => {
let completed = false;
return Object.freeze({
allowed: true as const,
refund() {
if (completed || closed) return;
completed = true;
if (
globalWindow?.startedAt === globalStartedAt &&
globalWindow.count > 0
) {
globalWindow = {
startedAt: globalWindow.startedAt,
count: globalWindow.count - 1,
};
}
const currentPeerWindow = peers.get(peer);
if (
currentPeerWindow?.startedAt === peerStartedAt &&
currentPeerWindow.count > 0
) {
if (currentPeerWindow.count === 1) peers.delete(peer);
else {
peers.set(peer, {
startedAt: currentPeerWindow.startedAt,
count: currentPeerWindow.count - 1,
});
}
}
},
});
};
return {
consume(peerAddress) {
if (closed) {
return Object.freeze({
allowed: false,
reason: 'clock',
retryAfterMs: options.windowMs,
});
}
let currentTime: number;
try {
currentTime = now();
} catch {
return Object.freeze({
allowed: false,
reason: 'clock',
retryAfterMs: options.windowMs,
});
}
if (
!Number.isFinite(currentTime) ||
currentTime < 0 ||
currentTime < lastNow
) {
return Object.freeze({
allowed: false,
reason: 'clock',
retryAfterMs: options.windowMs,
});
}
lastNow = currentTime;
if (
!globalWindow ||
currentTime - globalWindow.startedAt >= options.windowMs
) {
globalWindow = { startedAt: currentTime, count: 0 };
}
if (globalWindow.count >= options.maxRequestsGlobal) {
return Object.freeze({
allowed: false,
reason: 'global',
retryAfterMs: remainingWindow(
currentTime,
globalWindow.startedAt,
options.windowMs,
),
});
}
globalWindow = {
startedAt: globalWindow.startedAt,
count: globalWindow.count + 1,
};
const peer = fingerprint(peerAddress);
let peerWindow = peers.get(peer);
if (
peerWindow &&
currentTime - peerWindow.startedAt >= options.windowMs
) {
peers.delete(peer);
peerWindow = undefined;
}
if (peerWindow) {
if (peerWindow.count >= options.maxRequestsPerPeer) {
return Object.freeze({
allowed: false,
reason: 'peer',
retryAfterMs: remainingWindow(
currentTime,
peerWindow.startedAt,
options.windowMs,
),
});
}
peers.delete(peer);
peers.set(peer, {
startedAt: peerWindow.startedAt,
count: peerWindow.count + 1,
});
return accepted(peer, peerWindow.startedAt, globalWindow.startedAt);
}
if (peers.size >= options.maxTrackedPeers) pruneExpired(currentTime);
if (peers.size >= options.maxTrackedPeers) {
return Object.freeze({
allowed: false,
reason: 'capacity',
retryAfterMs: options.windowMs,
});
}
peers.set(peer, { startedAt: currentTime, count: 1 });
return accepted(peer, currentTime, globalWindow.startedAt);
},
close() {
if (closed) return;
closed = true;
peers.clear();
globalWindow = undefined;
fingerprintKey.fill(0);
},
};
}