fix(fleet): contain credential trust roots
AMD1213-B4: reject symlinked auth ancestry and group/world-readable credential artifacts before composition can write.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
chmodSync,
|
||||
lstatSync,
|
||||
mkdirSync,
|
||||
mkdtempSync,
|
||||
@@ -319,7 +320,41 @@ describe('A3 credential validation', () => {
|
||||
).toThrowError(/real, non-symlink credential file/);
|
||||
});
|
||||
|
||||
it('accepts a real credential file contained in the harness auth root', () => {
|
||||
it('refuses an auth ancestor symlink that relocates the credential trust root', () => {
|
||||
const fx = fixture();
|
||||
rmSync(join(fx.userHome, 'auth'), { recursive: true, force: true });
|
||||
const outsideAuth = join(fx.root, 'outside-auth');
|
||||
const outsideBundle = join(outsideAuth, 'claude', 'fred_example.com');
|
||||
mkdirSync(outsideBundle, { recursive: true });
|
||||
writeFileSync(join(outsideBundle, '.credentials.json'), '{}\n', { mode: 0o600 });
|
||||
writeFileSync(
|
||||
join(outsideBundle, 'account.json'),
|
||||
'{"oauthAccount":{"emailAddress":"[email protected]"}}\n',
|
||||
);
|
||||
symlinkSync('fred_example.com', join(outsideAuth, 'claude', 'primary'), 'dir');
|
||||
symlinkSync(outsideAuth, join(fx.userHome, 'auth'), 'dir');
|
||||
|
||||
expect(() =>
|
||||
resolveFleetLaunchComposition('fred', {
|
||||
systemHome: fx.systemHome,
|
||||
userHome: fx.userHome,
|
||||
}),
|
||||
).toThrowError(/auth directory must be a real, non-symlink directory/);
|
||||
});
|
||||
|
||||
it('refuses a group- or world-readable credential file', () => {
|
||||
const fx = fixture();
|
||||
chmodSync(join(fx.namedBundleDir, '.credentials.json'), 0o644);
|
||||
|
||||
expect(() =>
|
||||
resolveFleetLaunchComposition('fred', {
|
||||
systemHome: fx.systemHome,
|
||||
userHome: fx.userHome,
|
||||
}),
|
||||
).toThrowError(/credential file must not grant group or other permissions/);
|
||||
});
|
||||
|
||||
it('accepts a real private credential file contained in the harness auth root', () => {
|
||||
const fx = fixture();
|
||||
const plan = resolveFleetLaunchComposition('fred', {
|
||||
systemHome: fx.systemHome,
|
||||
|
||||
Reference in New Issue
Block a user