@modelprofile.com/authswitch 6.3.0 → 6.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/authority-contract.d.ts +142 -0
- package/dist_ts/authority-contract.js +3 -0
- package/dist_ts/authority-runtime-contract.d.ts +32 -0
- package/dist_ts/authority-runtime-contract.js +2 -0
- package/dist_ts/classes.authoritybroker.d.ts +73 -0
- package/dist_ts/classes.authoritybroker.js +548 -0
- package/dist_ts/classes.authorityclient.d.ts +34 -0
- package/dist_ts/classes.authorityclient.js +200 -0
- package/dist_ts/classes.authoritydaemon.d.ts +26 -0
- package/dist_ts/classes.authoritydaemon.js +249 -0
- package/dist_ts/classes.authoritydatabase.d.ts +94 -0
- package/dist_ts/classes.authoritydatabase.js +736 -0
- package/dist_ts/classes.authorityframing.d.ts +8 -0
- package/dist_ts/classes.authorityframing.js +22 -0
- package/dist_ts/classes.authoritymodels.d.ts +215 -0
- package/dist_ts/classes.authoritymodels.js +818 -0
- package/dist_ts/classes.authoritysecrets.d.ts +9 -0
- package/dist_ts/classes.authoritysecrets.js +30 -0
- package/dist_ts/classes.authorityservice.d.ts +28 -0
- package/dist_ts/classes.authorityservice.js +71 -0
- package/dist_ts/index.d.ts +2 -0
- package/dist_ts/index.js +26 -1
- package/dist_ts/plugins.d.ts +9 -2
- package/dist_ts/plugins.js +10 -3
- package/package.json +17 -3
- package/readme.md +34 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/authority-contract.ts +109 -0
- package/ts/authority-runtime-contract.ts +27 -0
- package/ts/classes.authoritybroker.ts +530 -0
- package/ts/classes.authorityclient.ts +183 -0
- package/ts/classes.authoritydaemon.ts +219 -0
- package/ts/classes.authoritydatabase.ts +725 -0
- package/ts/classes.authorityframing.ts +21 -0
- package/ts/classes.authoritymodels.ts +367 -0
- package/ts/classes.authoritysecrets.ts +27 -0
- package/ts/classes.authorityservice.ts +83 -0
- package/ts/index.ts +25 -0
- package/ts/plugins.ts +9 -2
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface IAuthSwitchSecretCodec {
|
|
2
|
+
seal(accountId: string, plaintext: Uint8Array): Promise<string>;
|
|
3
|
+
unseal(accountId: string, ciphertext: string): Promise<Uint8Array>;
|
|
4
|
+
}
|
|
5
|
+
/** TPM-sealed byte payloads live only as ciphertext in SmartData. */
|
|
6
|
+
export declare class AuthSwitchTpmSecretCodec implements IAuthSwitchSecretCodec {
|
|
7
|
+
seal(accountId: string, plaintext: Uint8Array): Promise<string>;
|
|
8
|
+
unseal(accountId: string, ciphertext: string): Promise<Uint8Array>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
const secretName = (accountId) => {
|
|
3
|
+
if (!/^[a-f0-9]{64}$/.test(accountId))
|
|
4
|
+
throw new Error('Invalid account identity for secret custody.');
|
|
5
|
+
return `authswitch.account.${accountId}`;
|
|
6
|
+
};
|
|
7
|
+
/** TPM-sealed byte payloads live only as ciphertext in SmartData. */
|
|
8
|
+
export class AuthSwitchTpmSecretCodec {
|
|
9
|
+
async seal(accountId, plaintext) {
|
|
10
|
+
const ciphertext = await plugins.smartsecret.sealSmartSecretTpm2Credential(secretName(accountId), plaintext);
|
|
11
|
+
try {
|
|
12
|
+
return Buffer.from(ciphertext).toString('base64url');
|
|
13
|
+
}
|
|
14
|
+
finally {
|
|
15
|
+
ciphertext.fill(0);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
async unseal(accountId, ciphertext) {
|
|
19
|
+
if (!/^[A-Za-z0-9_-]{1,131072}$/.test(ciphertext))
|
|
20
|
+
throw new Error('Invalid sealed account credential.');
|
|
21
|
+
const bytes = Buffer.from(ciphertext, 'base64url');
|
|
22
|
+
try {
|
|
23
|
+
return await plugins.smartsecret.unsealSmartSecretTpm2Credential(secretName(accountId), bytes);
|
|
24
|
+
}
|
|
25
|
+
finally {
|
|
26
|
+
bytes.fill(0);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5hdXRob3JpdHlzZWNyZXRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2xhc3Nlcy5hdXRob3JpdHlzZWNyZXRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBT3hDLE1BQU0sVUFBVSxHQUFHLENBQUMsU0FBaUIsRUFBVSxFQUFFO0lBQy9DLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO1FBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyw4Q0FBOEMsQ0FBQyxDQUFDO0lBQ3ZHLE9BQU8sc0JBQXNCLFNBQVMsRUFBRSxDQUFDO0FBQzNDLENBQUMsQ0FBQztBQUVGLHFFQUFxRTtBQUNyRSxNQUFNLE9BQU8sd0JBQXdCO0lBQzVCLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBaUIsRUFBRSxTQUFxQjtRQUN4RCxNQUFNLFVBQVUsR0FBRyxNQUFNLE9BQU8sQ0FBQyxXQUFXLENBQUMsNkJBQTZCLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQzdHLElBQUksQ0FBQztZQUFDLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUM7UUFBQyxDQUFDO2dCQUNyRCxDQUFDO1lBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUFDLENBQUM7SUFDakMsQ0FBQztJQUVNLEtBQUssQ0FBQyxNQUFNLENBQUMsU0FBaUIsRUFBRSxVQUFrQjtRQUN2RCxJQUFJLENBQUMsMkJBQTJCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQztZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsb0NBQW9DLENBQUMsQ0FBQztRQUN6RyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxXQUFXLENBQUMsQ0FBQztRQUNuRCxJQUFJLENBQUM7WUFBQyxPQUFPLE1BQU0sT0FBTyxDQUFDLFdBQVcsQ0FBQywrQkFBK0IsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFBQyxDQUFDO2dCQUMvRixDQUFDO1lBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUFDLENBQUM7SUFDNUIsQ0FBQztDQUNGIn0=
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
export interface IAuthSwitchAuthorityPaths {
|
|
3
|
+
runtimeDirectory: string;
|
|
4
|
+
dataDirectory: string;
|
|
5
|
+
databaseSocketPath: string;
|
|
6
|
+
authoritySocketPath: string;
|
|
7
|
+
runtimeSocketPath: string;
|
|
8
|
+
runtimeSocketDirectory: string;
|
|
9
|
+
}
|
|
10
|
+
/** Canonical per-user paths. An explicit runtime directory is also usable by a trusted container host. */
|
|
11
|
+
export declare const resolveAuthSwitchAuthorityPaths: (runtimeDirectory?: string | undefined) => IAuthSwitchAuthorityPaths;
|
|
12
|
+
/** Explicit installer and lifecycle operations for a user-scoped systemd service. */
|
|
13
|
+
export declare class AuthSwitchAuthorityService {
|
|
14
|
+
readonly unit: plugins.smartdaemon.SystemdUnit;
|
|
15
|
+
readonly unitFile: plugins.smartdaemon.SystemdUnitFile;
|
|
16
|
+
readonly definition: plugins.smartdaemon.SystemdServiceDefinition;
|
|
17
|
+
constructor(runtimeDirectory: string, unitDirectory?: string);
|
|
18
|
+
install(): Promise<Readonly<{
|
|
19
|
+
changed: boolean;
|
|
20
|
+
masked: boolean;
|
|
21
|
+
sha256: string;
|
|
22
|
+
}>>;
|
|
23
|
+
inspect(): Promise<plugins.smartdaemon.ISystemdUnitState>;
|
|
24
|
+
enable(): Promise<plugins.smartdaemon.ISystemdUnitState>;
|
|
25
|
+
start(): Promise<plugins.smartdaemon.ISystemdUnitState>;
|
|
26
|
+
stop(): Promise<plugins.smartdaemon.ISystemdUnitState>;
|
|
27
|
+
}
|
|
28
|
+
export declare const runAuthSwitchAuthorityDaemon: (paths?: IAuthSwitchAuthorityPaths) => Promise<void>;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import { AuthSwitchAuthorityDaemon } from './classes.authoritydaemon.js';
|
|
3
|
+
/** Canonical per-user paths. An explicit runtime directory is also usable by a trusted container host. */
|
|
4
|
+
export const resolveAuthSwitchAuthorityPaths = (runtimeDirectory = process.env.XDG_RUNTIME_DIR) => {
|
|
5
|
+
if (!runtimeDirectory || !plugins.path.isAbsolute(runtimeDirectory)) {
|
|
6
|
+
throw new Error('A private XDG_RUNTIME_DIR is required for authswitch authority.');
|
|
7
|
+
}
|
|
8
|
+
const home = plugins.os.userInfo().homedir;
|
|
9
|
+
const dataHome = process.env.XDG_DATA_HOME || plugins.path.join(home, '.local/share');
|
|
10
|
+
if (!plugins.path.isAbsolute(dataHome))
|
|
11
|
+
throw new Error('XDG_DATA_HOME must be an absolute path.');
|
|
12
|
+
const socketDirectory = plugins.path.join(runtimeDirectory, 'authswitch');
|
|
13
|
+
const runtimeSocketDirectory = plugins.path.join(socketDirectory, 'runtime');
|
|
14
|
+
return {
|
|
15
|
+
runtimeDirectory,
|
|
16
|
+
dataDirectory: plugins.path.join(dataHome, 'authswitch', 'authority'),
|
|
17
|
+
databaseSocketPath: plugins.path.join(socketDirectory, 'internal', 'db.sock'),
|
|
18
|
+
authoritySocketPath: plugins.path.join(socketDirectory, 'management', 'authority.sock'),
|
|
19
|
+
runtimeSocketPath: plugins.path.join(runtimeSocketDirectory, 'runtime.sock'),
|
|
20
|
+
runtimeSocketDirectory,
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
/** Explicit installer and lifecycle operations for a user-scoped systemd service. */
|
|
24
|
+
export class AuthSwitchAuthorityService {
|
|
25
|
+
unit;
|
|
26
|
+
unitFile;
|
|
27
|
+
definition;
|
|
28
|
+
constructor(runtimeDirectory, unitDirectory) {
|
|
29
|
+
const packageRoot = plugins.path.dirname(plugins.path.dirname(plugins.fileURLToPath(import.meta.url)));
|
|
30
|
+
const options = { unitName: 'authswitch-authority.service', scope: 'user', runtimeDirectory };
|
|
31
|
+
this.unit = new plugins.smartdaemon.SystemdUnit(options);
|
|
32
|
+
this.unitFile = new plugins.smartdaemon.SystemdUnitFile({ ...options, unitDirectory });
|
|
33
|
+
this.definition = new plugins.smartdaemon.SystemdServiceDefinition({
|
|
34
|
+
unitName: options.unitName, scope: 'user', description: 'Authswitch account authority', executable: process.execPath,
|
|
35
|
+
args: [plugins.path.join(packageRoot, 'cli.js'), 'authority', 'daemon'],
|
|
36
|
+
workingDirectory: packageRoot, restart: 'on-failure', killMode: 'mixed', timeoutStopSeconds: 60,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
async install() {
|
|
40
|
+
const previous = await this.unitFile.inspect();
|
|
41
|
+
const result = await this.unitFile.install(this.definition, previous?.sha256 ?? null);
|
|
42
|
+
return { changed: result.changed, masked: result.masked, sha256: result.record.sha256 };
|
|
43
|
+
}
|
|
44
|
+
inspect() { return this.unit.inspect(); }
|
|
45
|
+
enable() { return this.unit.enable(); }
|
|
46
|
+
start() { return this.unit.start(); }
|
|
47
|
+
stop() { return this.unit.stop(); }
|
|
48
|
+
}
|
|
49
|
+
export const runAuthSwitchAuthorityDaemon = async (paths = resolveAuthSwitchAuthorityPaths()) => {
|
|
50
|
+
const daemon = new AuthSwitchAuthorityDaemon({
|
|
51
|
+
dataDirectory: paths.dataDirectory,
|
|
52
|
+
socketPath: paths.databaseSocketPath,
|
|
53
|
+
authoritySocketPath: paths.authoritySocketPath,
|
|
54
|
+
runtimeSocketPath: paths.runtimeSocketPath,
|
|
55
|
+
});
|
|
56
|
+
await daemon.start();
|
|
57
|
+
await new Promise((resolve, reject) => {
|
|
58
|
+
let stopping = false;
|
|
59
|
+
const stop = () => {
|
|
60
|
+
if (stopping)
|
|
61
|
+
return;
|
|
62
|
+
stopping = true;
|
|
63
|
+
process.off('SIGINT', stop);
|
|
64
|
+
process.off('SIGTERM', stop);
|
|
65
|
+
void daemon.close().then(resolve, reject);
|
|
66
|
+
};
|
|
67
|
+
process.on('SIGINT', stop);
|
|
68
|
+
process.on('SIGTERM', stop);
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5hdXRob3JpdHlzZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2xhc3Nlcy5hdXRob3JpdHlzZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBV3pFLDBHQUEwRztBQUMxRyxNQUFNLENBQUMsTUFBTSwrQkFBK0IsR0FBRyxDQUFDLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsZUFBZSxFQUE2QixFQUFFO0lBQzNILElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQztRQUNwRSxNQUFNLElBQUksS0FBSyxDQUFDLGlFQUFpRSxDQUFDLENBQUM7SUFDckYsQ0FBQztJQUNELE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsT0FBTyxDQUFDO0lBQzNDLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsYUFBYSxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxjQUFjLENBQUMsQ0FBQztJQUN0RixJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDO1FBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDO0lBQ25HLE1BQU0sZUFBZSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLFlBQVksQ0FBQyxDQUFDO0lBQzFFLE1BQU0sc0JBQXNCLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQzdFLE9BQU87UUFDTCxnQkFB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
|
package/dist_ts/index.d.ts
CHANGED
|
@@ -23,4 +23,6 @@ export * from './classes.service.js';
|
|
|
23
23
|
export * from './classes.watch.js';
|
|
24
24
|
export * from './classes.watchlock.js';
|
|
25
25
|
export * from './watchpolicy.js';
|
|
26
|
+
export * from './classes.authorityclient.js';
|
|
27
|
+
export * from './classes.authorityservice.js';
|
|
26
28
|
export declare const runCli: (argvArg?: string[]) => Promise<void>;
|
package/dist_ts/index.js
CHANGED
|
@@ -23,9 +23,34 @@ export * from './classes.service.js';
|
|
|
23
23
|
export * from './classes.watch.js';
|
|
24
24
|
export * from './classes.watchlock.js';
|
|
25
25
|
export * from './watchpolicy.js';
|
|
26
|
+
export * from './classes.authorityclient.js';
|
|
27
|
+
export * from './classes.authorityservice.js';
|
|
26
28
|
import { AuthSwitchCli } from './classes.cli.js';
|
|
29
|
+
import { AuthSwitchAuthorityService, resolveAuthSwitchAuthorityPaths, runAuthSwitchAuthorityDaemon } from './classes.authorityservice.js';
|
|
27
30
|
export const runCli = async (argvArg = process.argv.slice(2)) => {
|
|
31
|
+
if (argvArg[0] === 'authority') {
|
|
32
|
+
const paths = resolveAuthSwitchAuthorityPaths();
|
|
33
|
+
if (argvArg[1] === 'daemon' && argvArg.length === 2) {
|
|
34
|
+
await runAuthSwitchAuthorityDaemon(paths);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (argvArg[1] === 'service' && argvArg.length === 3) {
|
|
38
|
+
const service = new AuthSwitchAuthorityService(paths.runtimeDirectory);
|
|
39
|
+
const action = argvArg[2];
|
|
40
|
+
const result = action === 'install' ? await service.install()
|
|
41
|
+
: action === 'status' ? await service.inspect()
|
|
42
|
+
: action === 'enable' ? await service.enable()
|
|
43
|
+
: action === 'start' ? await service.start()
|
|
44
|
+
: action === 'stop' ? await service.stop()
|
|
45
|
+
: null;
|
|
46
|
+
if (result !== null) {
|
|
47
|
+
process.stdout.write(JSON.stringify(result) + '\n');
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
throw new Error('Usage: authswitch authority daemon | service install|status|enable|start|stop');
|
|
52
|
+
}
|
|
28
53
|
const exitCode = await new AuthSwitchCli().run(argvArg);
|
|
29
54
|
process.exitCode = exitCode;
|
|
30
55
|
};
|
|
31
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
56
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLGlCQUFpQixDQUFDO0FBQ2hDLGNBQWMseUJBQXlCLENBQUM7QUFDeEMsY0FBYyxzQkFBc0IsQ0FBQztBQUNyQyxjQUFjLDJCQUEyQixDQUFDO0FBQzFDLGNBQWMsOEJBQThCLENBQUM7QUFDN0MsY0FBYyxnQ0FBZ0MsQ0FBQztBQUMvQyxjQUFjLCtCQUErQixDQUFDO0FBQzlDLGNBQWMsMkJBQTJCLENBQUM7QUFDMUMsY0FBYywwQkFBMEIsQ0FBQztBQUN6QyxjQUFjLDBCQUEwQixDQUFDO0FBQ3pDLGNBQWMsYUFBYSxDQUFDO0FBQzVCLGNBQWMsY0FBYyxDQUFDO0FBQzdCLGNBQWMsd0JBQXdCLENBQUM7QUFDdkMsY0FBYyx3QkFBd0IsQ0FBQztBQUN2QyxjQUFjLDRCQUE0QixDQUFDO0FBQzNDLGNBQWMseUJBQXlCLENBQUM7QUFDeEMsY0FBYywwQkFBMEIsQ0FBQztBQUN6QyxjQUFjLDRCQUE0QixDQUFDO0FBQzNDLGNBQWMsa0JBQWtCLENBQUM7QUFDakMsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLHlCQUF5QixDQUFDO0FBQ3hDLGNBQWMsc0JBQXNCLENBQUM7QUFDckMsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGNBQWMsa0JBQWtCLENBQUM7QUFDakMsY0FBYyw4QkFBOEIsQ0FBQztBQUM3QyxjQUFjLCtCQUErQixDQUFDO0FBRTlDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsK0JBQStCLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUUxSSxNQUFNLENBQUMsTUFBTSxNQUFNLEdBQUcsS0FBSyxFQUFFLFVBQW9CLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFpQixFQUFFO0lBQ3ZGLElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLFdBQVcsRUFBRSxDQUFDO1FBQy9CLE1BQU0sS0FBSyxHQUFHLCtCQUErQixFQUFFLENBQUM7UUFDaEQsSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssUUFBUSxJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDcEQsTUFBTSw0QkFBNEIsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMxQyxPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLFNBQVMsSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3JELE1BQU0sT0FBTyxHQUFHLElBQUksMEJBQTBCLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDdkUsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzFCLE1BQU0sTUFBTSxHQUFHLE1BQU0sS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLE1BQU0sT0FBTyxDQUFDLE9BQU8sRUFBRTtnQkFDM0QsQ0FBQyxDQUFDLE1BQU0sS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sT0FBTyxDQUFDLE9BQU8sRUFBRTtvQkFDL0MsQ0FBQyxDQUFDLE1BQU0sS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sT0FBTyxDQUFDLE1BQU0sRUFBRTt3QkFDOUMsQ0FBQyxDQUFDLE1BQU0sS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sT0FBTyxDQUFDLEtBQUssRUFBRTs0QkFDNUMsQ0FBQyxDQUFDLE1BQU0sS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sT0FBTyxDQUFDLElBQUksRUFBRTtnQ0FDMUMsQ0FBQyxDQUFDLElBQUksQ0FBQztZQUNULElBQUksTUFBTSxLQUFLLElBQUksRUFBRSxDQUFDO2dCQUNwQixPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO2dCQUNwRCxPQUFPO1lBQ1QsQ0FBQztRQUNILENBQUM7UUFDRCxNQUFNLElBQUksS0FBSyxDQUFDLCtFQUErRSxDQUFDLENBQUM7SUFDbkcsQ0FBQztJQUNELE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBSSxhQUFhLEVBQUUsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDeEQsT0FBTyxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7QUFDOUIsQ0FBQyxDQUFDIn0=
|
package/dist_ts/plugins.d.ts
CHANGED
|
@@ -3,8 +3,10 @@ import * as os from 'node:os';
|
|
|
3
3
|
import * as path from 'node:path';
|
|
4
4
|
import * as childProcess from 'node:child_process';
|
|
5
5
|
import * as crypto from 'node:crypto';
|
|
6
|
+
import * as net from 'node:net';
|
|
7
|
+
import { fileURLToPath } from 'node:url';
|
|
6
8
|
import type { DatabaseSync } from 'node:sqlite';
|
|
7
|
-
export { childProcess, crypto, fs, os, path };
|
|
9
|
+
export { childProcess, crypto, fileURLToPath, fs, net, os, path };
|
|
8
10
|
export type { DatabaseSync };
|
|
9
11
|
/** SQLite is needed only when accessing a Codex state database, not when hosting account APIs. */
|
|
10
12
|
export declare const loadSqlite: () => typeof import("node:sqlite");
|
|
@@ -16,7 +18,12 @@ export type TProperLockfile = typeof properLockfile;
|
|
|
16
18
|
*/
|
|
17
19
|
export declare const loadProperLockfile: () => Promise<TProperLockfile>;
|
|
18
20
|
import * as smartconsole from '@push.rocks/smartconsole';
|
|
19
|
-
|
|
21
|
+
import * as smartdata from '@push.rocks/smartdata';
|
|
22
|
+
import * as smartdb from '@push.rocks/smartdb';
|
|
23
|
+
import * as smartsecret from '@push.rocks/smartsecret';
|
|
24
|
+
import * as smartdaemon from '@push.rocks/smartdaemon';
|
|
25
|
+
import * as typedrequest from '@api.global/typedrequest';
|
|
26
|
+
export { smartconsole, smartdata, smartdb, smartsecret, smartdaemon, typedrequest };
|
|
20
27
|
import * as flexModels from '@modelprofile.com/flexharness-models';
|
|
21
28
|
import * as flexOpenAi from '@modelprofile.com/flexharness-providers/openai';
|
|
22
29
|
import * as flexAuth from '@modelprofile.com/flexharness-providers/auth';
|
package/dist_ts/plugins.js
CHANGED
|
@@ -4,8 +4,10 @@ import * as os from 'node:os';
|
|
|
4
4
|
import * as path from 'node:path';
|
|
5
5
|
import * as childProcess from 'node:child_process';
|
|
6
6
|
import * as crypto from 'node:crypto';
|
|
7
|
+
import * as net from 'node:net';
|
|
7
8
|
import { createRequire } from 'node:module';
|
|
8
|
-
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
10
|
+
export { childProcess, crypto, fileURLToPath, fs, net, os, path };
|
|
9
11
|
const nativeRequire = createRequire(import.meta.url);
|
|
10
12
|
/** SQLite is needed only when accessing a Codex state database, not when hosting account APIs. */
|
|
11
13
|
export const loadSqlite = () => nativeRequire('node:sqlite');
|
|
@@ -16,11 +18,16 @@ export const loadSqlite = () => nativeRequire('node:sqlite');
|
|
|
16
18
|
export const loadProperLockfile = () => import('proper-lockfile');
|
|
17
19
|
// @push.rocks modules
|
|
18
20
|
import * as smartconsole from '@push.rocks/smartconsole';
|
|
19
|
-
|
|
21
|
+
import * as smartdata from '@push.rocks/smartdata';
|
|
22
|
+
import * as smartdb from '@push.rocks/smartdb';
|
|
23
|
+
import * as smartsecret from '@push.rocks/smartsecret';
|
|
24
|
+
import * as smartdaemon from '@push.rocks/smartdaemon';
|
|
25
|
+
import * as typedrequest from '@api.global/typedrequest';
|
|
26
|
+
export { smartconsole, smartdata, smartdb, smartsecret, smartdaemon, typedrequest };
|
|
20
27
|
// @modelprofile.com modules
|
|
21
28
|
import * as flexModels from '@modelprofile.com/flexharness-models';
|
|
22
29
|
import * as flexOpenAi from '@modelprofile.com/flexharness-providers/openai';
|
|
23
30
|
import * as flexAuth from '@modelprofile.com/flexharness-providers/auth';
|
|
24
31
|
import * as flexAccounts from '@modelprofile.com/flexharness-providers/accounts';
|
|
25
32
|
export { flexModels, flexOpenAi, flexAuth, flexAccounts };
|
|
26
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
33
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsc0JBQXNCO0FBQ3RCLE9BQU8sS0FBSyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzlCLE9BQU8sS0FBSyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzlCLE9BQU8sS0FBSyxJQUFJLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sS0FBSyxZQUFZLE1BQU0sb0JBQW9CLENBQUM7QUFDbkQsT0FBTyxLQUFLLE1BQU0sTUFBTSxhQUFhLENBQUM7QUFDdEMsT0FBTyxLQUFLLEdBQUcsTUFBTSxVQUFVLENBQUM7QUFDaEMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUM1QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBR3pDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLGFBQWEsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQztBQUVsRSxNQUFNLGFBQWEsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNyRCxrR0FBa0c7QUFDbEcsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHLEdBQWlDLEVBQUUsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLENBQUM7QUFLM0Y7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQUcsR0FBNkIsRUFBRSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0FBRTVGLHNCQUFzQjtBQUN0QixPQUFPLEtBQUssWUFBWSxNQUFNLDBCQUEwQixDQUFDO0FBQ3pELE9BQU8sS0FBSyxTQUFTLE1BQU0sdUJBQXVCLENBQUM7QUFDbkQsT0FBTyxLQUFLLE9BQU8sTUFBTSxxQkFBcUIsQ0FBQztBQUMvQyxPQUFPLEtBQUssV0FBVyxNQUFNLHlCQUF5QixDQUFDO0FBQ3ZELE9BQU8sS0FBSyxXQUFXLE1BQU0seUJBQXlCLENBQUM7QUFDdkQsT0FBTyxLQUFLLFlBQVksTUFBTSwwQkFBMEIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsQ0FBQztBQUVwRiw0QkFBNEI7QUFDNUIsT0FBTyxLQUFLLFVBQVUsTUFBTSxzQ0FBc0MsQ0FBQztBQUNuRSxPQUFPLEtBQUssVUFBVSxNQUFNLGdEQUFnRCxDQUFDO0FBQzdFLE9BQU8sS0FBSyxRQUFRLE1BQU0sOENBQThDLENBQUM7QUFDekUsT0FBTyxLQUFLLFlBQVksTUFBTSxrREFBa0QsQ0FBQztBQUNqRixPQUFPLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLENBQUMifQ==
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modelprofile.com/authswitch",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.4.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Manage Codex, OpenCode and Claude Code accounts with guided switching and live usage status",
|
|
6
6
|
"main": "dist_ts/index.js",
|
|
@@ -13,6 +13,14 @@
|
|
|
13
13
|
"./mutation": {
|
|
14
14
|
"types": "./dist_ts/mutation.d.ts",
|
|
15
15
|
"import": "./dist_ts/mutation.js"
|
|
16
|
+
},
|
|
17
|
+
"./authority-contract": {
|
|
18
|
+
"types": "./dist_ts/authority-contract.d.ts",
|
|
19
|
+
"import": "./dist_ts/authority-contract.js"
|
|
20
|
+
},
|
|
21
|
+
"./authority-client": {
|
|
22
|
+
"types": "./dist_ts/classes.authorityclient.d.ts",
|
|
23
|
+
"import": "./dist_ts/classes.authorityclient.js"
|
|
16
24
|
}
|
|
17
25
|
},
|
|
18
26
|
"type": "module",
|
|
@@ -40,9 +48,15 @@
|
|
|
40
48
|
"esbuild": "^0.28.2"
|
|
41
49
|
},
|
|
42
50
|
"dependencies": {
|
|
43
|
-
"@
|
|
44
|
-
"@
|
|
51
|
+
"@api.global/typedrequest": "8.1.0",
|
|
52
|
+
"@api.global/typedrequest-interfaces": "7.1.0",
|
|
53
|
+
"@modelprofile.com/flexharness-models": "^8.0.0",
|
|
54
|
+
"@modelprofile.com/flexharness-providers": "^8.0.0",
|
|
45
55
|
"@push.rocks/smartconsole": "^1.3.0",
|
|
56
|
+
"@push.rocks/smartdaemon": "2.7.0",
|
|
57
|
+
"@push.rocks/smartdata": "11.14.2",
|
|
58
|
+
"@push.rocks/smartdb": "7.0.1",
|
|
59
|
+
"@push.rocks/smartsecret": "1.8.0",
|
|
46
60
|
"@types/proper-lockfile": "^4.1.4",
|
|
47
61
|
"proper-lockfile": "^4.1.2"
|
|
48
62
|
},
|
package/readme.md
CHANGED
|
@@ -24,6 +24,40 @@ pnpm install -g @modelprofile.com/authswitch
|
|
|
24
24
|
|
|
25
25
|
Node.js 24 or newer is required.
|
|
26
26
|
|
|
27
|
+
## Authority SDK (new account registry)
|
|
28
|
+
|
|
29
|
+
The package also exports a typed client for a per-user authswitch authority daemon. Its
|
|
30
|
+
SmartData registry stores account identity separately from sealed refresh grants, runtime
|
|
31
|
+
bindings, Codex enrollment records, and native-handoff and migration journals. A daemon
|
|
32
|
+
owns OpenAI device login, targeted reauthentication, and proactive refresh for grants
|
|
33
|
+
added through this API. Management snapshots and events contain no credentials.
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { AuthSwitchClient } from '@modelprofile.com/authswitch/authority-client';
|
|
37
|
+
import { resolveAuthSwitchAuthorityPaths } from '@modelprofile.com/authswitch';
|
|
38
|
+
|
|
39
|
+
const paths = resolveAuthSwitchAuthorityPaths();
|
|
40
|
+
const client = new AuthSwitchClient(paths.authoritySocketPath, paths.runtimeSocketPath);
|
|
41
|
+
const snapshot = await client.snapshotAll();
|
|
42
|
+
const operation = await client.beginAddOpenAi();
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Browser code can import the credential-free DTOs from
|
|
46
|
+
`@modelprofile.com/authswitch/authority-contract`. A backend binds an account to a
|
|
47
|
+
runtime incarnation and keeps the returned capability private. The runtime-only socket
|
|
48
|
+
resolves that binding to a current access token; its directory can be mounted into a
|
|
49
|
+
container without exposing the management socket. Reconnect and reload a snapshot after
|
|
50
|
+
an event gap or daemon restart.
|
|
51
|
+
|
|
52
|
+
This SDK is additive at this stage. The commands documented below still use the existing
|
|
53
|
+
credential stores. The authority daemon does not import those stores automatically,
|
|
54
|
+
replace their active native sessions, or take over their refresh grants. An active
|
|
55
|
+
Codex/OpenCode native grant remains pending until its owner is idle and an explicit
|
|
56
|
+
handoff verifies the latest native source. Claude Code's own native credential files
|
|
57
|
+
remain vendor-owned; a container setup-token grant is a separate grant under the same
|
|
58
|
+
account. The one-time migration and deletion of authswitch's old stores are separate
|
|
59
|
+
cutover steps.
|
|
60
|
+
|
|
27
61
|
## Usage
|
|
28
62
|
|
|
29
63
|
Run `authswitch`, `authswitch -i`, or `authswitch --interactive` for an interactive guide. Use the arrow keys and
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type { ITypedRequest } from '@api.global/typedrequest-interfaces';
|
|
2
|
+
|
|
3
|
+
/** Credential-free account management contract. Safe to import in browser code. */
|
|
4
|
+
export type TAuthSwitchAccountHealth = 'ready' | 'refreshing' | 'retry_wait' | 'needs_reauth' | 'native' | 'legacy_native_pending' | 'removed';
|
|
5
|
+
|
|
6
|
+
export interface IAuthSwitchAccount {
|
|
7
|
+
id: string;
|
|
8
|
+
providerId: string;
|
|
9
|
+
label: string;
|
|
10
|
+
email: string | null;
|
|
11
|
+
plan: string | null;
|
|
12
|
+
health: TAuthSwitchAccountHealth;
|
|
13
|
+
owner: 'daemon' | 'claude_native' | 'legacy_native' | 'none';
|
|
14
|
+
grantGeneration: number;
|
|
15
|
+
revision: number;
|
|
16
|
+
accessExpiresAt: string | null;
|
|
17
|
+
retryAt: string | null;
|
|
18
|
+
problem: 'none' | 'provider_unavailable' | 'exchange_uncertain' | 'provider_rejected' | 'native_owner';
|
|
19
|
+
statusObservedAt: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface IAuthSwitchBinding {
|
|
23
|
+
id: string;
|
|
24
|
+
accountId: string;
|
|
25
|
+
runtime: 'flex' | 'codex' | 'opencode' | 'claude';
|
|
26
|
+
scopeId: string;
|
|
27
|
+
incarnationId: string;
|
|
28
|
+
revision: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface IAuthSwitchSnapshot {
|
|
32
|
+
schemaVersion: 1;
|
|
33
|
+
epoch: string;
|
|
34
|
+
revision: number;
|
|
35
|
+
generatedAt: string;
|
|
36
|
+
accounts: IAuthSwitchAccount[];
|
|
37
|
+
bindings: IAuthSwitchBinding[];
|
|
38
|
+
nextAccountCursor: string | null;
|
|
39
|
+
nextBindingCursor: string | null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface IAuthSwitchAccountEvent {
|
|
43
|
+
epoch: string;
|
|
44
|
+
revision: number;
|
|
45
|
+
kind: 'account' | 'binding';
|
|
46
|
+
accountId: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export type TAuthSwitchLoginPrompt =
|
|
50
|
+
| { flow: 'device'; verificationUrl: string; userCode: string }
|
|
51
|
+
| { flow: 'browser'; authUrl: string };
|
|
52
|
+
|
|
53
|
+
export interface IAuthSwitchOperation {
|
|
54
|
+
id: string;
|
|
55
|
+
state: 'pending' | 'complete' | 'failed' | 'cancelled';
|
|
56
|
+
prompt: TAuthSwitchLoginPrompt | null;
|
|
57
|
+
account: IAuthSwitchAccount | null;
|
|
58
|
+
error: string | null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface IReq_AuthSwitchSnapshot extends ITypedRequest {
|
|
62
|
+
method: 'authswitch.authority.snapshot';
|
|
63
|
+
request: { accountAfter?: string; bindingAfter?: string; limit?: number };
|
|
64
|
+
response: { snapshot: IAuthSwitchSnapshot };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface IReq_AuthSwitchEvents extends ITypedRequest {
|
|
68
|
+
method: 'authswitch.authority.events';
|
|
69
|
+
request: { epoch: string; afterRevision: number; waitMs: number };
|
|
70
|
+
response: { epoch: string; revision: number; resyncRequired: boolean; events: IAuthSwitchAccountEvent[] };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface IReq_AuthSwitchBeginAdd extends ITypedRequest {
|
|
74
|
+
method: 'authswitch.authority.add';
|
|
75
|
+
request: { providerId: 'openai'; flow: 'device' };
|
|
76
|
+
response: { operation: IAuthSwitchOperation };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface IReq_AuthSwitchBeginReauth extends ITypedRequest {
|
|
80
|
+
method: 'authswitch.authority.reauth';
|
|
81
|
+
request: { accountId: string; flow: 'device' };
|
|
82
|
+
response: { operation: IAuthSwitchOperation };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface IReq_AuthSwitchGetOperation extends ITypedRequest {
|
|
86
|
+
method: 'authswitch.authority.operation';
|
|
87
|
+
request: { operationId: string };
|
|
88
|
+
response: { operation: IAuthSwitchOperation };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface IReq_AuthSwitchCancelOperation extends ITypedRequest {
|
|
92
|
+
method: 'authswitch.authority.cancel';
|
|
93
|
+
request: { operationId: string };
|
|
94
|
+
response: { operation: IAuthSwitchOperation };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface IReq_AuthSwitchRenameAccount extends ITypedRequest {
|
|
98
|
+
method: 'authswitch.authority.rename';
|
|
99
|
+
request: { accountId: string; expectedRevision: number; label: string };
|
|
100
|
+
response: { account: IAuthSwitchAccount };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface IReq_AuthSwitchRemoveAccount extends ITypedRequest {
|
|
104
|
+
method: 'authswitch.authority.remove';
|
|
105
|
+
request: { accountId: string; expectedRevision: number };
|
|
106
|
+
response: { account: IAuthSwitchAccount };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** Runtime capability is returned only to trusted backend callers; do not expose this response in a browser API. */
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ITypedRequest } from '@api.global/typedrequest-interfaces';
|
|
2
|
+
import type { IAuthSwitchBinding } from './authority-contract.js';
|
|
3
|
+
|
|
4
|
+
/** Backend-only binding operation. The capability must never enter a browser-facing response. */
|
|
5
|
+
export interface IReq_AuthSwitchBindAccount extends ITypedRequest {
|
|
6
|
+
method: 'authswitch.authority.bind';
|
|
7
|
+
request: {
|
|
8
|
+
accountId: string;
|
|
9
|
+
runtime: IAuthSwitchBinding['runtime'];
|
|
10
|
+
scopeId: string;
|
|
11
|
+
incarnationId: string;
|
|
12
|
+
};
|
|
13
|
+
response: { binding: IAuthSwitchBinding; capability: string };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Backend-only access operation. Refresh grants never cross this interface. */
|
|
17
|
+
export interface IReq_AuthSwitchResolveAccess extends ITypedRequest {
|
|
18
|
+
method: 'authswitch.authority.resolveAccess';
|
|
19
|
+
request: { bindingId: string; capability: string; minValidityMs: number };
|
|
20
|
+
response: {
|
|
21
|
+
accessToken: string;
|
|
22
|
+
accountId: string;
|
|
23
|
+
isFedrampAccount: boolean;
|
|
24
|
+
expiresAt: string;
|
|
25
|
+
grantGeneration: number;
|
|
26
|
+
};
|
|
27
|
+
}
|