mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
feat(ql3): cut alpha.1 candidate milestone
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user