@zivis/cli 0.1.0-alpha.4 → 0.1.0-alpha.41
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/LICENSE +201 -0
- package/README.md +31 -0
- package/dist/commands/app/index.d.ts +0 -8
- package/dist/commands/app/index.js +8 -18
- package/dist/commands/assurance/index.d.ts +33 -0
- package/dist/commands/assurance/index.js +149 -0
- package/dist/commands/auth/bind.d.ts +4 -0
- package/dist/commands/auth/bind.js +97 -0
- package/dist/commands/auth/index.js +21 -2
- package/dist/commands/auth/init.d.ts +2 -0
- package/dist/commands/auth/init.js +249 -73
- package/dist/commands/auth/login.d.ts +2 -0
- package/dist/commands/auth/login.js +136 -18
- package/dist/commands/auth/logout.js +19 -7
- package/dist/commands/auth/sessions.js +7 -4
- package/dist/commands/auth/status.js +33 -12
- package/dist/commands/auth/token.d.ts +4 -0
- package/dist/commands/auth/token.js +73 -0
- package/dist/commands/check/index.d.ts +2 -0
- package/dist/commands/check/index.js +463 -0
- package/dist/commands/credits/index.js +2 -3
- package/dist/commands/gate/index.d.ts +2 -0
- package/dist/commands/gate/index.js +171 -0
- package/dist/commands/inspect/index.d.ts +2 -0
- package/dist/commands/inspect/index.js +136 -0
- package/dist/commands/mcp/index.js +113 -14
- package/dist/commands/open/index.d.ts +0 -8
- package/dist/commands/open/index.js +0 -11
- package/dist/commands/run/index.d.ts +2 -0
- package/dist/commands/run/index.js +111 -0
- package/dist/commands/scan/index.js +3 -8
- package/dist/commands/sync/index.d.ts +2 -0
- package/dist/commands/sync/index.js +187 -0
- package/dist/commands/target/index.js +0 -3
- package/dist/commands/test/index.d.ts +2 -0
- package/dist/commands/test/index.js +115 -0
- package/dist/commands/tm/index.js +7 -10
- package/dist/index.js +24 -1
- package/dist/internal/application-binding.d.ts +8 -0
- package/dist/internal/application-binding.js +167 -0
- package/dist/internal/binding-token-mint.d.ts +33 -0
- package/dist/internal/binding-token-mint.js +174 -0
- package/dist/internal/cli-output.d.ts +16 -0
- package/dist/internal/cli-output.js +39 -0
- package/dist/internal/devx-run.d.ts +47 -0
- package/dist/internal/devx-run.js +36 -0
- package/dist/internal/extractor/adapters/go/index.d.ts +0 -4
- package/dist/internal/extractor/adapters/go/index.js +0 -6
- package/dist/internal/extractor/adapters/go/manifest.d.ts +0 -17
- package/dist/internal/extractor/adapters/go/manifest.js +19 -25
- package/dist/internal/extractor/adapters/go/parser.d.ts +0 -4
- package/dist/internal/extractor/adapters/go/parser.js +0 -5
- package/dist/internal/extractor/adapters/go/scanner.d.ts +0 -20
- package/dist/internal/extractor/adapters/go/scanner.js +0 -43
- package/dist/internal/extractor/adapters/python/index.d.ts +0 -3
- package/dist/internal/extractor/adapters/python/index.js +0 -4
- package/dist/internal/extractor/adapters/python/manifest.d.ts +0 -8
- package/dist/internal/extractor/adapters/python/manifest.js +21 -18
- package/dist/internal/extractor/adapters/python/parser.d.ts +0 -3
- package/dist/internal/extractor/adapters/python/parser.js +0 -4
- package/dist/internal/extractor/adapters/python/scanner.d.ts +0 -18
- package/dist/internal/extractor/adapters/python/scanner.js +1 -54
- package/dist/internal/extractor/adapters/typescript/index.d.ts +0 -7
- package/dist/internal/extractor/adapters/typescript/index.js +1 -21
- package/dist/internal/extractor/adapters/typescript/manifest.d.ts +0 -14
- package/dist/internal/extractor/adapters/typescript/manifest.js +26 -17
- package/dist/internal/extractor/adapters/typescript/parser.d.ts +0 -8
- package/dist/internal/extractor/adapters/typescript/parser.js +0 -9
- package/dist/internal/extractor/adapters/typescript/scanner.d.ts +0 -24
- package/dist/internal/extractor/adapters/typescript/scanner.js +0 -43
- package/dist/internal/extractor/graph-builder.d.ts +10 -0
- package/dist/internal/extractor/graph-builder.js +245 -0
- package/dist/internal/extractor/graph-types.d.ts +89 -0
- package/dist/internal/extractor/graph-types.js +1 -0
- package/dist/internal/extractor/index.d.ts +0 -14
- package/dist/internal/extractor/index.js +0 -13
- package/dist/internal/extractor/types.d.ts +0 -45
- package/dist/internal/extractor/types.js +0 -27
- package/dist/internal/extractor/walker.d.ts +0 -18
- package/dist/internal/extractor/walker.js +0 -18
- package/dist/internal/gate-evaluate.d.ts +50 -0
- package/dist/internal/gate-evaluate.js +111 -0
- package/dist/internal/gate-policy.d.ts +38 -0
- package/dist/internal/gate-policy.js +167 -0
- package/dist/internal/git-metadata.d.ts +8 -0
- package/dist/internal/git-metadata.js +38 -0
- package/dist/internal/git.d.ts +8 -0
- package/dist/internal/git.js +30 -0
- package/dist/internal/github-linkage-prompt.d.ts +7 -0
- package/dist/internal/github-linkage-prompt.js +95 -0
- package/dist/internal/ide-setup.d.ts +17 -7
- package/dist/internal/ide-setup.js +377 -46
- package/dist/internal/inventory-sync.d.ts +74 -0
- package/dist/internal/inventory-sync.js +189 -0
- package/dist/internal/org-picker.d.ts +11 -0
- package/dist/internal/org-picker.js +34 -0
- package/dist/internal/orgs.js +0 -1
- package/dist/internal/packs/cache.d.ts +8 -0
- package/dist/internal/packs/cache.js +60 -0
- package/dist/internal/packs/index.d.ts +10 -0
- package/dist/internal/packs/index.js +7 -0
- package/dist/internal/packs/integrity.d.ts +9 -0
- package/dist/internal/packs/integrity.js +24 -0
- package/dist/internal/packs/jcs.d.ts +2 -0
- package/dist/internal/packs/jcs.js +57 -0
- package/dist/internal/packs/local-paths.d.ts +4 -0
- package/dist/internal/packs/local-paths.js +26 -0
- package/dist/internal/packs/registry-client.d.ts +20 -0
- package/dist/internal/packs/registry-client.js +40 -0
- package/dist/internal/packs/resolve.d.ts +8 -0
- package/dist/internal/packs/resolve.js +89 -0
- package/dist/internal/packs/semver.d.ts +9 -0
- package/dist/internal/packs/semver.js +57 -0
- package/dist/internal/packs/signing.d.ts +5 -0
- package/dist/internal/packs/signing.js +49 -0
- package/dist/internal/packs/types.d.ts +70 -0
- package/dist/internal/packs/types.js +20 -0
- package/dist/internal/project-binding.d.ts +1 -0
- package/dist/internal/project-binding.js +14 -9
- package/dist/internal/run-workdir.d.ts +1 -0
- package/dist/internal/run-workdir.js +11 -0
- package/dist/internal/security-context.d.ts +62 -0
- package/dist/internal/security-context.js +50 -0
- package/dist/internal/sync-outbox.d.ts +40 -0
- package/dist/internal/sync-outbox.js +66 -0
- package/dist/internal/target-auth/api-config.d.ts +0 -17
- package/dist/internal/target-auth/api-config.js +0 -18
- package/dist/internal/target-auth/config.d.ts +0 -12
- package/dist/internal/target-auth/config.js +0 -13
- package/dist/internal/target-auth/index.d.ts +0 -18
- package/dist/internal/target-auth/index.js +0 -19
- package/dist/internal/target-auth/keychain.d.ts +0 -18
- package/dist/internal/target-auth/keychain.js +3 -23
- package/dist/internal/target-auth/types.d.ts +0 -26
- package/dist/internal/target-auth/types.js +0 -10
- package/dist/internal/target-auth/workos.d.ts +0 -15
- package/dist/internal/target-auth/workos.js +9 -18
- package/dist/internal/test-scope.d.ts +68 -0
- package/dist/internal/test-scope.js +69 -0
- package/dist/internal/zivis-local-state.d.ts +1 -0
- package/dist/internal/zivis-local-state.js +22 -0
- package/package.json +20 -5
- package/dist/commands/app/index.js.map +0 -1
- package/dist/commands/auth/index.js.map +0 -1
- package/dist/commands/auth/init.js.map +0 -1
- package/dist/commands/auth/login.js.map +0 -1
- package/dist/commands/auth/logout.js.map +0 -1
- package/dist/commands/auth/sessions.js.map +0 -1
- package/dist/commands/auth/status.js.map +0 -1
- package/dist/commands/credits/index.js.map +0 -1
- package/dist/commands/mcp/index.js.map +0 -1
- package/dist/commands/open/index.js.map +0 -1
- package/dist/commands/scan/index.js.map +0 -1
- package/dist/commands/target/index.js.map +0 -1
- package/dist/commands/tm/index.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/internal/extractor/adapters/go/index.js.map +0 -1
- package/dist/internal/extractor/adapters/go/manifest.js.map +0 -1
- package/dist/internal/extractor/adapters/go/parser.js.map +0 -1
- package/dist/internal/extractor/adapters/go/scanner.js.map +0 -1
- package/dist/internal/extractor/adapters/python/index.js.map +0 -1
- package/dist/internal/extractor/adapters/python/manifest.js.map +0 -1
- package/dist/internal/extractor/adapters/python/parser.js.map +0 -1
- package/dist/internal/extractor/adapters/python/scanner.js.map +0 -1
- package/dist/internal/extractor/adapters/typescript/index.js.map +0 -1
- package/dist/internal/extractor/adapters/typescript/manifest.js.map +0 -1
- package/dist/internal/extractor/adapters/typescript/parser.js.map +0 -1
- package/dist/internal/extractor/adapters/typescript/scanner.js.map +0 -1
- package/dist/internal/extractor/index.js.map +0 -1
- package/dist/internal/extractor/types.js.map +0 -1
- package/dist/internal/extractor/walker.js.map +0 -1
- package/dist/internal/ide-setup.js.map +0 -1
- package/dist/internal/orgs.js.map +0 -1
- package/dist/internal/project-binding.js.map +0 -1
- package/dist/internal/target-auth/api-config.js.map +0 -1
- package/dist/internal/target-auth/config.js.map +0 -1
- package/dist/internal/target-auth/index.js.map +0 -1
- package/dist/internal/target-auth/keychain.js.map +0 -1
- package/dist/internal/target-auth/types.js.map +0 -1
- package/dist/internal/target-auth/workos.js.map +0 -1
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const SEMVER_RE = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?/;
|
|
2
|
+
export function parseVersion(version) {
|
|
3
|
+
const m = SEMVER_RE.exec(version.trim());
|
|
4
|
+
if (!m) {
|
|
5
|
+
throw new Error(`Not a valid semver-like version: "${version}"`);
|
|
6
|
+
}
|
|
7
|
+
const [, major, minor, patch, prerelease] = m;
|
|
8
|
+
return {
|
|
9
|
+
major: Number(major),
|
|
10
|
+
minor: Number(minor),
|
|
11
|
+
patch: Number(patch),
|
|
12
|
+
prerelease: prerelease
|
|
13
|
+
? prerelease.split(".").map((part) => (/^\d+$/.test(part) ? Number(part) : part))
|
|
14
|
+
: [],
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function compareIdentifier(a, b) {
|
|
18
|
+
if (typeof a === "number" && typeof b === "number")
|
|
19
|
+
return a - b;
|
|
20
|
+
const as = String(a);
|
|
21
|
+
const bs = String(b);
|
|
22
|
+
if (typeof a === "number")
|
|
23
|
+
return -1;
|
|
24
|
+
if (typeof b === "number")
|
|
25
|
+
return 1;
|
|
26
|
+
return as < bs ? -1 : as > bs ? 1 : 0;
|
|
27
|
+
}
|
|
28
|
+
export function compareVersions(a, b) {
|
|
29
|
+
const pa = parseVersion(a);
|
|
30
|
+
const pb = parseVersion(b);
|
|
31
|
+
if (pa.major !== pb.major)
|
|
32
|
+
return pa.major - pb.major;
|
|
33
|
+
if (pa.minor !== pb.minor)
|
|
34
|
+
return pa.minor - pb.minor;
|
|
35
|
+
if (pa.patch !== pb.patch)
|
|
36
|
+
return pa.patch - pb.patch;
|
|
37
|
+
if (pa.prerelease.length === 0 && pb.prerelease.length === 0)
|
|
38
|
+
return 0;
|
|
39
|
+
if (pa.prerelease.length === 0)
|
|
40
|
+
return 1;
|
|
41
|
+
if (pb.prerelease.length === 0)
|
|
42
|
+
return -1;
|
|
43
|
+
const len = Math.max(pa.prerelease.length, pb.prerelease.length);
|
|
44
|
+
for (let i = 0; i < len; i++) {
|
|
45
|
+
if (i >= pa.prerelease.length)
|
|
46
|
+
return -1;
|
|
47
|
+
if (i >= pb.prerelease.length)
|
|
48
|
+
return 1;
|
|
49
|
+
const cmp = compareIdentifier(pa.prerelease[i], pb.prerelease[i]);
|
|
50
|
+
if (cmp !== 0)
|
|
51
|
+
return cmp;
|
|
52
|
+
}
|
|
53
|
+
return 0;
|
|
54
|
+
}
|
|
55
|
+
export function satisfiesMinVersion(cliVersion, minCliVersion) {
|
|
56
|
+
return compareVersions(cliVersion, minCliVersion) >= 0;
|
|
57
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { PackManifestV1, PackSignature } from "./types.js";
|
|
2
|
+
export declare const DEV_PACK_SIGNING_KEY_ID = "zivis-pack-dev-2026-08";
|
|
3
|
+
export declare function manifestSigningPayload(manifest: Omit<PackManifestV1, "signature">): string;
|
|
4
|
+
export declare function verifyManifestSignature(manifest: PackManifestV1): boolean;
|
|
5
|
+
export declare function signManifestDev(manifest: Omit<PackManifestV1, "signature">, privateKeySpkiB64: string): PackSignature;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as crypto from "node:crypto";
|
|
2
|
+
import { canonicalize } from "./jcs.js";
|
|
3
|
+
export const DEV_PACK_SIGNING_KEY_ID = "zivis-pack-dev-2026-08";
|
|
4
|
+
const DEV_PACK_PUBLIC_KEY_SPKI_B64 = "MCowBQYDK2VwAyEA1xfF9X57KKlqMA8vbHg7DEuU6K5aTURJaFINYk6wRvA=";
|
|
5
|
+
const KNOWN_PUBLIC_KEYS = {
|
|
6
|
+
[DEV_PACK_SIGNING_KEY_ID]: DEV_PACK_PUBLIC_KEY_SPKI_B64,
|
|
7
|
+
};
|
|
8
|
+
function loadPublicKey(keyId) {
|
|
9
|
+
const spkiB64 = KNOWN_PUBLIC_KEYS[keyId];
|
|
10
|
+
if (!spkiB64)
|
|
11
|
+
return null;
|
|
12
|
+
return crypto.createPublicKey({
|
|
13
|
+
key: Buffer.from(spkiB64, "base64"),
|
|
14
|
+
format: "der",
|
|
15
|
+
type: "spki",
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
export function manifestSigningPayload(manifest) {
|
|
19
|
+
return canonicalize(manifest);
|
|
20
|
+
}
|
|
21
|
+
export function verifyManifestSignature(manifest) {
|
|
22
|
+
const { signature, ...unsigned } = manifest;
|
|
23
|
+
if (!signature || signature.algorithm !== "ed25519")
|
|
24
|
+
return false;
|
|
25
|
+
const publicKey = loadPublicKey(signature.key_id);
|
|
26
|
+
if (!publicKey)
|
|
27
|
+
return false;
|
|
28
|
+
try {
|
|
29
|
+
const payload = manifestSigningPayload(unsigned);
|
|
30
|
+
return crypto.verify(null, new Uint8Array(Buffer.from(payload, "utf8")), publicKey, new Uint8Array(Buffer.from(signature.signature, "base64")));
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export function signManifestDev(manifest, privateKeySpkiB64) {
|
|
37
|
+
const privateKey = crypto.createPrivateKey({
|
|
38
|
+
key: Buffer.from(privateKeySpkiB64, "base64"),
|
|
39
|
+
format: "der",
|
|
40
|
+
type: "pkcs8",
|
|
41
|
+
});
|
|
42
|
+
const payload = manifestSigningPayload(manifest);
|
|
43
|
+
const sig = crypto.sign(null, new Uint8Array(Buffer.from(payload, "utf8")), privateKey);
|
|
44
|
+
return {
|
|
45
|
+
algorithm: "ed25519",
|
|
46
|
+
key_id: DEV_PACK_SIGNING_KEY_ID,
|
|
47
|
+
signature: sig.toString("base64"),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export type PackType = "appsec" | "threatmodel";
|
|
2
|
+
export interface PackContentEntry {
|
|
3
|
+
path: string;
|
|
4
|
+
sha256: string;
|
|
5
|
+
}
|
|
6
|
+
export interface PackScopeEntry extends PackContentEntry {
|
|
7
|
+
id: string;
|
|
8
|
+
label: string;
|
|
9
|
+
description: string;
|
|
10
|
+
}
|
|
11
|
+
export interface PackSignature {
|
|
12
|
+
algorithm: "ed25519";
|
|
13
|
+
key_id: string;
|
|
14
|
+
signature: string;
|
|
15
|
+
}
|
|
16
|
+
export interface PackManifestV1 {
|
|
17
|
+
schema_version: "1.0.0";
|
|
18
|
+
pack_id: string;
|
|
19
|
+
pack_type: PackType;
|
|
20
|
+
version: string;
|
|
21
|
+
min_cli_version: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
built_at: string;
|
|
24
|
+
base: PackContentEntry;
|
|
25
|
+
scopes?: PackScopeEntry[];
|
|
26
|
+
signature: PackSignature;
|
|
27
|
+
}
|
|
28
|
+
export interface PackVersionSummary {
|
|
29
|
+
version: string;
|
|
30
|
+
min_cli_version: string;
|
|
31
|
+
manifest_sha256: string;
|
|
32
|
+
published_at: string;
|
|
33
|
+
}
|
|
34
|
+
export interface PackVersionListing {
|
|
35
|
+
pack_type: PackType;
|
|
36
|
+
versions: PackVersionSummary[];
|
|
37
|
+
}
|
|
38
|
+
export type PackSource = "network" | "cache-verified" | "cache-offline";
|
|
39
|
+
export interface ResolvedScope {
|
|
40
|
+
id: string;
|
|
41
|
+
label: string;
|
|
42
|
+
description: string;
|
|
43
|
+
content: string;
|
|
44
|
+
}
|
|
45
|
+
export interface ResolvedPack {
|
|
46
|
+
packId: string;
|
|
47
|
+
packType: PackType;
|
|
48
|
+
version: string;
|
|
49
|
+
minCliVersion: string;
|
|
50
|
+
source: PackSource;
|
|
51
|
+
basePath: string;
|
|
52
|
+
baseContent: string;
|
|
53
|
+
scopes: PackScopeEntry[];
|
|
54
|
+
cacheDir: string;
|
|
55
|
+
}
|
|
56
|
+
export declare class PackIntegrityError extends Error {
|
|
57
|
+
constructor(message: string);
|
|
58
|
+
}
|
|
59
|
+
export declare class PackUnavailableError extends Error {
|
|
60
|
+
constructor(message: string);
|
|
61
|
+
}
|
|
62
|
+
export declare class UnknownScopeError extends Error {
|
|
63
|
+
readonly availableScopes: PackScopeEntry[];
|
|
64
|
+
constructor(scopeId: string, availableScopes: PackScopeEntry[]);
|
|
65
|
+
}
|
|
66
|
+
export interface PackRegistryClient {
|
|
67
|
+
listVersions(packType: PackType): Promise<PackVersionListing>;
|
|
68
|
+
getManifest(packType: PackType, version: string): Promise<PackManifestV1>;
|
|
69
|
+
getContent(packType: PackType, version: string, relativePath: string): Promise<string>;
|
|
70
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export class PackIntegrityError extends Error {
|
|
2
|
+
constructor(message) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = "PackIntegrityError";
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
export class PackUnavailableError extends Error {
|
|
8
|
+
constructor(message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = "PackUnavailableError";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export class UnknownScopeError extends Error {
|
|
14
|
+
availableScopes;
|
|
15
|
+
constructor(scopeId, availableScopes) {
|
|
16
|
+
super(`Unknown scope "${scopeId}". Available scopes: ${availableScopes.map((s) => s.id).join(", ") || "(none)"}`);
|
|
17
|
+
this.name = "UnknownScopeError";
|
|
18
|
+
this.availableScopes = availableScopes;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -13,19 +13,25 @@ export async function ensureProjectBinding(opts) {
|
|
|
13
13
|
console.log(" Note: JWT has no org_id — skipping project binding.");
|
|
14
14
|
return;
|
|
15
15
|
}
|
|
16
|
-
|
|
16
|
+
let detected = detectProjectBinding(cwd);
|
|
17
17
|
if (detected?.binding.workosOrgId === jwtOrgId) {
|
|
18
18
|
console.log(`✓ Project binding verified: ${detected.filePath}`);
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
21
21
|
if (detected?.binding.workosOrgId && detected.binding.workosOrgId !== jwtOrgId) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
if (!opts.force) {
|
|
23
|
+
console.error("");
|
|
24
|
+
console.error("[zivis] ERROR: Project binding org mismatches JWT org.");
|
|
25
|
+
console.error(`[zivis] Binding file: ${detected.filePath}`);
|
|
26
|
+
console.error(`[zivis] Binding org: ${detected.binding.workosOrgId}${detected.binding.orgName ? ` (${detected.binding.orgName})` : ""}`);
|
|
27
|
+
console.error(`[zivis] JWT org: ${jwtOrgId}`);
|
|
28
|
+
console.error("[zivis] This should not happen — investigate before proceeding.");
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
const oldLabel = detected.binding.orgName ?? detected.binding.workosOrgId;
|
|
32
|
+
console.log(` Replacing existing binding (was: ${oldLabel})`);
|
|
33
|
+
fs.unlinkSync(detected.filePath);
|
|
34
|
+
detected = null;
|
|
29
35
|
}
|
|
30
36
|
let orgInfo;
|
|
31
37
|
try {
|
|
@@ -93,4 +99,3 @@ export async function ensureProjectBinding(opts) {
|
|
|
93
99
|
console.log(` File: ${bindingPath}`);
|
|
94
100
|
console.log(" Commit this file so future sessions in this repo are org-locked.");
|
|
95
101
|
}
|
|
96
|
-
//# sourceMappingURL=project-binding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function writeRunWorkFile(cwd: string, runId: string, filename: string, data: unknown): string;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { ensureZivisGitignore } from "./zivis-local-state.js";
|
|
4
|
+
export function writeRunWorkFile(cwd, runId, filename, data) {
|
|
5
|
+
ensureZivisGitignore(cwd);
|
|
6
|
+
const dir = path.join(cwd, ".zivis", "work", runId);
|
|
7
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
8
|
+
const filePath = path.join(dir, filename);
|
|
9
|
+
fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n");
|
|
10
|
+
return filePath;
|
|
11
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export interface SecurityContextFinding {
|
|
2
|
+
id: string;
|
|
3
|
+
title: string;
|
|
4
|
+
severity: string;
|
|
5
|
+
status: string;
|
|
6
|
+
owaspId: string | null;
|
|
7
|
+
sourceSubtype: string;
|
|
8
|
+
resourceId: string | null;
|
|
9
|
+
firstDetectedAt: string;
|
|
10
|
+
dispositionAt?: string | null;
|
|
11
|
+
dispositionRef?: string | null;
|
|
12
|
+
}
|
|
13
|
+
export interface SecurityContext {
|
|
14
|
+
application: {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
};
|
|
18
|
+
repo: {
|
|
19
|
+
repoFullName: string;
|
|
20
|
+
defaultBranch: string | null;
|
|
21
|
+
latestKnownCommitSha: string | null;
|
|
22
|
+
revisionSyncedAt: string | null;
|
|
23
|
+
} | null;
|
|
24
|
+
lastTestedGitSha: string | null;
|
|
25
|
+
lastThreatModeledGitSha: string | null;
|
|
26
|
+
openFindings: {
|
|
27
|
+
total: number;
|
|
28
|
+
truncated: boolean;
|
|
29
|
+
items: SecurityContextFinding[];
|
|
30
|
+
};
|
|
31
|
+
findingsAwaitingRetest: {
|
|
32
|
+
total: number;
|
|
33
|
+
truncated: boolean;
|
|
34
|
+
items: SecurityContextFinding[];
|
|
35
|
+
};
|
|
36
|
+
inconclusiveAreas: unknown[];
|
|
37
|
+
weakOrUncoveredAreas: unknown[];
|
|
38
|
+
latestThreatModel: {
|
|
39
|
+
version: number;
|
|
40
|
+
gitCommitSha: string | null;
|
|
41
|
+
updatedAt: string;
|
|
42
|
+
methodology: string | null;
|
|
43
|
+
} | null;
|
|
44
|
+
trustRoomUrl: string | null;
|
|
45
|
+
generatedAt: string;
|
|
46
|
+
gaps: {
|
|
47
|
+
field: string;
|
|
48
|
+
reason: string;
|
|
49
|
+
}[];
|
|
50
|
+
}
|
|
51
|
+
export interface SecurityContextApi {
|
|
52
|
+
get<T>(path: string): Promise<T>;
|
|
53
|
+
}
|
|
54
|
+
export type SecurityContextOutcome = {
|
|
55
|
+
available: true;
|
|
56
|
+
context: SecurityContext;
|
|
57
|
+
} | {
|
|
58
|
+
available: false;
|
|
59
|
+
reason: string;
|
|
60
|
+
};
|
|
61
|
+
export declare function fetchSecurityContext(client: SecurityContextApi, applicationId: string): Promise<SecurityContextOutcome>;
|
|
62
|
+
export declare function renderSecurityContext(outcome: SecurityContextOutcome, format?: "human" | "json"): string;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export async function fetchSecurityContext(client, applicationId) {
|
|
2
|
+
try {
|
|
3
|
+
const context = await client.get(`/api/rt/applications/${encodeURIComponent(applicationId)}/security-context`);
|
|
4
|
+
return { available: true, context };
|
|
5
|
+
}
|
|
6
|
+
catch (err) {
|
|
7
|
+
return { available: false, reason: err instanceof Error ? err.message : String(err) };
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function summarizeFinding(f) {
|
|
11
|
+
return ` - [${f.severity}] ${f.title} (${f.id})${f.owaspId ? ` — ${f.owaspId}` : ""}`;
|
|
12
|
+
}
|
|
13
|
+
export function renderSecurityContext(outcome, format = "human") {
|
|
14
|
+
if (format === "json") {
|
|
15
|
+
return JSON.stringify(outcome, null, 2);
|
|
16
|
+
}
|
|
17
|
+
if (!outcome.available) {
|
|
18
|
+
return `[zivis] No connected security context available (${outcome.reason}). Continuing with local-only context.`;
|
|
19
|
+
}
|
|
20
|
+
const c = outcome.context;
|
|
21
|
+
const lines = [];
|
|
22
|
+
lines.push(`ZIVIS connected security context — ${c.application.name}`);
|
|
23
|
+
if (c.repo) {
|
|
24
|
+
lines.push(`Last known repo commit: ${c.repo.latestKnownCommitSha ?? "unknown"} (${c.repo.repoFullName})`);
|
|
25
|
+
}
|
|
26
|
+
lines.push(c.lastThreatModeledGitSha
|
|
27
|
+
? `Last threat-modeled commit: ${c.lastThreatModeledGitSha}; compare local HEAD using git.`
|
|
28
|
+
: `No prior threat model on record for this Application.`);
|
|
29
|
+
if (c.lastTestedGitSha) {
|
|
30
|
+
lines.push(`Last tested commit: ${c.lastTestedGitSha}; compare local HEAD using git.`);
|
|
31
|
+
}
|
|
32
|
+
if (c.openFindings.total > 0) {
|
|
33
|
+
lines.push(`Prior open findings: ${c.openFindings.total}${c.openFindings.truncated ? ` (showing ${c.openFindings.items.length})` : ""}`);
|
|
34
|
+
c.openFindings.items.forEach((f) => lines.push(summarizeFinding(f)));
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
lines.push(`No prior open findings on record.`);
|
|
38
|
+
}
|
|
39
|
+
if (c.findingsAwaitingRetest.total > 0) {
|
|
40
|
+
lines.push(`Findings claimed fixed but not yet retested: ${c.findingsAwaitingRetest.total}${c.findingsAwaitingRetest.truncated ? ` (showing ${c.findingsAwaitingRetest.items.length})` : ""}`);
|
|
41
|
+
c.findingsAwaitingRetest.items.forEach((f) => lines.push(` - Finding ${f.id} was remediated but has not been retested.${f.dispositionRef ? ` (ref: ${f.dispositionRef})` : ""}`));
|
|
42
|
+
}
|
|
43
|
+
if (c.latestThreatModel) {
|
|
44
|
+
lines.push(`Latest threat model: v${c.latestThreatModel.version}${c.latestThreatModel.methodology ? `, methodology: ${c.latestThreatModel.methodology}` : ""}`);
|
|
45
|
+
}
|
|
46
|
+
if (c.trustRoomUrl) {
|
|
47
|
+
lines.push(`Trust Room: ${c.trustRoomUrl}`);
|
|
48
|
+
}
|
|
49
|
+
return lines.join("\n");
|
|
50
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { InventorySyncInput, InventorySyncProvenance } from "./inventory-sync.js";
|
|
2
|
+
interface OutboxEntryBase {
|
|
3
|
+
id: string;
|
|
4
|
+
queuedAt: string;
|
|
5
|
+
attempts: number;
|
|
6
|
+
lastError: string;
|
|
7
|
+
}
|
|
8
|
+
export interface InventorySyncOutboxEntry extends OutboxEntryBase {
|
|
9
|
+
kind: "inventory-sync";
|
|
10
|
+
applicationId: string;
|
|
11
|
+
input: InventorySyncInput;
|
|
12
|
+
provenance: InventorySyncProvenance;
|
|
13
|
+
}
|
|
14
|
+
export interface DevXRunCompleteOutboxEntry extends OutboxEntryBase {
|
|
15
|
+
kind: "devx-run-complete";
|
|
16
|
+
runId: string;
|
|
17
|
+
contractVersion: string;
|
|
18
|
+
result: unknown;
|
|
19
|
+
}
|
|
20
|
+
export type OutboxEntry = InventorySyncOutboxEntry | DevXRunCompleteOutboxEntry;
|
|
21
|
+
export declare function writeOutboxEntry(cwd: string, params: {
|
|
22
|
+
applicationId: string;
|
|
23
|
+
input: InventorySyncInput;
|
|
24
|
+
provenance: InventorySyncProvenance;
|
|
25
|
+
error: string;
|
|
26
|
+
}): string;
|
|
27
|
+
export declare function writeDevXRunCompleteOutboxEntry(cwd: string, params: {
|
|
28
|
+
runId: string;
|
|
29
|
+
contractVersion: string;
|
|
30
|
+
result: unknown;
|
|
31
|
+
error: string;
|
|
32
|
+
}): string;
|
|
33
|
+
export interface OutboxListing {
|
|
34
|
+
filePath: string;
|
|
35
|
+
entry: OutboxEntry;
|
|
36
|
+
}
|
|
37
|
+
export declare function listOutboxEntries(cwd: string): OutboxListing[];
|
|
38
|
+
export declare function removeOutboxEntry(filePath: string): void;
|
|
39
|
+
export declare function recordOutboxRetryFailure(filePath: string, entry: OutboxEntry, error: string): void;
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import * as crypto from "node:crypto";
|
|
4
|
+
import { ensureZivisGitignore } from "./zivis-local-state.js";
|
|
5
|
+
function outboxDir(cwd) {
|
|
6
|
+
return path.join(cwd, ".zivis", "outbox");
|
|
7
|
+
}
|
|
8
|
+
function writeEntryFile(cwd, entry) {
|
|
9
|
+
ensureZivisGitignore(cwd);
|
|
10
|
+
const dir = outboxDir(cwd);
|
|
11
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
12
|
+
const filePath = path.join(dir, `${entry.queuedAt.replace(/[:.]/g, "-")}-${entry.id.slice(0, 8)}.json`);
|
|
13
|
+
fs.writeFileSync(filePath, JSON.stringify(entry, null, 2) + "\n");
|
|
14
|
+
return filePath;
|
|
15
|
+
}
|
|
16
|
+
export function writeOutboxEntry(cwd, params) {
|
|
17
|
+
const entry = {
|
|
18
|
+
kind: "inventory-sync",
|
|
19
|
+
id: crypto.randomUUID(),
|
|
20
|
+
applicationId: params.applicationId,
|
|
21
|
+
input: params.input,
|
|
22
|
+
provenance: params.provenance,
|
|
23
|
+
queuedAt: new Date().toISOString(),
|
|
24
|
+
attempts: 1,
|
|
25
|
+
lastError: params.error,
|
|
26
|
+
};
|
|
27
|
+
return writeEntryFile(cwd, entry);
|
|
28
|
+
}
|
|
29
|
+
export function writeDevXRunCompleteOutboxEntry(cwd, params) {
|
|
30
|
+
const entry = {
|
|
31
|
+
kind: "devx-run-complete",
|
|
32
|
+
id: crypto.randomUUID(),
|
|
33
|
+
runId: params.runId,
|
|
34
|
+
contractVersion: params.contractVersion,
|
|
35
|
+
result: params.result,
|
|
36
|
+
queuedAt: new Date().toISOString(),
|
|
37
|
+
attempts: 1,
|
|
38
|
+
lastError: params.error,
|
|
39
|
+
};
|
|
40
|
+
return writeEntryFile(cwd, entry);
|
|
41
|
+
}
|
|
42
|
+
export function listOutboxEntries(cwd) {
|
|
43
|
+
const dir = outboxDir(cwd);
|
|
44
|
+
if (!fs.existsSync(dir))
|
|
45
|
+
return [];
|
|
46
|
+
const files = fs.readdirSync(dir).filter((f) => f.endsWith(".json")).sort();
|
|
47
|
+
const listings = [];
|
|
48
|
+
for (const file of files) {
|
|
49
|
+
const filePath = path.join(dir, file);
|
|
50
|
+
try {
|
|
51
|
+
const raw = JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
52
|
+
const entry = (raw.kind ? raw : { ...raw, kind: "inventory-sync" });
|
|
53
|
+
listings.push({ filePath, entry });
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return listings;
|
|
59
|
+
}
|
|
60
|
+
export function removeOutboxEntry(filePath) {
|
|
61
|
+
fs.rmSync(filePath, { force: true });
|
|
62
|
+
}
|
|
63
|
+
export function recordOutboxRetryFailure(filePath, entry, error) {
|
|
64
|
+
const updated = { ...entry, attempts: entry.attempts + 1, lastError: error };
|
|
65
|
+
fs.writeFileSync(filePath, JSON.stringify(updated, null, 2) + "\n");
|
|
66
|
+
}
|
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fetches an Application's auth config from the ZIVIS platform.
|
|
3
|
-
*
|
|
4
|
-
* Phase J.4: replaces the local `~/.config/zivis/target-configs/*.json`
|
|
5
|
-
* file the user previously had to write by hand. The Application's IdP
|
|
6
|
-
* discovery (clientId, domain, mode, scopes) lives on the Application
|
|
7
|
-
* record on the platform; the CLI calls this endpoint to learn how to
|
|
8
|
-
* PKCE-auth, then runs the flow locally and stores tokens in the user's
|
|
9
|
-
* keychain. Tokens never leave the user's machine unless the user
|
|
10
|
-
* explicitly ships them with a scenario-run trigger.
|
|
11
|
-
*/
|
|
12
1
|
import type { TargetAuthConfig, WorkosMode } from "./types.js";
|
|
13
2
|
interface AuthConfigResponse {
|
|
14
3
|
applicationId: string;
|
|
@@ -27,11 +16,5 @@ interface AuthConfigResponse {
|
|
|
27
16
|
error?: string;
|
|
28
17
|
}
|
|
29
18
|
export declare function fetchAuthConfig(applicationId: string, sessionName?: string): Promise<AuthConfigResponse>;
|
|
30
|
-
/**
|
|
31
|
-
* Adapt the platform's auth-config response into the local TargetAuthConfig
|
|
32
|
-
* shape that the existing PKCE flow consumes. Throws when the application
|
|
33
|
-
* isn't OAuth-PKCE-shaped (e.g., static_token, client_credentials) — the
|
|
34
|
-
* caller should give a useful error and direct the user elsewhere.
|
|
35
|
-
*/
|
|
36
19
|
export declare function adaptToWorkosConfig(resp: AuthConfigResponse): TargetAuthConfig;
|
|
37
20
|
export {};
|
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fetches an Application's auth config from the ZIVIS platform.
|
|
3
|
-
*
|
|
4
|
-
* Phase J.4: replaces the local `~/.config/zivis/target-configs/*.json`
|
|
5
|
-
* file the user previously had to write by hand. The Application's IdP
|
|
6
|
-
* discovery (clientId, domain, mode, scopes) lives on the Application
|
|
7
|
-
* record on the platform; the CLI calls this endpoint to learn how to
|
|
8
|
-
* PKCE-auth, then runs the flow locally and stores tokens in the user's
|
|
9
|
-
* keychain. Tokens never leave the user's machine unless the user
|
|
10
|
-
* explicitly ships them with a scenario-run trigger.
|
|
11
|
-
*/
|
|
12
1
|
import { ApiClient } from "@zivis/mcp/api-client";
|
|
13
2
|
import { DEFAULT_CONFIG } from "@zivis/mcp/types";
|
|
14
3
|
export async function fetchAuthConfig(applicationId, sessionName) {
|
|
@@ -18,12 +7,6 @@ export async function fetchAuthConfig(applicationId, sessionName) {
|
|
|
18
7
|
const client = new ApiClient(config);
|
|
19
8
|
return client.request("GET", `/api/applications/${encodeURIComponent(applicationId)}/auth-config`);
|
|
20
9
|
}
|
|
21
|
-
/**
|
|
22
|
-
* Adapt the platform's auth-config response into the local TargetAuthConfig
|
|
23
|
-
* shape that the existing PKCE flow consumes. Throws when the application
|
|
24
|
-
* isn't OAuth-PKCE-shaped (e.g., static_token, client_credentials) — the
|
|
25
|
-
* caller should give a useful error and direct the user elsewhere.
|
|
26
|
-
*/
|
|
27
10
|
export function adaptToWorkosConfig(resp) {
|
|
28
11
|
if (!resp.oauth) {
|
|
29
12
|
throw new Error(resp.hint || resp.error ||
|
|
@@ -37,4 +20,3 @@ export function adaptToWorkosConfig(resp) {
|
|
|
37
20
|
extraScopes: resp.oauth.scopes,
|
|
38
21
|
};
|
|
39
22
|
}
|
|
40
|
-
//# sourceMappingURL=api-config.js.map
|
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Target-auth config storage (local-only, v1).
|
|
3
|
-
*
|
|
4
|
-
* Per-target IdP config (domain, client_id, mode, callback port) lives under
|
|
5
|
-
* `~/.config/zivis/target-configs/<targetId>.json`. This is *config*, not
|
|
6
|
-
* credentials — safe to commit a sanitized version to your repo if you want
|
|
7
|
-
* teammates to share it.
|
|
8
|
-
*
|
|
9
|
-
* v2: ZIVIS will serve target-auth config from the API so any team member's
|
|
10
|
-
* CLI can discover it. For now, configure once locally with `zivis target
|
|
11
|
-
* configure` and check in the file if you want it shared.
|
|
12
|
-
*/
|
|
13
1
|
import type { TargetAuthConfig } from "./types.js";
|
|
14
2
|
export declare function loadTargetConfig(targetId: string): Promise<TargetAuthConfig | null>;
|
|
15
3
|
export declare function saveTargetConfig(targetId: string, cfg: TargetAuthConfig): Promise<string>;
|
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Target-auth config storage (local-only, v1).
|
|
3
|
-
*
|
|
4
|
-
* Per-target IdP config (domain, client_id, mode, callback port) lives under
|
|
5
|
-
* `~/.config/zivis/target-configs/<targetId>.json`. This is *config*, not
|
|
6
|
-
* credentials — safe to commit a sanitized version to your repo if you want
|
|
7
|
-
* teammates to share it.
|
|
8
|
-
*
|
|
9
|
-
* v2: ZIVIS will serve target-auth config from the API so any team member's
|
|
10
|
-
* CLI can discover it. For now, configure once locally with `zivis target
|
|
11
|
-
* configure` and check in the file if you want it shared.
|
|
12
|
-
*/
|
|
13
1
|
import * as fs from "node:fs/promises";
|
|
14
2
|
import * as path from "node:path";
|
|
15
3
|
import * as os from "node:os";
|
|
@@ -55,4 +43,3 @@ export async function listTargetConfigs() {
|
|
|
55
43
|
export function getConfigPath(targetId) {
|
|
56
44
|
return configPath(targetId);
|
|
57
45
|
}
|
|
58
|
-
//# sourceMappingURL=config.js.map
|
|
@@ -1,23 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Target-auth orchestrator: load config, run the right IdP flow, manage tokens.
|
|
3
|
-
*
|
|
4
|
-
* Public API:
|
|
5
|
-
* getValidTargetToken(targetId, persona) — returns access_token; refreshes if near expiry
|
|
6
|
-
* loginTarget(targetId, persona) — runs the appropriate IdP flow
|
|
7
|
-
* logoutTarget(targetId, persona) — clears stored tokens
|
|
8
|
-
*
|
|
9
|
-
* Designed so RT-runner-side ephemeral cred plumbing only sees a flat
|
|
10
|
-
* { accessToken, refreshToken?, expiresAt, idpType } bundle — no IdP
|
|
11
|
-
* specifics leak past this boundary.
|
|
12
|
-
*/
|
|
13
1
|
import type { EphemeralTargetCreds, TargetTokens } from "./types.js";
|
|
14
2
|
export declare function loginTarget(targetId: string, persona: string): Promise<TargetTokens>;
|
|
15
|
-
/**
|
|
16
|
-
* J.4 path: log in against an Application by id. Auth config comes from
|
|
17
|
-
* the platform (no local config file required). Tokens are stored under
|
|
18
|
-
* the existing keychain namespace using applicationId as the key — same
|
|
19
|
-
* keychain layout, no migration needed for already-stored tokens.
|
|
20
|
-
*/
|
|
21
3
|
export declare function loginApplication(applicationId: string, persona: string, sessionName?: string): Promise<TargetTokens>;
|
|
22
4
|
export declare function logoutTarget(targetId: string, persona: string): Promise<void>;
|
|
23
5
|
export declare function getValidTargetToken(targetId: string, persona: string): Promise<TargetTokens | null>;
|
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Target-auth orchestrator: load config, run the right IdP flow, manage tokens.
|
|
3
|
-
*
|
|
4
|
-
* Public API:
|
|
5
|
-
* getValidTargetToken(targetId, persona) — returns access_token; refreshes if near expiry
|
|
6
|
-
* loginTarget(targetId, persona) — runs the appropriate IdP flow
|
|
7
|
-
* logoutTarget(targetId, persona) — clears stored tokens
|
|
8
|
-
*
|
|
9
|
-
* Designed so RT-runner-side ephemeral cred plumbing only sees a flat
|
|
10
|
-
* { accessToken, refreshToken?, expiresAt, idpType } bundle — no IdP
|
|
11
|
-
* specifics leak past this boundary.
|
|
12
|
-
*/
|
|
13
1
|
import { loadTargetConfig } from "./config.js";
|
|
14
2
|
import { loadTokens, storeTokens, deleteTokens } from "./keychain.js";
|
|
15
3
|
import { loginWorkos, refreshWorkos } from "./workos.js";
|
|
@@ -21,12 +9,6 @@ export async function loginTarget(targetId, persona) {
|
|
|
21
9
|
await storeTokens(targetId, persona, tokens);
|
|
22
10
|
return tokens;
|
|
23
11
|
}
|
|
24
|
-
/**
|
|
25
|
-
* J.4 path: log in against an Application by id. Auth config comes from
|
|
26
|
-
* the platform (no local config file required). Tokens are stored under
|
|
27
|
-
* the existing keychain namespace using applicationId as the key — same
|
|
28
|
-
* keychain layout, no migration needed for already-stored tokens.
|
|
29
|
-
*/
|
|
30
12
|
export async function loginApplication(applicationId, persona, sessionName) {
|
|
31
13
|
const resp = await fetchAuthConfig(applicationId, sessionName);
|
|
32
14
|
const cfg = adaptToWorkosConfig(resp);
|
|
@@ -98,4 +80,3 @@ async function runRefresh(cfg, refreshToken) {
|
|
|
98
80
|
throw new Error(`Unsupported IdP type: ${cfg.type}`);
|
|
99
81
|
}
|
|
100
82
|
}
|
|
101
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Target-auth keychain.
|
|
3
|
-
*
|
|
4
|
-
* Distinct namespace from the user's ZIVIS-platform tokens (handled by
|
|
5
|
-
* `zivis-mcp-security`'s keychain module). A user can be logged into
|
|
6
|
-
* ZIVIS itself AND to N customer-target IdPs simultaneously, each with
|
|
7
|
-
* multiple personas (admin, user_a, …) for permutation testing.
|
|
8
|
-
*
|
|
9
|
-
* Storage layout
|
|
10
|
-
* service: zivis.target.<targetId>.<persona>
|
|
11
|
-
* account: zivis-target
|
|
12
|
-
* value: JSON-serialised TargetTokens
|
|
13
|
-
*
|
|
14
|
-
* macOS-only for v1 (matches the engagement helper). Linux/Windows fall
|
|
15
|
-
* back to an encrypted file on disk; the underlying impl lives in
|
|
16
|
-
* `@zivis/mcp/auth/keychain.ts` for the platform login — we
|
|
17
|
-
* deliberately don't share that module to keep the namespaces isolated.
|
|
18
|
-
*/
|
|
19
1
|
import type { TargetTokens } from "./types.js";
|
|
20
2
|
export declare function storeTokens(targetId: string, persona: string, tokens: TargetTokens): Promise<void>;
|
|
21
3
|
export declare function loadTokens(targetId: string, persona: string): Promise<TargetTokens | null>;
|