| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- import test from 'node:test';
- import assert from 'node:assert/strict';
- import fs from 'node:fs';
- import os from 'node:os';
- import path from 'node:path';
- import crypto from 'node:crypto';
- import {fileURLToPath} from 'node:url';
- import {issue} from '../scripts/enterprise-auth/issue.mjs';
- import {exportRecipient} from '../scripts/enterprise-auth/export-recipient.mjs';
- import {install,validateDelivery} from '../scripts/enterprise-auth/install.mjs';
- import {decryptEnvelope} from '../scripts/enterprise-auth/decrypt-envelope.mjs';
- import {executeSecure} from '../skills/ksf-workshop-runtime/scripts/ksf-secure.mjs';
- import {APP,COMPANY,AGENT,HOST,SKILL,SCOPES,WRAPPER_SHA,sha,encode} from '../scripts/enterprise-auth/common.mjs';
- const ROOT=path.dirname(path.dirname(fileURLToPath(import.meta.url)));
- const pair=crypto.generateKeyPairSync('rsa',{modulusLength:3072});
- const recipient={schema:'ksf.enterprise-workshop-recipient.v1',publicOnly:true,companyObjectId:COMPANY,appId:APP,
- agentId:AGENT,host:HOST,keyDirectory:'/opt/data/ksf-key-receive-20261031-fixture',
- publicKeyPem:pair.publicKey.export({type:'spki',format:'pem'}),
- publicKeySha256:sha(pair.publicKey.export({type:'spki',format:'der'})),privateKeyExported:false,tokenExported:false};
- const write=(file,body)=>{fs.mkdirSync(path.dirname(file),{recursive:true,mode:0o700});fs.writeFileSync(file,body,{mode:0o600});};
- function fixture(t){
- const base=fs.mkdtempSync(path.join(os.tmpdir(),'ksf-auth-test-'));
- t.after(()=>fs.rmSync(base,{recursive:true,force:true}));
- const recipientFile=path.join(base,'recipient.json');write(recipientFile,encode(recipient));
- return{base,recipientFile,output:path.join(base,'private-issuance')};
- }
- function fakeApi(f,options={}){
- let row,token;const writes=[],calls=[];
- return{
- writes,calls,get row(){return row;},get token(){return token;},
- request:async(method,route,body)=>{
- calls.push([method,route]);
- assert.ok(route.startsWith('/classes/KsfServiceCredential'),'no business classes written');
- if(method==='GET')return route.includes('?')?{results:row?[structuredClone(row)]:[]}:structuredClone(row);
- writes.push([method,structuredClone(body)]);
- if(method==='POST'){assert.equal(body.enabled,false);row={...structuredClone(body),objectId:'newCred123'};return{objectId:row.objectId};}
- if(method==='PUT'){
- assert.ok(fs.existsSync(path.join(f.output,'delivery/FILES.sha256')),'encrypted delivery exists before enable');
- if(options.failEnable)throw Object.assign(Error(),{code:'ENABLE_UNCERTAIN'});
- Object.assign(row,body);return{updatedAt:'2026-11-10T00:00:00.000Z'};
- }
- throw Error('unexpected request');
- },
- invoke:async(name,params,headers)=>{
- const candidate=headers['X-Ksf-Service-Token'];
- if(!candidate||candidate.startsWith('invalid-control-'))return{http:401,body:{result:{ok:false,errors:[{code:'AUTH_REQUIRED'}]}}};
- token=headers['X-Ksf-Service-Token'];assert.equal(sha(token),row.tokenHash);assert.ok(row.enabled);
- assert.deepEqual(Object.keys(headers).sort(),['Content-Type','X-Ksf-Service-Token','X-Parse-Application-Id'].sort());
- if(name==='ksfGetIngestContract')return{http:200,body:{result:{ok:true,data:{workshop:{version:'ksf.workshop.v1'}}}}};
- assert.equal(name,'ksfGetRecord');assert.equal(params.className,'KfSource');
- return{http:400,body:{result:{ok:false,errors:[{code:'REFERENCE_NOT_FOUND'}]}}};
- }
- };
- }
- function target(f){
- const dataDir=path.join(f.base,'target');
- write(path.join(dataDir,'.fmode/config/enterprise/current.json'),encode({companyObjectId:COMPANY,appId:APP,provisionStatus:'success'}));
- const skill=path.join(dataDir,'skills/ksf-workshop-runtime');
- for(const n of ['SKILL.md','scripts/ksf-secure.mjs'])write(path.join(skill,n),fs.readFileSync(path.join(ROOT,'skills/ksf-workshop-runtime',n)));
- write(path.join(dataDir,path.posix.basename(recipient.keyDirectory),'recipient-private.pem'),pair.privateKey.export({type:'pkcs8',format:'pem'}));
- return{dataDir,skill,hostname:HOST,platform:'linux'};
- }
- const contractChild=()=>({status:0,stdout:JSON.stringify({ok:true,wrapperSha256:WRAPPER_SHA,credentialLoadedForChild:true,
- credentialWrittenToDisk:false,entryResult:{readOnly:true,result:{workshop:{version:'ksf.workshop.v1'}}}}),stderr:''});
- test('plan neither creates a service credential nor writes an output directory',async t=>{
- const f=fixture(t),api=fakeApi(f),result=await issue({...f,apply:false},api);
- assert.equal(result.planOnly,true);assert.deepEqual(result.scopes,SCOPES);
- assert.equal(fs.existsSync(f.output),false);assert.equal(api.writes.length,0);
- });
- test('fresh issuance enables only a recoverable encrypted credential; no plaintext is persisted',async t=>{
- const f=fixture(t),api=fakeApi(f),result=await issue({...f,apply:true},api);
- assert.equal(result.credentialId,'newCred123');assert.equal(result.authorizationRecordWrites,2);
- assert.deepEqual(api.row.scopes,['data:read','source:write','ingest:write']);
- assert.equal(api.row.scopes.includes('*'),false);assert.equal(api.row.scopes.includes('data:read-all'),false);
- const delivery=validateDelivery(result.deliveryDirectory,result.bundleManifestSha256);
- const payload=decryptEnvelope(delivery.envelope,pair.privateKey,{host:HOST,directory:recipient.keyDirectory,publicKeySha256:recipient.publicKeySha256});
- assert.equal(payload.credentialId,api.row.objectId);assert.equal(payload.env.KSF_SERVICE_TOKEN,api.token);
- for(const item of fs.readdirSync(f.output,{recursive:true,withFileTypes:true})){
- if(item.isFile()){
- const raw=fs.readFileSync(path.join(item.parentPath,item.name));
- assert.equal(raw.includes(Buffer.from(api.token)),false);assert.equal(raw.includes(Buffer.from('-----BEGIN PRIVATE KEY-----')),false);
- }
- }
- assert.equal(JSON.stringify(result).includes(api.token),false);
- });
- test('repeated issuance returns the same ID with no second create or rotation',async t=>{
- const f=fixture(t),api=fakeApi(f);const first=await issue({...f,apply:true},api);
- const second=await issue({...f,apply:true},api);
- assert.equal(second.credentialId,first.credentialId);assert.equal(second.alreadyIssued,true);assert.equal(api.writes.length,2);
- });
- test('interrupted enable leaves an encrypted recoverable delivery and stops an ambiguous replay',async t=>{
- const f=fixture(t),api=fakeApi(f,{failEnable:true});
- await assert.rejects(issue({...f,apply:true},api),{code:'ENABLE_UNCERTAIN'});
- assert.equal(api.row.enabled,false);assert.ok(fs.existsSync(path.join(f.output,'delivery/credential-envelope.json')));
- await assert.rejects(issue({...f,apply:true},api),{code:'INCOMPLETE_ISSUANCE_REQUIRES_RECONCILIATION'});
- assert.equal(api.writes.filter(x=>x[0]==='POST').length,1);
- });
- test('an existing server credential without its journal is not silently adopted',async t=>{
- const f=fixture(t),api=fakeApi(f);await issue({...f,apply:true},api);
- fs.renameSync(f.output,f.output+'-saved');
- await assert.rejects(issue({...f,apply:true},api),{code:'EXISTING_SERVICE_CREDENTIAL_REQUIRES_RECONCILIATION'});
- assert.equal(api.writes.length,2);
- });
- test('recipient host, enterprise app and public-key substitution fail before an API mutation',async t=>{
- for(const change of [{host:'043bb9231c09'},{appId:'FKieRbIoGtmain'},{publicKeySha256:'0'.repeat(64)}]){
- const f=fixture(t),api=fakeApi(f);write(f.recipientFile,encode({...recipient,...change}));
- await assert.rejects(issue({...f,apply:true},api));assert.equal(api.writes.length,0);assert.equal(api.calls.length,0);
- }
- });
- test('changed delivery manifest is rejected even when its file names remain plausible',async t=>{
- const f=fixture(t),api=fakeApi(f),r=await issue({...f,apply:true},api);
- write(path.join(r.deliveryDirectory,'credential-envelope.json'),Buffer.from('{}\n'));
- await assert.rejects(issue({...f,apply:true},api),{code:'DELIVERY_FILE_MISMATCH'});
- assert.throws(()=>validateDelivery(r.deliveryDirectory,r.bundleManifestSha256),{code:'DELIVERY_FILE_MISMATCH'});
- });
- test('recipient public export uses the target own key and repeats without changing it',t=>{
- const f=fixture(t),deps=target(f),output=path.join(deps.dataDir,'public/recipient.json');
- exportRecipient({keyDirectory:recipient.keyDirectory,output},deps);
- const first=fs.readFileSync(output);exportRecipient({output},deps);assert.deepEqual(fs.readFileSync(output),first);
- assert.equal(JSON.parse(first).publicKeySha256,recipient.publicKeySha256);assert.equal(first.includes(Buffer.from('PRIVATE KEY')),false);
- });
- test('recipient export can generate its own key without using another agent identity',t=>{
- const f=fixture(t),deps=target(f),output=path.join(deps.dataDir,'public/new.json');
- exportRecipient({output},deps);const r=JSON.parse(fs.readFileSync(output));
- assert.notEqual(r.publicKeySha256,recipient.publicKeySha256);
- assert.ok(fs.existsSync(path.join(deps.dataDir,path.posix.basename(r.keyDirectory),'recipient-private.pem')));
- });
- test('target install plan decrypts successfully without writing the binding',async t=>{
- const f=fixture(t),api=fakeApi(f),r=await issue({...f,apply:true},api),deps=target(f);
- const result=await install({bundle:r.deliveryDirectory,manifestSha:r.bundleManifestSha256},deps);
- assert.equal(result.planOnly,true);assert.equal(fs.existsSync(path.join(deps.skill,'credential-binding.json')),false);
- });
- test('installation preserves the frozen wrapper, exercises it and permits identical replay',async t=>{
- const f=fixture(t),api=fakeApi(f),r=await issue({...f,apply:true},api),deps=target(f);let calls=0;
- const run={...deps,spawn:(node,argv)=>{calls++;assert.equal(argv[1],'workshop-contract');return contractChild();},
- controls:async env=>{assert.equal(env.KSF_SERVICE_TOKEN,api.token);return[{identity:'test-fixture',http:400}];}};
- const options={bundle:r.deliveryDirectory,manifestSha:r.bundleManifestSha256,apply:true};
- const first=await install(options,run),second=await install(options,run);
- assert.equal(first.workshopContractVerified,true);assert.equal(second.alreadyBound,true);assert.equal(calls,2);
- assert.equal(sha(fs.readFileSync(path.join(deps.skill,'scripts/ksf-secure.mjs'))),WRAPPER_SHA);
- assert.equal(first.saveReadbackVerified,false);
- });
- test('unknown binding or wrong container cannot be overwritten by the installer',async t=>{
- const f=fixture(t),api=fakeApi(f),r=await issue({...f,apply:true},api),deps=target(f);
- const o={bundle:r.deliveryDirectory,manifestSha:r.bundleManifestSha256,apply:true};
- await assert.rejects(install(o,{...deps,hostname:'043bb9231c09'}),{code:'WRONG_CONTAINER'});
- write(path.join(deps.skill,'credential-binding.json'),Buffer.from('{"keep":"existing"}'));
- await assert.rejects(install(o,deps),{code:'EXISTING_BINDING_CHANGED'});
- assert.equal(fs.existsSync(path.join(deps.dataDir,'ksf-enterprise-auth-'+r.credentialId)),false);
- });
- test('installer rejects a different private key before installing a binding',async t=>{
- const f=fixture(t),api=fakeApi(f),r=await issue({...f,apply:true},api),deps=target(f);
- const other=crypto.generateKeyPairSync('rsa',{modulusLength:3072});
- write(path.join(deps.dataDir,path.posix.basename(recipient.keyDirectory),'recipient-private.pem'),other.privateKey.export({type:'pkcs8',format:'pem'}));
- await assert.rejects(install({bundle:r.deliveryDirectory,manifestSha:r.bundleManifestSha256,apply:true},deps),{code:'KEY_FINGERPRINT_MISMATCH'});
- assert.equal(fs.existsSync(path.join(deps.skill,'credential-binding.json')),false);
- });
- test('failed live contract does not claim readiness and an identical install can resume',async t=>{
- const f=fixture(t),api=fakeApi(f),r=await issue({...f,apply:true},api),deps=target(f);
- const options={bundle:r.deliveryDirectory,manifestSha:r.bundleManifestSha256,apply:true};
- await assert.rejects(install(options,{...deps,spawn:()=>({status:1,stdout:'',stderr:'{}'})}),{code:'FROZEN_ENTRY_CONTRACT_FAILED'});
- const resumed=await install(options,{...deps,spawn:contractChild,controls:async()=>[]});
- assert.equal(resumed.alreadyBound,true);assert.equal(resumed.workshopContractVerified,true);
- });
- test('the frozen secure wrapper decrypts the newly issued envelope and passes token only to its child',async t=>{
- const f=fixture(t),api=fakeApi(f),r=await issue({...f,apply:true},api);
- const delivery=validateDelivery(r.deliveryDirectory,r.bundleManifestSha256),argv=['workshop-contract','--input','/opt/data/input.json','--request-id','test-new-agent'];
- const skillDir=path.join(ROOT,'skills/ksf-workshop-runtime');
- const entry=path.join(skillDir,'scripts/ksf-workshop.mjs'),entryHash=sha(fs.readFileSync(entry));
- let childToken;
- const result=await executeSecure(argv,{skillDir,hostname:HOST,readPrivateKey:()=>pair.privateKey,
- readBytes:file=>{
- if(path.basename(file)==='credential-binding.json')return delivery.files['credential-binding.json'];
- if(file===delivery.binding.envelopeFile)return delivery.files['credential-envelope.json'];
- if(file===delivery.binding.decryptModule)return delivery.files['decrypt-envelope.mjs'];
- return fs.readFileSync(file);
- },importDecrypt:async()=>({decryptEnvelope}),spawn:(node,args,options)=>{
- childToken=options.env.KSF_SERVICE_TOKEN;
- return{status:0,stdout:JSON.stringify({skill:'ksf-workshop-runtime',entry,entrySha256:entryHash,command:'workshop-contract',
- invocationId:crypto.randomUUID(),requestId:'test-new-agent',ok:true}),stderr:''};
- }});
- assert.equal(childToken,api.token);assert.equal(result.credentialWrittenToDisk,false);assert.equal(JSON.stringify(result).includes(api.token),false);
- });
|