feat(ql3): cut alpha.1 candidate milestone

This commit is contained in:
whyour
2026-08-26 01:41:20 +08:00
parent c2df0c7215
commit 07cdc76bae
94 changed files with 1469 additions and 168 deletions
@@ -13,6 +13,7 @@ const {
const NOW = 10_000;
const PEPPER = Buffer.alloc(32, 1).toString('base64url');
const NEXT_PEPPER = Buffer.alloc(32, 3).toString('base64url');
const SECRET = Buffer.alloc(32, 2).toString('base64url');
const CREDENTIAL_ID = 'app_primary';
@@ -86,6 +87,53 @@ test('derives a domain-separated HMAC digest and user assurance', async () => {
assert.equal(principal.assurance, 'single_factor');
});
test('authenticates overlap generations by exact stored key id without fallback', async () => {
const keyring = {
schemaVersion: 1,
activePepperKeyId: 'rotation-2026-08',
keys: [
{ pepperKeyId: 'legacy-v1', pepper: PEPPER },
{ pepperKeyId: 'rotation-2026-08', pepper: NEXT_PEPPER },
],
};
const records = new Map([
[
'legacy',
credential({
credentialId: 'legacy',
secretDigest: apiCredentialSecretDigest(PEPPER, 'legacy', SECRET),
}),
],
[
'next',
credential({
credentialId: 'next',
pepperKeyId: 'rotation-2026-08',
secretDigest: apiCredentialSecretDigest(
NEXT_PEPPER,
'next',
SECRET,
),
}),
],
['unknown', credential({ credentialId: 'unknown', pepperKeyId: 'missing' })],
]);
const verifier = createClusterControlApiCredentialAuthenticator(
{ async resolve(credentialId) { return records.get(credentialId) ?? null; } },
keyring,
{ now: () => NOW },
);
const request = (credentialId) =>
metadata(`Bearer ql3c_${credentialId}_${SECRET}`);
assert.equal((await verifier.authenticate(request('legacy'))).subject.id, 'app_primary');
assert.equal((await verifier.authenticate(request('next'))).subject.id, 'app_primary');
await assert.rejects(
verifier.authenticate(request('unknown')),
ClusterControlApiCredentialUnavailableError,
);
});
test('rejects missing, malformed, wrong, inactive and disabled credentials', async () => {
let repositoryCalls = 0;
const strict = createClusterControlApiCredentialAuthenticator(
@@ -1,4 +1,6 @@
const assert = require('node:assert/strict');
const fs = require('node:fs');
const os = require('node:os');
const path = require('node:path');
const { test } = require('node:test');
const {
@@ -112,7 +114,16 @@ test('builds an exact runtime-only TLS-verified Pool configuration', async () =>
},
});
assert.deepEqual(config.security, {
apiCredentialPepper: BASE_ENV.QL3_API_CREDENTIAL_PEPPER,
apiCredentialPepperKeyring: {
schemaVersion: 1,
activePepperKeyId: 'legacy-v1',
keys: [
{
pepperKeyId: 'legacy-v1',
pepper: BASE_ENV.QL3_API_CREDENTIAL_PEPPER,
},
],
},
});
assert.deepEqual(config.logRetention, {
enabled: true,
@@ -133,6 +144,50 @@ test('builds an exact runtime-only TLS-verified Pool configuration', async () =>
await database.close();
});
test('loads an exact private dual-generation pepper keyring file', (context) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'ql3-keyring-'));
context.after(() => fs.rmSync(directory, { recursive: true, force: true }));
fs.chmodSync(directory, 0o700);
const keyringFile = path.join(directory, 'api-credential-keyring.json');
const nextPepper = Buffer.alloc(32, 2).toString('base64url');
fs.writeFileSync(
keyringFile,
JSON.stringify({
schemaVersion: 1,
activePepperKeyId: 'rotation-2026-08',
keys: [
{ pepperKeyId: 'legacy-v1', pepper: 'A'.repeat(43) },
{ pepperKeyId: 'rotation-2026-08', pepper: nextPepper },
],
}),
{ mode: 0o600 },
);
const environment = {
...BASE_ENV,
QL3_API_CREDENTIAL_PEPPER: undefined,
QL3_API_CREDENTIAL_PEPPER_KEYRING_FILE: keyringFile,
};
assert.equal(
loadClusterControlConfig(environment).security.apiCredentialPepperKeyring
.activePepperKeyId,
'rotation-2026-08',
);
assert.throws(
() =>
loadClusterControlConfig({
...environment,
QL3_API_CREDENTIAL_PEPPER: 'A'.repeat(43),
}),
/exactly one API credential pepper source/,
);
fs.chmodSync(keyringFile, 0o622);
assert.throws(
() => loadClusterControlConfig(environment),
/file authority is invalid/,
);
});
test('loads discrete operator-managed runtime credentials without a DSN copy', () => {
const {
QL3_POSTGRES_RUNTIME_URL: _connectionString,