@modelprofile.com/authswitch 6.2.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/classes.cli.d.ts +56 -0
- package/dist_ts/classes.cli.js +238 -63
- package/dist_ts/classes.codexpreuse.js +2 -2
- package/dist_ts/classes.tui.js +51 -2
- 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/dist_ts/preuse.d.ts +89 -2
- package/dist_ts/preuse.js +107 -2
- package/package.json +17 -3
- package/readme.md +118 -16
- 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/classes.cli.ts +236 -54
- package/ts/classes.codexpreuse.ts +1 -1
- package/ts/classes.tui.ts +39 -2
- package/ts/index.ts +25 -0
- package/ts/plugins.ts +9 -2
- package/ts/preuse.ts +141 -3
package/readme.md
CHANGED
|
@@ -24,12 +24,47 @@ 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
|
|
30
64
|
Enter to switch accounts, save the current login, list accounts and live status, check remote
|
|
31
|
-
control, or remove a saved account. The guide shows the current
|
|
32
|
-
to the menu after each successful action; choose **Back** in a submenu or
|
|
65
|
+
control, preuse one or all accounts, or remove a saved account. The guide shows the current
|
|
66
|
+
account and returns to the menu after each successful action; choose **Back** in a submenu or
|
|
67
|
+
**Exit** to finish.
|
|
33
68
|
|
|
34
69
|
Before showing the actions, the guide checks whether the current credential has a
|
|
35
70
|
readable saved copy of its own account. A login without one gets an offer to save it
|
|
@@ -62,6 +97,7 @@ authswitch codex use [email] # activate one; prompts when no email is given
|
|
|
62
97
|
authswitch opencode use [email] --stop # stop running OpenCode instances first
|
|
63
98
|
authswitch opencode use [email] --keep-running # switch without stopping anything
|
|
64
99
|
authswitch codex preuse <email> # send the default prompt without activating the account
|
|
100
|
+
authswitch codex preuse --all # the same for every Codex account, one account at a time
|
|
65
101
|
authswitch watch # check usage every 2 minutes and switch when an account runs out
|
|
66
102
|
authswitch claude watch --threshold 90 --dry-run # report what it would switch, for one harness
|
|
67
103
|
authswitch codex current # print the account currently in use
|
|
@@ -381,12 +417,58 @@ to make the first token-consuming request for the next usage window:
|
|
|
381
417
|
authswitch codex preuse alice@example.com
|
|
382
418
|
authswitch codex preuse alice@example.com --prompt "Write 2000 words about strawberries."
|
|
383
419
|
authswitch codex preuse alice@example.com --model gpt-5.5 --prompt "Describe a strawberry in one sentence."
|
|
420
|
+
authswitch codex preuse --all
|
|
421
|
+
authswitch codex preuse --all --model gpt-5.5
|
|
384
422
|
```
|
|
385
423
|
|
|
386
424
|
The default prompt is `Write 2000 words about strawberries.` Without an account,
|
|
387
|
-
an interactive terminal shows
|
|
388
|
-
|
|
389
|
-
|
|
425
|
+
an interactive terminal shows a picker of the harness's accounts, plus **All
|
|
426
|
+
accounts** when it has more than one and **Back**. Choosing one account runs it
|
|
427
|
+
exactly as naming it would; choosing **All accounts** confirms once and then runs
|
|
428
|
+
as `--all` does, table and exit status included. Scripts must specify an account
|
|
429
|
+
or `--all` and, when multiple harnesses are registered, the harness. Active and
|
|
430
|
+
saved accounts are supported, including an active login that has not been stashed.
|
|
431
|
+
|
|
432
|
+
`--all` preuses every account the harness lists, active and saved, each exactly
|
|
433
|
+
once -- an active login and its own saved record are one account -- and it cannot
|
|
434
|
+
be combined with an account reference. The accounts run strictly one after
|
|
435
|
+
another, never in parallel, each with one request and no retry, and each one is
|
|
436
|
+
reported as it goes. The run ends with a table and a counts line:
|
|
437
|
+
|
|
438
|
+
```
|
|
439
|
+
[1/3] Preusing alice@example.com (Codex)…
|
|
440
|
+
Prompt completed with gpt-5.5. Tokens: 19 input, 2711 output, 2730 total.
|
|
441
|
+
[2/3] Preusing bob@example.com (Codex)…
|
|
442
|
+
Prompt completed with gpt-5.5. Tokens: 19 input, 2711 output, 2730 total.
|
|
443
|
+
[3/3] Preusing apikey:9f2 (Codex)…
|
|
444
|
+
Codex preuse requires a ChatGPT subscription login; API-key logins have no subscription reset window.
|
|
445
|
+
|
|
446
|
+
Preuse results
|
|
447
|
+
┌────────────────────┬───────────┬─────────┬─────────────────────┬──────────────┐
|
|
448
|
+
│ Account │ Outcome │ Model │ Tokens in/out/total │ Next reset │
|
|
449
|
+
├────────────────────┼───────────┼─────────┼─────────────────────┼──────────────┤
|
|
450
|
+
│ alice@example.com │ Completed │ gpt-5.5 │ 19/2711/2730 │ 5d 18h 53min │
|
|
451
|
+
│ bob@example.com │ Completed │ gpt-5.5 │ 19/2711/2730 │ 5d 18h 53min │
|
|
452
|
+
│ apikey:9f2 │ Skipped │ - │ - │ - │
|
|
453
|
+
└────────────────────┴───────────┴─────────┴─────────────────────┴──────────────┘
|
|
454
|
+
2 completed, 1 skipped.
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
`Next reset` is the lead window of the reset schedule read after that account's
|
|
458
|
+
prompt, the same window the single-account reset table lists first. An account
|
|
459
|
+
that sent no prompt has no model, token count or deadline of its own, and says so
|
|
460
|
+
rather than showing a zero. `Skipped` is a refusal the adapter stated before any
|
|
461
|
+
request -- an API-key login, a missing or expired credential, a model catalog
|
|
462
|
+
that could not be read -- so nothing was consumed for it. `Failed` and
|
|
463
|
+
`Interrupted` may both have consumed tokens and are never retried; `Not run` is
|
|
464
|
+
an account the interruption never reached.
|
|
465
|
+
|
|
466
|
+
The guide (`authswitch`, `authswitch -i`) offers **Preuse an account or all
|
|
467
|
+
accounts (consumes quota)** for a harness that supports it. It asks which account
|
|
468
|
+
or **All accounts**, confirms once and names what the prompt will be sent to, then
|
|
469
|
+
reports exactly as the command line does: one account's reset schedule, or the
|
|
470
|
+
results table for all of them. **Back** or a declined confirmation sends nothing,
|
|
471
|
+
and an account the adapter refuses returns to the menu rather than ending the guide.
|
|
390
472
|
|
|
391
473
|
Codex inference uses the published FlexHarness models/providers packages and the
|
|
392
474
|
selected ChatGPT login's access token and account ID. It selects the account's
|
|
@@ -395,21 +477,25 @@ low reasoning setting when the catalog provides one. API-key logins are rejected
|
|
|
395
477
|
because they do not have ChatGPT subscription reset windows. Expired credentials
|
|
396
478
|
must be renewed through Codex and saved again.
|
|
397
479
|
|
|
398
|
-
Each invocation consumes quota and sends
|
|
399
|
-
not watch for resets or schedule future requests. No active login is switched,
|
|
480
|
+
Each invocation consumes quota and sends one inference request per account. It
|
|
481
|
+
does not watch for resets or schedule future requests. No active login is switched,
|
|
400
482
|
credential refreshed or written, app-server restarted, or earned reset consumed.
|
|
401
483
|
The prompt has no tools, files or conversation history. The generated prose is
|
|
402
484
|
drained without being printed or stored; the command reports provider token
|
|
403
485
|
counts and then reads the account's reset schedule. It does not infer that a
|
|
404
486
|
timer started merely from a zero-percent usage reading or a successful response.
|
|
405
487
|
|
|
406
|
-
Ctrl-C cancels the request
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
488
|
+
Ctrl-C cancels the request, and in a `--all` run it stops the run before the next
|
|
489
|
+
account starts. Codex preuse has a three-minute deadline, with a ten-second
|
|
490
|
+
model-catalog limit. Failed or interrupted requests can have consumed tokens and
|
|
491
|
+
are never retried automatically. A completed prompt exits with 0 even if the
|
|
492
|
+
subsequent reset lookup fails, reporting that uncertainty separately; inference
|
|
493
|
+
failure exits with 1, invalid arguments or unsupported harnesses with 2, and an
|
|
494
|
+
interrupted prompt with 130. A named single account also exits 1 when it was
|
|
495
|
+
refused, because it is the account the command was asked to preuse; `--all` exits
|
|
496
|
+
0 when every account either completed or was skipped for a stated reason. Check
|
|
497
|
+
`authswitch list` before repeating an uncertain request. `--json` remains a
|
|
498
|
+
list-only option.
|
|
413
499
|
|
|
414
500
|
### Watching usage and switching automatically
|
|
415
501
|
|
|
@@ -492,10 +578,18 @@ incrementally through each account's status API, without activating it.
|
|
|
492
578
|
| `/`, `s`, `S` | Filter the table, cycle its sort column, reverse sorting |
|
|
493
579
|
| `a` / `c` | Save the current login and keep it active / save and clear it |
|
|
494
580
|
| `d` | Remove the selected saved copy, preserving the active login |
|
|
581
|
+
| `p` / `P` | Preuse the selected account / every account of this harness (consumes quota) |
|
|
495
582
|
| `r` / `g` | Refresh status / run harness diagnostics |
|
|
496
583
|
| `q` / Ctrl-C | Close and restore the terminal |
|
|
497
584
|
|
|
498
|
-
|
|
585
|
+
The preuse keys appear in the key line only for a harness that supports preuse,
|
|
586
|
+
and each run states how many accounts it will consume quota on before it starts.
|
|
587
|
+
The footer follows the run account by account, the activity log keeps each
|
|
588
|
+
account's result, and the table is read again afterwards because the prompts
|
|
589
|
+
moved the usage it shows. Closing the dashboard stops the run before its next
|
|
590
|
+
account.
|
|
591
|
+
|
|
592
|
+
Save, switch, preuse and removal actions require confirmation. Confirmations start on
|
|
499
593
|
Cancel; use Left/Right or Tab to select the action, then Enter. Switching first
|
|
500
594
|
checks the current credential and offers to save an unsaved login. A declined,
|
|
501
595
|
failed or unverified save prevents switching. Plain character shortcuts remain
|
|
@@ -993,7 +1087,15 @@ model identifier and cancellation signal; `IHarnessPreuseResult` returns the
|
|
|
993
1087
|
selected model and optional input/output/total token counts. The adapter owns
|
|
994
1088
|
credential selection and inference and must leave the active login unchanged.
|
|
995
1089
|
Unsupported adapters reject the command before account selection. Prompt results
|
|
996
|
-
never contain credentials or raw provider responses.
|
|
1090
|
+
never contain credentials or raw provider responses. A refusal that sent no
|
|
1091
|
+
request must be a `PreuseError` with `requestStarted` false, which is what a run
|
|
1092
|
+
over several accounts reports as skipped rather than failed; every other error,
|
|
1093
|
+
`PreuseError` or not, is treated as a request that may have consumed tokens.
|
|
1094
|
+
`preuseAccounts(harness, accounts, options, report)` is that run: it sends one
|
|
1095
|
+
prompt per account in turn, reports a `started` and a `finished` event for each,
|
|
1096
|
+
reads the account's reset schedule after a completed prompt, stops before the
|
|
1097
|
+
next account once the signal aborts, and returns the per-account results with
|
|
1098
|
+
their counts.
|
|
997
1099
|
|
|
998
1100
|
Adapters can also return an optional `IHarnessAccountStatus.summary` with a
|
|
999
1101
|
subscription plan and its live/stored provenance, labelled usage windows with
|
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
|
+
}
|