@praxis.guard/auditor-cli 0.0.17 → 0.0.19
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/README.md +23 -1
- package/dist/approval/argv-fingerprint.d.ts +2 -0
- package/dist/approval/argv-fingerprint.d.ts.map +1 -0
- package/dist/approval/argv-fingerprint.js +2 -0
- package/dist/approval/argv-fingerprint.js.map +1 -0
- package/dist/approval/client.d.ts +35 -0
- package/dist/approval/client.d.ts.map +1 -0
- package/dist/approval/client.js +117 -0
- package/dist/approval/client.js.map +1 -0
- package/dist/approval/grant.d.ts +6 -0
- package/dist/approval/grant.d.ts.map +1 -0
- package/dist/approval/grant.js +78 -0
- package/dist/approval/grant.js.map +1 -0
- package/dist/approval/mcp-flow.d.ts +41 -0
- package/dist/approval/mcp-flow.d.ts.map +1 -0
- package/dist/approval/mcp-flow.js +116 -0
- package/dist/approval/mcp-flow.js.map +1 -0
- package/dist/approval/redeem.d.ts +21 -0
- package/dist/approval/redeem.d.ts.map +1 -0
- package/dist/approval/redeem.js +67 -0
- package/dist/approval/redeem.js.map +1 -0
- package/dist/approval/types.d.ts +53 -0
- package/dist/approval/types.d.ts.map +1 -0
- package/dist/approval/types.js +2 -0
- package/dist/approval/types.js.map +1 -0
- package/dist/bridge/execution-ticket.d.ts +17 -0
- package/dist/bridge/execution-ticket.d.ts.map +1 -0
- package/dist/bridge/execution-ticket.js +91 -0
- package/dist/bridge/execution-ticket.js.map +1 -0
- package/dist/bridge/shell-approval-bridge.d.ts +1 -1
- package/dist/bridge/shell-approval-bridge.d.ts.map +1 -1
- package/dist/bridge/shell-approval-bridge.js +9 -1
- package/dist/bridge/shell-approval-bridge.js.map +1 -1
- package/dist/cli/approvals.d.ts +2 -0
- package/dist/cli/approvals.d.ts.map +1 -0
- package/dist/cli/approvals.js +78 -0
- package/dist/cli/approvals.js.map +1 -0
- package/dist/cli/cursor-config.d.ts +5 -0
- package/dist/cli/cursor-config.d.ts.map +1 -1
- package/dist/cli/cursor-config.js +118 -13
- package/dist/cli/cursor-config.js.map +1 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +2 -0
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +19 -2
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/setup-doctor.d.ts.map +1 -1
- package/dist/cli/setup-doctor.js +57 -7
- package/dist/cli/setup-doctor.js.map +1 -1
- package/dist/hooks/agent-message.d.ts +19 -0
- package/dist/hooks/agent-message.d.ts.map +1 -0
- package/dist/hooks/agent-message.js +48 -0
- package/dist/hooks/agent-message.js.map +1 -0
- package/dist/hooks/run-before-mcp.d.ts.map +1 -1
- package/dist/hooks/run-before-mcp.js +27 -9
- package/dist/hooks/run-before-mcp.js.map +1 -1
- package/dist/hooks/run-before-shell.d.ts.map +1 -1
- package/dist/hooks/run-before-shell.js +24 -9
- package/dist/hooks/run-before-shell.js.map +1 -1
- package/dist/mcp/guard-mode.d.ts +26 -0
- package/dist/mcp/guard-mode.d.ts.map +1 -0
- package/dist/mcp/guard-mode.js +27 -0
- package/dist/mcp/guard-mode.js.map +1 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +243 -149
- package/dist/mcp/server.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,7 +11,29 @@ Use one built binary for **MCP stdio**, **Cursor hook**, and diagnostics:
|
|
|
11
11
|
| **MCP** (`mcp.json`) | `auditor` + args `["mcp"]`, or `node …/auditor-cli/dist/cli.js mcp` |
|
|
12
12
|
| **Hook** (`.cursor/hooks.json`) | `node …/auditor-cli/dist/cli.js hook before-shell` (or `auditor hook before-shell` if `auditor` is on `PATH`) |
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Legacy configs that still reference `guard-mcp` are migrated by `auditor setup all` / `auditor setup doctor`.
|
|
15
|
+
|
|
16
|
+
## MUTATE human approval
|
|
17
|
+
|
|
18
|
+
Hooks **enforce** (deny without bridge). MCP **`guard`** / **`guard_wait`** **coordinate**: create `approval_requests` in Cloud Functions, human approves in the Praxis app (or dev: `auditor approvals approve` with `GUARD_APPROVAL_DEV=1`), then redeem grant and write the one-shot `.cursor/guard/bridge` file.
|
|
19
|
+
|
|
20
|
+
### MCP `mode`: shadow vs enforce
|
|
21
|
+
|
|
22
|
+
Both tools require `mode` in the JSON payload:
|
|
23
|
+
|
|
24
|
+
| `mode` | Behavior |
|
|
25
|
+
|--------|----------|
|
|
26
|
+
| **`shadow`** | Dry-run. Response `decision` is always `allow` (non-blocking). Field `shadow` carries the policy verdict (`allow` / `require_approval` / `block`). No approval requests are created. |
|
|
27
|
+
| **`enforce`** | Coordination. Response `decision` is the real outcome (may call the approval backend for MUTATE). Field `shadow` carries the policy-only verdict (what would apply before grant redemption). |
|
|
28
|
+
|
|
29
|
+
`guard_wait` always runs in **enforce** semantics (poll + redeem). Typical flow: `guard` with `mode: "enforce"` → human approves → `guard_wait` with `context.approval.request_id` and `context.wait_ms`.
|
|
30
|
+
|
|
31
|
+
Smoke examples (after `pnpm -C packages/auditor-cli build`):
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
node scripts/guard-smoke.mjs shadow gcloud compute instances list
|
|
35
|
+
node scripts/guard-smoke.mjs enforce gcloud compute instances delete example-vm
|
|
36
|
+
```
|
|
15
37
|
|
|
16
38
|
## Policy source of truth
|
|
17
39
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"argv-fingerprint.d.ts","sourceRoot":"","sources":["../../src/approval/argv-fingerprint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,IAAI,UAAU,EAAE,MAAM,oCAAoC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"argv-fingerprint.js","sourceRoot":"","sources":["../../src/approval/argv-fingerprint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,IAAI,UAAU,EAAE,MAAM,oCAAoC,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ApprovalRequestRecord, CreateApprovalRequestInput } from "./types.js";
|
|
2
|
+
export declare function createApprovalRequest(input: CreateApprovalRequestInput): Promise<{
|
|
3
|
+
request_id: string;
|
|
4
|
+
open_url: string;
|
|
5
|
+
expires_at: string;
|
|
6
|
+
}>;
|
|
7
|
+
export declare function getApprovalRequest(requestId: string): Promise<ApprovalRequestRecord>;
|
|
8
|
+
export declare function pollUntilApproved(requestId: string, opts?: {
|
|
9
|
+
timeoutMs?: number;
|
|
10
|
+
intervalMs?: number;
|
|
11
|
+
}): Promise<ApprovalRequestRecord>;
|
|
12
|
+
export declare function redeemApprovalGrant(input: {
|
|
13
|
+
request_id: string;
|
|
14
|
+
grant: string;
|
|
15
|
+
install_id: string;
|
|
16
|
+
argv: string[];
|
|
17
|
+
}): Promise<{
|
|
18
|
+
redeemed: boolean;
|
|
19
|
+
approved_by: string | null;
|
|
20
|
+
execution_ticket: string | null;
|
|
21
|
+
}>;
|
|
22
|
+
export declare function listApprovalRequests(status?: string): Promise<Array<{
|
|
23
|
+
request_id: string;
|
|
24
|
+
status: string;
|
|
25
|
+
raw_display?: string;
|
|
26
|
+
open_url?: string;
|
|
27
|
+
expires_at?: string;
|
|
28
|
+
}>>;
|
|
29
|
+
export declare function issueApprovalDecision(requestId: string, decision: "approved" | "denied", opts?: {
|
|
30
|
+
idToken?: string;
|
|
31
|
+
}): Promise<{
|
|
32
|
+
grant?: string;
|
|
33
|
+
status: string;
|
|
34
|
+
}>;
|
|
35
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/approval/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAyBpF,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,0BAA0B,GAChC,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAcvE;AAED,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAS1F;AAED,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GACjD,OAAO,CAAC,qBAAqB,CAAC,CAahC;AAED,wBAAsB,mBAAmB,CAAC,KAAK,EAAE;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,GAAG,OAAO,CAAC;IACV,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC,CAAC,CAeD;AAED,wBAAsB,oBAAoB,CAAC,MAAM,SAAY,GAAG,OAAO,CACrE,KAAK,CAAC;IACJ,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC,CACH,CAeA;AAED,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,UAAU,GAAG,QAAQ,EAC/B,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1B,OAAO,CAAC;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAqB7C"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { resolveGuardToken } from "../cli/credentials.js";
|
|
2
|
+
import { prodFunctionUrl } from "../cli/function-url.js";
|
|
3
|
+
function approvalUrl(name) {
|
|
4
|
+
const override = process.env[`PRAXIS_GUARD_APPROVAL_${name.toUpperCase()}_URL`];
|
|
5
|
+
if (override?.trim())
|
|
6
|
+
return override.trim();
|
|
7
|
+
return prodFunctionUrl(name);
|
|
8
|
+
}
|
|
9
|
+
async function authFetch(url, init) {
|
|
10
|
+
const token = resolveGuardToken();
|
|
11
|
+
if (!token)
|
|
12
|
+
throw new Error("Not authenticated. Run `auditor login` or set PRAXIS_GUARD_TOKEN.");
|
|
13
|
+
return fetch(url, {
|
|
14
|
+
...init,
|
|
15
|
+
headers: {
|
|
16
|
+
Authorization: `Bearer ${token}`,
|
|
17
|
+
"Content-Type": "application/json",
|
|
18
|
+
...(init.headers ?? {}),
|
|
19
|
+
},
|
|
20
|
+
signal: AbortSignal.timeout(8000),
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
export async function createApprovalRequest(input) {
|
|
24
|
+
const res = await authFetch(approvalUrl("guardApprovalRequest"), {
|
|
25
|
+
method: "POST",
|
|
26
|
+
body: JSON.stringify(input),
|
|
27
|
+
});
|
|
28
|
+
const data = (await res.json().catch(() => ({})));
|
|
29
|
+
if (!res.ok) {
|
|
30
|
+
throw new Error(typeof data.error === "string" ? data.error : `create failed (${res.status})`);
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
request_id: String(data.request_id),
|
|
34
|
+
open_url: String(data.open_url),
|
|
35
|
+
expires_at: String(data.expires_at),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export async function getApprovalRequest(requestId) {
|
|
39
|
+
const url = `${approvalUrl("guardApprovalGet")}?id=${encodeURIComponent(requestId)}`;
|
|
40
|
+
const res = await authFetch(url, { method: "GET" });
|
|
41
|
+
const data = (await res.json().catch(() => ({})));
|
|
42
|
+
if (!res.ok) {
|
|
43
|
+
throw new Error(typeof data.error === "string" ? data.error : `get failed (${res.status})`);
|
|
44
|
+
}
|
|
45
|
+
const req = data.request;
|
|
46
|
+
return req;
|
|
47
|
+
}
|
|
48
|
+
export async function pollUntilApproved(requestId, opts) {
|
|
49
|
+
const timeoutMs = opts?.timeoutMs ?? 5 * 60 * 1000;
|
|
50
|
+
const intervalMs = opts?.intervalMs ?? 2000;
|
|
51
|
+
const deadline = Date.now() + timeoutMs;
|
|
52
|
+
while (Date.now() < deadline) {
|
|
53
|
+
const row = await getApprovalRequest(requestId);
|
|
54
|
+
if (row.status === "denied")
|
|
55
|
+
throw new Error("approval_denied");
|
|
56
|
+
if (row.status === "expired")
|
|
57
|
+
throw new Error("approval_expired");
|
|
58
|
+
if (row.status === "approved")
|
|
59
|
+
return row;
|
|
60
|
+
await new Promise((r) => setTimeout(r, intervalMs));
|
|
61
|
+
}
|
|
62
|
+
throw new Error("approval_timeout");
|
|
63
|
+
}
|
|
64
|
+
export async function redeemApprovalGrant(input) {
|
|
65
|
+
const res = await authFetch(approvalUrl("guardApprovalRedeem"), {
|
|
66
|
+
method: "POST",
|
|
67
|
+
body: JSON.stringify(input),
|
|
68
|
+
});
|
|
69
|
+
const data = (await res.json().catch(() => ({})));
|
|
70
|
+
if (!res.ok) {
|
|
71
|
+
throw new Error(typeof data.error === "string" ? data.error : `redeem failed (${res.status})`);
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
redeemed: Boolean(data.redeemed),
|
|
75
|
+
approved_by: typeof data.approved_by === "string" ? data.approved_by : null,
|
|
76
|
+
execution_ticket: typeof data.execution_ticket === "string" ? data.execution_ticket : null,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export async function listApprovalRequests(status = "pending") {
|
|
80
|
+
const url = `${approvalUrl("guardApprovalList")}?status=${encodeURIComponent(status)}`;
|
|
81
|
+
const res = await authFetch(url, { method: "GET" });
|
|
82
|
+
const data = (await res.json().catch(() => ({})));
|
|
83
|
+
if (!res.ok) {
|
|
84
|
+
throw new Error(typeof data.error === "string" ? data.error : `list failed (${res.status})`);
|
|
85
|
+
}
|
|
86
|
+
const raw = data.requests ?? [];
|
|
87
|
+
return raw.map((r) => ({
|
|
88
|
+
request_id: String(r.request_id),
|
|
89
|
+
status: String(r.status),
|
|
90
|
+
raw_display: typeof r.raw_display === "string" ? r.raw_display : undefined,
|
|
91
|
+
open_url: typeof r.open_url === "string" ? r.open_url : undefined,
|
|
92
|
+
expires_at: typeof r.expires_at === "string" ? r.expires_at : undefined,
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
95
|
+
export async function issueApprovalDecision(requestId, decision, opts) {
|
|
96
|
+
const token = opts?.idToken ?? resolveGuardToken();
|
|
97
|
+
if (!token)
|
|
98
|
+
throw new Error("Not authenticated");
|
|
99
|
+
const res = await fetch(approvalUrl("guardApprovalIssue"), {
|
|
100
|
+
method: "POST",
|
|
101
|
+
headers: {
|
|
102
|
+
Authorization: `Bearer ${token}`,
|
|
103
|
+
"Content-Type": "application/json",
|
|
104
|
+
},
|
|
105
|
+
body: JSON.stringify({ request_id: requestId, decision }),
|
|
106
|
+
signal: AbortSignal.timeout(8000),
|
|
107
|
+
});
|
|
108
|
+
const data = (await res.json().catch(() => ({})));
|
|
109
|
+
if (!res.ok) {
|
|
110
|
+
throw new Error(typeof data.error === "string" ? data.error : `issue failed (${res.status})`);
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
status: String(data.status),
|
|
114
|
+
grant: typeof data.grant === "string" ? data.grant : undefined,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/approval/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ApprovalGrantClaims, ExecutionTicketClaims } from "./types.js";
|
|
2
|
+
/** Verify a server-issued approval grant JWT (HS256). */
|
|
3
|
+
export declare function verifyApprovalGrant(token: string): ApprovalGrantClaims | null;
|
|
4
|
+
/** Verify a server-issued execution ticket JWT (HS256) for hook one-shot allow. */
|
|
5
|
+
export declare function verifyExecutionTicket(token: string): ExecutionTicketClaims | null;
|
|
6
|
+
//# sourceMappingURL=grant.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grant.d.ts","sourceRoot":"","sources":["../../src/approval/grant.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAoB7E,yDAAyD;AACzD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAkB7E;AAED,mFAAmF;AACnF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,qBAAqB,GAAG,IAAI,CAqBjF"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
2
|
+
function base64urlDecodeJson(segment) {
|
|
3
|
+
try {
|
|
4
|
+
const raw = Buffer.from(segment, "base64url").toString("utf8");
|
|
5
|
+
return JSON.parse(raw);
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function approvalJwtSecret() {
|
|
12
|
+
const fromEnv = process.env.GUARD_APPROVAL_JWT_SECRET?.trim();
|
|
13
|
+
if (fromEnv)
|
|
14
|
+
return fromEnv;
|
|
15
|
+
if (process.env.PRAXIS_FIREBASE_FUNCTIONS_EMULATOR_HOST?.trim()) {
|
|
16
|
+
return "praxis-guard-approval-dev-secret";
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
/** Verify a server-issued approval grant JWT (HS256). */
|
|
21
|
+
export function verifyApprovalGrant(token) {
|
|
22
|
+
const parts = token.split(".");
|
|
23
|
+
if (parts.length !== 3)
|
|
24
|
+
return null;
|
|
25
|
+
const secret = approvalJwtSecret();
|
|
26
|
+
if (!secret)
|
|
27
|
+
return null;
|
|
28
|
+
const [header, body, sig] = parts;
|
|
29
|
+
const expected = createHmac("sha256", secret).update(`${header}.${body}`).digest("base64url");
|
|
30
|
+
try {
|
|
31
|
+
const a = Buffer.from(sig, "utf8");
|
|
32
|
+
const b = Buffer.from(expected, "utf8");
|
|
33
|
+
if (a.length !== b.length || !timingSafeEqual(a, b))
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
const payload = base64urlDecodeJson(body);
|
|
40
|
+
if (!payload || payload.typ !== "approval")
|
|
41
|
+
return null;
|
|
42
|
+
if (typeof payload.exp !== "number" || payload.exp * 1000 < Date.now())
|
|
43
|
+
return null;
|
|
44
|
+
return payload;
|
|
45
|
+
}
|
|
46
|
+
/** Verify a server-issued execution ticket JWT (HS256) for hook one-shot allow. */
|
|
47
|
+
export function verifyExecutionTicket(token) {
|
|
48
|
+
const parts = token.split(".");
|
|
49
|
+
if (parts.length !== 3)
|
|
50
|
+
return null;
|
|
51
|
+
const secret = approvalJwtSecret();
|
|
52
|
+
if (!secret)
|
|
53
|
+
return null;
|
|
54
|
+
const [header, body, sig] = parts;
|
|
55
|
+
const expected = createHmac("sha256", secret).update(`${header}.${body}`).digest("base64url");
|
|
56
|
+
try {
|
|
57
|
+
const a = Buffer.from(sig, "utf8");
|
|
58
|
+
const b = Buffer.from(expected, "utf8");
|
|
59
|
+
if (a.length !== b.length || !timingSafeEqual(a, b))
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
const payload = base64urlDecodeJson(body);
|
|
66
|
+
if (!payload || payload.typ !== "execution")
|
|
67
|
+
return null;
|
|
68
|
+
if (typeof payload.exp !== "number" || payload.exp * 1000 < Date.now())
|
|
69
|
+
return null;
|
|
70
|
+
if (payload.kind !== "shell" && payload.kind !== "mcp")
|
|
71
|
+
return null;
|
|
72
|
+
if (typeof payload.request_id !== "string" || typeof payload.argv_sha256 !== "string")
|
|
73
|
+
return null;
|
|
74
|
+
if (typeof payload.install_id !== "string" || typeof payload.jti !== "string")
|
|
75
|
+
return null;
|
|
76
|
+
return payload;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=grant.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grant.js","sourceRoot":"","sources":["../../src/approval/grant.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { argvSha256 } from "./argv-fingerprint.js";
|
|
2
|
+
export type McpApprovalContext = {
|
|
3
|
+
request_id?: string | null;
|
|
4
|
+
grant?: string | null;
|
|
5
|
+
};
|
|
6
|
+
export type McpApprovalOutcome = {
|
|
7
|
+
kind: "require_approval";
|
|
8
|
+
request_id: string;
|
|
9
|
+
open_url: string;
|
|
10
|
+
expires_at: string;
|
|
11
|
+
} | {
|
|
12
|
+
kind: "allow";
|
|
13
|
+
redeemed: boolean;
|
|
14
|
+
approved_by: string | null;
|
|
15
|
+
bridgeRecorded: boolean;
|
|
16
|
+
ticketRecorded: boolean;
|
|
17
|
+
request_id: string;
|
|
18
|
+
} | {
|
|
19
|
+
kind: "credential_not_recorded";
|
|
20
|
+
request_id: string;
|
|
21
|
+
message: string;
|
|
22
|
+
} | {
|
|
23
|
+
kind: "backend_unavailable";
|
|
24
|
+
message: string;
|
|
25
|
+
};
|
|
26
|
+
export declare function resolveMutateApproval(input: {
|
|
27
|
+
argv: string[];
|
|
28
|
+
proposalKind: "shell" | "mcp";
|
|
29
|
+
cwd?: string;
|
|
30
|
+
rawDisplay?: string;
|
|
31
|
+
eventId: string;
|
|
32
|
+
policyRevision: number | null;
|
|
33
|
+
reasons: unknown[];
|
|
34
|
+
sessionId?: string | null;
|
|
35
|
+
environment?: string | null;
|
|
36
|
+
approval?: McpApprovalContext | null;
|
|
37
|
+
waitMs?: number | null;
|
|
38
|
+
}): Promise<McpApprovalOutcome>;
|
|
39
|
+
export declare function argvFingerprint(argv: readonly string[]): string;
|
|
40
|
+
export { argvSha256 };
|
|
41
|
+
//# sourceMappingURL=mcp-flow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-flow.d.ts","sourceRoot":"","sources":["../../src/approval/mcp-flow.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AASnD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAC1B;IACE,IAAI,EAAE,kBAAkB,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB,GACD;IACE,IAAI,EAAE,yBAAyB,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB,GACD;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAMrD,wBAAsB,qBAAqB,CAAC,KAAK,EAAE;IACjD,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,YAAY,EAAE,OAAO,GAAG,KAAK,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAiH9B;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAE/D;AAED,OAAO,EAAE,UAAU,EAAE,CAAC"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { getInstallId } from "../cli/install-id.js";
|
|
2
|
+
import { argvSha256 } from "./argv-fingerprint.js";
|
|
3
|
+
import { createApprovalRequest, getApprovalRequest, pollUntilApproved, } from "./client.js";
|
|
4
|
+
import { redeemApprovalAndRecordBridge } from "./redeem.js";
|
|
5
|
+
import { verifyApprovalGrant } from "./grant.js";
|
|
6
|
+
function defaultAppUrl() {
|
|
7
|
+
return process.env.PRAXIS_APP_URL?.trim() || "https://app.usepraxis.tech";
|
|
8
|
+
}
|
|
9
|
+
export async function resolveMutateApproval(input) {
|
|
10
|
+
const installId = getInstallId();
|
|
11
|
+
const requestId = input.approval?.request_id?.trim() || null;
|
|
12
|
+
const grant = input.approval?.grant?.trim() || null;
|
|
13
|
+
try {
|
|
14
|
+
if (requestId) {
|
|
15
|
+
if (grant) {
|
|
16
|
+
const claims = verifyApprovalGrant(grant);
|
|
17
|
+
if (!claims || claims.request_id !== requestId) {
|
|
18
|
+
return { kind: "backend_unavailable", message: "invalid_grant" };
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const row = grant ? null : await getApprovalRequest(requestId);
|
|
22
|
+
const status = grant ? "approved" : row?.status;
|
|
23
|
+
if (status === "pending" && input.waitMs && input.waitMs > 0) {
|
|
24
|
+
await pollUntilApproved(requestId, { timeoutMs: input.waitMs });
|
|
25
|
+
}
|
|
26
|
+
else if (status === "pending") {
|
|
27
|
+
return {
|
|
28
|
+
kind: "require_approval",
|
|
29
|
+
request_id: requestId,
|
|
30
|
+
open_url: row?.open_url ?? `${defaultAppUrl().replace(/\/$/, "")}/app/approvals/${requestId}`,
|
|
31
|
+
expires_at: row?.expires_at ?? new Date(Date.now() + 30 * 60 * 1000).toISOString(),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
if (status === "denied") {
|
|
35
|
+
return { kind: "backend_unavailable", message: "approval_denied" };
|
|
36
|
+
}
|
|
37
|
+
const redeem = await redeemApprovalAndRecordBridge({
|
|
38
|
+
request_id: requestId,
|
|
39
|
+
argv: input.argv,
|
|
40
|
+
kind: input.proposalKind,
|
|
41
|
+
cwd: input.cwd,
|
|
42
|
+
grant,
|
|
43
|
+
environment: input.environment,
|
|
44
|
+
session_id: input.sessionId,
|
|
45
|
+
});
|
|
46
|
+
if (!redeem.bridgeRecorded && !redeem.ticketRecorded) {
|
|
47
|
+
return {
|
|
48
|
+
kind: "credential_not_recorded",
|
|
49
|
+
request_id: requestId,
|
|
50
|
+
message: "Approval redeemed but no hook credential was written (bridge and execution ticket both failed).",
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
kind: "allow",
|
|
55
|
+
redeemed: redeem.redeemed,
|
|
56
|
+
approved_by: redeem.approved_by,
|
|
57
|
+
bridgeRecorded: redeem.bridgeRecorded,
|
|
58
|
+
ticketRecorded: redeem.ticketRecorded,
|
|
59
|
+
request_id: requestId,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const created = await createApprovalRequest({
|
|
63
|
+
kind: input.proposalKind,
|
|
64
|
+
tier: "MUTATE",
|
|
65
|
+
argv: [...input.argv],
|
|
66
|
+
install_id: installId,
|
|
67
|
+
session_id: input.sessionId ?? null,
|
|
68
|
+
environment: input.environment ?? null,
|
|
69
|
+
raw_display: input.rawDisplay ?? input.argv.join(" "),
|
|
70
|
+
event_id: input.eventId,
|
|
71
|
+
policy_revision: input.policyRevision,
|
|
72
|
+
reasons: input.reasons,
|
|
73
|
+
});
|
|
74
|
+
if (input.waitMs && input.waitMs > 0) {
|
|
75
|
+
await pollUntilApproved(created.request_id, { timeoutMs: input.waitMs });
|
|
76
|
+
const redeem = await redeemApprovalAndRecordBridge({
|
|
77
|
+
request_id: created.request_id,
|
|
78
|
+
argv: input.argv,
|
|
79
|
+
kind: input.proposalKind,
|
|
80
|
+
cwd: input.cwd,
|
|
81
|
+
environment: input.environment,
|
|
82
|
+
session_id: input.sessionId,
|
|
83
|
+
});
|
|
84
|
+
if (!redeem.bridgeRecorded && !redeem.ticketRecorded) {
|
|
85
|
+
return {
|
|
86
|
+
kind: "credential_not_recorded",
|
|
87
|
+
request_id: created.request_id,
|
|
88
|
+
message: "Approval redeemed but no hook credential was written (bridge and execution ticket both failed).",
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
kind: "allow",
|
|
93
|
+
redeemed: redeem.redeemed,
|
|
94
|
+
approved_by: redeem.approved_by,
|
|
95
|
+
bridgeRecorded: redeem.bridgeRecorded,
|
|
96
|
+
ticketRecorded: redeem.ticketRecorded,
|
|
97
|
+
request_id: created.request_id,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
kind: "require_approval",
|
|
102
|
+
request_id: created.request_id,
|
|
103
|
+
open_url: created.open_url,
|
|
104
|
+
expires_at: created.expires_at,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
catch (e) {
|
|
108
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
109
|
+
return { kind: "backend_unavailable", message: msg };
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
export function argvFingerprint(argv) {
|
|
113
|
+
return JSON.stringify(argv);
|
|
114
|
+
}
|
|
115
|
+
export { argvSha256 };
|
|
116
|
+
//# sourceMappingURL=mcp-flow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-flow.js","sourceRoot":"","sources":["../../src/approval/mcp-flow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type RedeemAndBridgeInput = {
|
|
2
|
+
request_id: string;
|
|
3
|
+
argv: string[];
|
|
4
|
+
kind: "shell" | "mcp";
|
|
5
|
+
cwd?: string;
|
|
6
|
+
grant?: string | null;
|
|
7
|
+
environment?: string | null;
|
|
8
|
+
session_id?: string | null;
|
|
9
|
+
};
|
|
10
|
+
export type RedeemAndBridgeResult = {
|
|
11
|
+
redeemed: boolean;
|
|
12
|
+
approved_by: string | null;
|
|
13
|
+
bridgeRecorded: boolean;
|
|
14
|
+
ticketRecorded: boolean;
|
|
15
|
+
execution_ticket: string | null;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* After backend status is `approved`, redeem the one-shot grant and record the local bridge.
|
|
19
|
+
*/
|
|
20
|
+
export declare function redeemApprovalAndRecordBridge(input: RedeemAndBridgeInput): Promise<RedeemAndBridgeResult>;
|
|
21
|
+
//# sourceMappingURL=redeem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redeem.d.ts","sourceRoot":"","sources":["../../src/approval/redeem.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,oBAAoB,GAAG;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,OAAO,GAAG,KAAK,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC,CAAC;AAEF;;GAEG;AACH,wBAAsB,6BAA6B,CACjD,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,qBAAqB,CAAC,CAuDhC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { getInstallId } from "../cli/install-id.js";
|
|
2
|
+
import { recordExecutionTicket } from "../bridge/execution-ticket.js";
|
|
3
|
+
import { recordShellApprovalBridge } from "../bridge/shell-approval-bridge.js";
|
|
4
|
+
import { argvSha256 } from "./argv-fingerprint.js";
|
|
5
|
+
import { getApprovalRequest, redeemApprovalGrant } from "./client.js";
|
|
6
|
+
import { verifyApprovalGrant } from "./grant.js";
|
|
7
|
+
/**
|
|
8
|
+
* After backend status is `approved`, redeem the one-shot grant and record the local bridge.
|
|
9
|
+
*/
|
|
10
|
+
export async function redeemApprovalAndRecordBridge(input) {
|
|
11
|
+
const installId = getInstallId();
|
|
12
|
+
const hash = argvSha256(input.argv);
|
|
13
|
+
let grant = input.grant?.trim() || null;
|
|
14
|
+
if (grant) {
|
|
15
|
+
const claims = verifyApprovalGrant(grant);
|
|
16
|
+
if (!claims)
|
|
17
|
+
throw new Error("invalid_grant");
|
|
18
|
+
if (claims.request_id !== input.request_id)
|
|
19
|
+
throw new Error("request_id_mismatch");
|
|
20
|
+
if (claims.argv_sha256 !== hash)
|
|
21
|
+
throw new Error("argv_mismatch");
|
|
22
|
+
if (claims.install_id !== installId)
|
|
23
|
+
throw new Error("install_id_mismatch");
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
const row = await getApprovalRequest(input.request_id);
|
|
27
|
+
if (row.status !== "approved") {
|
|
28
|
+
throw new Error(`approval_not_ready:${row.status}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const redeem = await redeemApprovalGrant({
|
|
32
|
+
request_id: input.request_id,
|
|
33
|
+
grant: grant ?? "pending",
|
|
34
|
+
install_id: installId,
|
|
35
|
+
argv: [...input.argv],
|
|
36
|
+
});
|
|
37
|
+
let bridgeRecorded = false;
|
|
38
|
+
let ticketRecorded = false;
|
|
39
|
+
const executionTicket = redeem.execution_ticket;
|
|
40
|
+
if (executionTicket) {
|
|
41
|
+
try {
|
|
42
|
+
await recordExecutionTicket(executionTicket, input.argv, {
|
|
43
|
+
cwd: input.cwd,
|
|
44
|
+
kind: input.kind,
|
|
45
|
+
});
|
|
46
|
+
ticketRecorded = true;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
ticketRecorded = false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
await recordShellApprovalBridge(input.argv, { cwd: input.cwd });
|
|
54
|
+
bridgeRecorded = true;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
bridgeRecorded = false;
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
redeemed: redeem.redeemed,
|
|
61
|
+
approved_by: redeem.approved_by,
|
|
62
|
+
bridgeRecorded,
|
|
63
|
+
ticketRecorded,
|
|
64
|
+
execution_ticket: executionTicket,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=redeem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redeem.js","sourceRoot":"","sources":["../../src/approval/redeem.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAoBjD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,KAA2B;IAE3B,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IACjC,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC;IAExC,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,MAAM,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;QAC9C,IAAI,MAAM,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU;YAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACnF,IAAI,MAAM,CAAC,WAAW,KAAK,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;QAClE,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAC9E,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,GAAG,MAAM,kBAAkB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACvD,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,sBAAsB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC;QACvC,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,KAAK,EAAE,KAAK,IAAI,SAAS;QACzB,UAAU,EAAE,SAAS;QACrB,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;KACtB,CAAC,CAAC;IAEH,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,MAAM,eAAe,GAAG,MAAM,CAAC,gBAAgB,CAAC;IAEhD,IAAI,eAAe,EAAE,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,qBAAqB,CAAC,eAAe,EAAE,KAAK,CAAC,IAAI,EAAE;gBACvD,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,IAAI,EAAE,KAAK,CAAC,IAAI;aACjB,CAAC,CAAC;YACH,cAAc,GAAG,IAAI,CAAC;QACxB,CAAC;QAAC,MAAM,CAAC;YACP,cAAc,GAAG,KAAK,CAAC;QACzB,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,yBAAyB,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAChE,cAAc,GAAG,IAAI,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,cAAc,GAAG,KAAK,CAAC;IACzB,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,cAAc;QACd,cAAc;QACd,gBAAgB,EAAE,eAAe;KAClC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export type ApprovalRequestStatus = "pending" | "approved" | "denied" | "expired";
|
|
2
|
+
export type ApprovalRequestRecord = {
|
|
3
|
+
request_id: string;
|
|
4
|
+
status: ApprovalRequestStatus;
|
|
5
|
+
tier?: string | null;
|
|
6
|
+
kind?: string | null;
|
|
7
|
+
argv?: string[] | null;
|
|
8
|
+
argv_sha256?: string | null;
|
|
9
|
+
raw_display?: string | null;
|
|
10
|
+
install_id?: string | null;
|
|
11
|
+
session_id?: string | null;
|
|
12
|
+
environment?: string | null;
|
|
13
|
+
expires_at?: string | null;
|
|
14
|
+
approved_by?: string | null;
|
|
15
|
+
approved_at?: string | null;
|
|
16
|
+
open_url?: string | null;
|
|
17
|
+
event_id?: string | null;
|
|
18
|
+
};
|
|
19
|
+
export type CreateApprovalRequestInput = {
|
|
20
|
+
kind: "shell" | "mcp";
|
|
21
|
+
tier: string;
|
|
22
|
+
argv: string[];
|
|
23
|
+
install_id: string;
|
|
24
|
+
session_id?: string | null;
|
|
25
|
+
environment?: string | null;
|
|
26
|
+
raw_display?: string;
|
|
27
|
+
event_id?: string;
|
|
28
|
+
policy_revision?: number | null;
|
|
29
|
+
reasons?: unknown;
|
|
30
|
+
};
|
|
31
|
+
export type ApprovalGrantClaims = {
|
|
32
|
+
typ: "approval";
|
|
33
|
+
sub: string;
|
|
34
|
+
argv_sha256: string;
|
|
35
|
+
install_id: string;
|
|
36
|
+
session_id: string | null;
|
|
37
|
+
env: string | null;
|
|
38
|
+
request_id: string;
|
|
39
|
+
exp: number;
|
|
40
|
+
jti: string;
|
|
41
|
+
};
|
|
42
|
+
/** Short-lived hook credential minted on guardApprovalRedeem (distinct from approval grant). */
|
|
43
|
+
export type ExecutionTicketClaims = {
|
|
44
|
+
typ: "execution";
|
|
45
|
+
request_id: string;
|
|
46
|
+
argv_sha256: string;
|
|
47
|
+
install_id: string;
|
|
48
|
+
kind: "shell" | "mcp";
|
|
49
|
+
jti: string;
|
|
50
|
+
exp: number;
|
|
51
|
+
env: string | null;
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/approval/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,CAAC;AAElF,MAAM,MAAM,qBAAqB,GAAG;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,EAAE,OAAO,GAAG,KAAK,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,GAAG,EAAE,UAAU,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,gGAAgG;AAChG,MAAM,MAAM,qBAAqB,GAAG;IAClC,GAAG,EAAE,WAAW,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,OAAO,GAAG,KAAK,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB,CAAC"}
|