feat(ql3): prove security administration custody live

This commit is contained in:
whyour
2026-08-25 09:15:40 +08:00
parent 2eb8b29e51
commit c6b9e1504c
14 changed files with 2391 additions and 10 deletions
@@ -48,6 +48,26 @@ test('rejects Kubernetes API token authority in the administration Job', () => {
);
});
test('rejects recursive fsGroup rewrites of persistent credential custody', () => {
const report = auditSecurityAdministrationKubernetes({
root: ROOT,
readFile: intercept(
'deploy/kubernetes/ql3-cluster/operations/security-administration/base/job.yaml',
(value) => value.replace(
'fsGroupChangePolicy: OnRootMismatch',
'fsGroupChangePolicy: Always',
),
),
});
assert.equal(report.compatible, false);
assert.ok(
report.findings.some(
({ code }) => code === 'QL3_SECURITY_ADMIN_KUBERNETES_JOB_BOUNDARY_INVALID',
),
);
});
test('rejects a non-persistent credential delivery boundary', () => {
const report = auditSecurityAdministrationKubernetes({
root: ROOT,
@@ -0,0 +1,175 @@
const assert = require('node:assert/strict');
const { test } = require('node:test');
const {
FIXTURE,
LIMITATIONS,
validateSecurityAdministrationKubernetesLiveReport,
} = require('../../scripts/ql3-security-administration-kubernetes-live-audit.cjs');
const digest = (value) => `sha256:${value.repeat(64)}`;
function report() {
return {
schemaVersion: 1,
fixture: FIXTURE,
observedAt: '2026-08-25T04:00:00.000Z',
platform: {
distribution: 'k3s',
kubernetesVersion: 'v1.34.3+k3s1',
architecture: 'amd64',
kubernetesImageId: digest('1'),
administrationImageId: digest('2'),
cniName: 'flannel',
cniDistributionBinding: 'rancher/k3s:v1.34.3-k3s1',
controlPlaneNodes: 1,
workerNodes: 2,
readyNodes: 3,
},
database: {
operator: 'cloudnative-pg',
operatorVersion: '1.30.0',
postgresVersionNumber: 180004,
postgresImageId: digest('3'),
instances: 3,
readyInstances: 3,
administrationRole: 'ql3_admin',
roleConnectionLimit: 4,
commandConnectionLimit: 1,
migrationCount: 71,
controlCoreCapability: 70,
tlsVerified: true,
leastPrivilege: true,
},
ceremony: {
operations: [
'identity.register',
'audit.list',
'credential.issue',
'credential.issue.replay',
'credential.rotate',
'credential.revoke',
],
completedJobs: 6,
failedJobs: 1,
callerDriven: true,
backoffLimit: 0,
activeDeadlineSeconds: 300,
ttlSecondsAfterFinished: 600,
serviceAccount: 'ql3-security-administration',
serviceAccountTokenMounted: false,
rbacGranted: false,
responseLossReplayObserved: true,
sensitiveMaterialReported: false,
},
inputBoundary: {
immutableSecret: true,
projectedMode0440: true,
memoryBackedPrivateStage: true,
targetDirectoryMode0700: true,
targetFilesMode0600: true,
kubeletAtomicWriterProjectionAccepted: true,
worldReadableProjectionRejected: true,
mainContainerNotStartedAfterStageFailure: true,
},
deliveryCustody: {
persistentVolumeClaim: true,
accessMode: 'ReadWriteOnce',
fixtureRootProvisioned: true,
fixtureRootMode: '2770',
fixtureProvisionerRanAsRoot: true,
privateDirectoryMode: '0700',
fileMode: '0600',
fileCount: 2,
issueDigest: digest('4'),
rotationDigest: digest('5'),
distinctRotationMaterial: true,
persistentAcrossJobs: true,
noReplaceReplayPreserved: true,
deliverySchemaValidated: true,
bearerFormatValidatedInPod: true,
sensitiveMaterialReported: false,
},
isolation: {
dnsAndDatabaseEgressAllowed: true,
kubernetesApiEgressDenied: true,
publicInternetEgressDenied: true,
secretReadRbacDenied: true,
jobMutationRbacDenied: true,
},
durability: {
identityVersion: 1,
identityStatus: 'active',
credentialVersion: 3,
credentialState: 'revoked',
identityMutationCount: 1,
credentialMutationCount: 3,
issueMutationCount: 1,
credentialVersionCount: 3,
allowedAuditCount: 4,
},
cleanup: {
jobsDeleted: true,
inputSecretsDeleted: true,
evidenceJobsDeleted: true,
storageProvisionJobDeleted: true,
deliveryVolumeClaimDeleted: true,
},
gates: {
realThreeNodeKubernetes: true,
realCloudNativePg: true,
realKubeletSecretProjection: true,
realAdministrationProductCommands: true,
realPersistentCredentialCustody: true,
responseLossReplay: true,
failedInputStageClosed: true,
leastPrivilege: true,
contentFreeEvidence: true,
passed: true,
},
limitations: [...LIMITATIONS],
};
}
test('accepts the exact content-free Security Administration live report', () => {
const result = validateSecurityAdministrationKubernetesLiveReport(report());
assert.equal(result.compatible, true);
assert.deepEqual(result.findings, []);
});
test('rejects widened authority, false custody and replay duplication', () => {
const candidate = report();
candidate.ceremony.serviceAccountTokenMounted = true;
candidate.deliveryCustody.noReplaceReplayPreserved = false;
candidate.durability.issueMutationCount = 2;
candidate.gates.passed = false;
const codes = validateSecurityAdministrationKubernetesLiveReport(
candidate,
).findings.map((finding) => finding.code);
assert.ok(
codes.includes('QL3_SECURITY_ADMINISTRATION_KUBERNETES_LIVE_CEREMONY'),
);
assert.ok(
codes.includes('QL3_SECURITY_ADMINISTRATION_KUBERNETES_LIVE_DELIVERY'),
);
assert.ok(
codes.includes('QL3_SECURITY_ADMINISTRATION_KUBERNETES_LIVE_DURABILITY'),
);
assert.ok(codes.includes('QL3_SECURITY_ADMINISTRATION_KUBERNETES_LIVE_GATES'));
});
test('rejects any credential or assertion material in evidence', () => {
const candidate = report();
candidate.deliveryCustody.proof = {
token: 'ql3c_example_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
};
const result = validateSecurityAdministrationKubernetesLiveReport(candidate);
assert.equal(result.compatible, false);
assert.ok(
result.findings.some(
(finding) =>
finding.code ===
'QL3_SECURITY_ADMINISTRATION_KUBERNETES_LIVE_MATERIAL_EXPOSURE',
),
);
});
@@ -0,0 +1,140 @@
const assert = require('node:assert/strict');
const { spawnSync } = require('node:child_process');
const fs = require('node:fs');
const path = require('node:path');
const { test } = require('node:test');
const {
auditListCommand,
credentialIssueCommand,
credentialRevokeCommand,
credentialRotateCommand,
custodyEvidenceSource,
deliveryVolumeProvisionSource,
identity,
identityRegisterCommand,
inputAuthorityEvidenceSource,
} = require('../../scripts/ql3-security-administration-kubernetes-live-contract.cjs');
const values = Object.freeze({
subject: Object.freeze({ type: 'api_app', id: 'd406-test-client' }),
credentialId: 'd406-test-client',
identityMutationId: '10000000-0000-4000-8000-000000000001',
issueMutationId: '10000000-0000-4000-8000-000000000002',
rotateMutationId: '10000000-0000-4000-8000-000000000003',
revokeMutationId: '10000000-0000-4000-8000-000000000004',
registerRequestId: 'd406-register-test',
issueRequestId: 'd406-issue-test',
rotateRequestId: 'd406-rotate-test',
revokeRequestId: 'd406-revoke-test',
notBeforeAtMs: 2_000_000_000_000,
expiresAtMs: 2_000_003_600_000,
});
test('requires a private report path before any Docker or Kubernetes mutation', () => {
const script = path.resolve(
__dirname,
'../../scripts/ql3-security-administration-kubernetes-live-contract.cjs',
);
const result = spawnSync(process.execPath, [script], {
encoding: 'utf8',
env: {
...process.env,
QL3_SECURITY_ADMINISTRATION_KUBERNETES_LIVE: '1',
},
});
assert.equal(result.status, 1);
assert.match(result.stderr, /--report=\/absolute\/private-report\.json/);
assert.doesNotMatch(result.stderr, /Docker\/Kubernetes/);
});
test('builds the exact register, audit, issue, rotate and revoke commands', () => {
assert.deepEqual(identityRegisterCommand(values), {
schemaVersion: 1,
operation: 'identity.register',
request: {
mutationId: values.identityMutationId,
requestId: values.registerRequestId,
expectedCurrentVersion: 0,
subject: values.subject,
},
});
assert.deepEqual(auditListCommand(), {
schemaVersion: 1,
operation: 'audit.list',
request: { limit: 25, filter: { outcome: 'allowed' } },
});
assert.equal(credentialIssueCommand(values).request.expectedCurrentVersion, 0);
assert.equal(credentialRotateCommand(values).request.expectedCurrentVersion, 1);
assert.equal(credentialRevokeCommand(values).request.expectedCurrentVersion, 2);
assert.equal('notBeforeAtMs' in credentialRevokeCommand(values).request, false);
});
test('binds the live assertion to the isolated Security Administration purpose', () => {
const key = identity.reviewedKey('security-administration-unit-key');
const document = identity.keyset(1, [key]);
assert.equal(document.audience, 'qinglong3-security-administration');
const assertion = identity.assertion(key, 'unit-test');
const header = JSON.parse(Buffer.from(assertion.split('.')[0], 'base64url'));
const payload = JSON.parse(Buffer.from(assertion.split('.')[1], 'base64url'));
assert.equal(header.typ, 'ql3-security-administration+jwt');
assert.equal(payload.ql3_purpose, 'security-administration');
assert.equal(payload.sub, 'security-owner');
assert.equal(payload.acr, 'urn:ql3:mfa');
assert.deepEqual(payload.amr, ['pwd', 'otp']);
});
test('keeps the in-Pod custody verifier content-free and fail-closed', () => {
const source = custodyEvidenceSource();
assert.match(source, /bytes\.fill\(0\)/);
assert.match(source, /kubernetesApiConnected/);
assert.match(source, /publicInternetConnected/);
assert.match(source, /status\.nlink!==1/);
assert.doesNotMatch(source, /value\.token[,}]/);
assert.doesNotMatch(source, /console\.log/);
});
test('inspects projected input authority without reading private material', () => {
const source = inputAuthorityEvidenceSource();
assert.match(source, /lstatSync/);
assert.match(source, /realpathSync/);
assert.match(source, /confined/);
assert.doesNotMatch(source, /readFile/);
assert.doesNotMatch(source, /createReadStream/);
});
test('constrains only the exact local-path fixture root without network authority', () => {
const source = deliveryVolumeProvisionSource();
assert.match(source, /before\.mode!==['"]2777['"]/);
assert.match(source, /chmodSync\(root,0o2770\)/);
assert.match(source, /after\.mode!==['"]2770['"]/);
assert.doesNotMatch(source, /child_process/);
assert.doesNotMatch(source, /net|fetch|http/);
});
test('live runner remains opt-in, reviewed, cleanup-bound and log-free', () => {
const source = fs.readFileSync(
path.resolve(
__dirname,
'../../scripts/ql3-security-administration-kubernetes-live-contract.cjs',
),
'utf8',
);
assert.match(
source,
/QL3_SECURITY_ADMINISTRATION_KUBERNETES_LIVE !== '1'/,
);
assert.match(source, /reviewedOperatorManifest\(operatorManifestFile\)/);
assert.match(source, /validateSecurityAdministrationKubernetesLiveReport/);
assert.match(source, /projectedMode: 0o444/);
assert.match(source, /credential\.issue\.replay/);
assert.match(source, /FallbackToLogsOnError/);
assert.match(source, /failureMessage: 'rejected'/);
assert.match(
source,
/deploy\/kubernetes\/ql3-cluster\/base\/service-account\.yaml/,
);
assert.match(source, /persistentvolumeclaim\/\$\{DELIVERY_CLAIM\}/);
assert.match(source, /await fixture\.cleanup\(\)/);
assert.doesNotMatch(source, /kubectl\([^)]*logs/);
});