@intutic/gate 2.2.0 → 2.3.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/README.md +29 -12
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +20 -6
- package/dist/actions.js.map +1 -1
- package/dist/client.d.ts +19 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +48 -4
- package/dist/client.js.map +1 -1
- package/dist/dsh.d.ts +1 -1
- package/dist/dsh.js +1 -1
- package/dist/errors.d.ts +25 -2
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +53 -0
- package/dist/errors.js.map +1 -1
- package/dist/eve.d.ts +11 -11
- package/dist/eve.d.ts.map +1 -1
- package/dist/eve.js +10 -10
- package/dist/eve.js.map +1 -1
- package/dist/gate.d.ts +33 -1
- package/dist/gate.d.ts.map +1 -1
- package/dist/gate.js +118 -9
- package/dist/gate.js.map +1 -1
- package/dist/harness.d.ts +28 -20
- package/dist/harness.d.ts.map +1 -1
- package/dist/harness.js +165 -26
- package/dist/harness.js.map +1 -1
- package/dist/hold.d.ts +69 -0
- package/dist/hold.d.ts.map +1 -0
- package/dist/hold.js +127 -0
- package/dist/hold.js.map +1 -0
- package/dist/imagecheck.d.ts +14 -7
- package/dist/imagecheck.d.ts.map +1 -1
- package/dist/imagecheck.js +3 -3
- package/dist/imagecheck.js.map +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/limits.d.ts +26 -0
- package/dist/limits.d.ts.map +1 -0
- package/dist/limits.js +45 -0
- package/dist/limits.js.map +1 -0
- package/dist/managedAgents.d.ts +3 -3
- package/dist/managedAgents.d.ts.map +1 -1
- package/dist/managedAgents.js +2 -2
- package/dist/mcpRegistryRecord.d.ts +143 -0
- package/dist/mcpRegistryRecord.d.ts.map +1 -0
- package/dist/mcpRegistryRecord.js +217 -0
- package/dist/mcpRegistryRecord.js.map +1 -0
- package/dist/openai.d.ts +3 -3
- package/dist/openai.d.ts.map +1 -1
- package/dist/openai.js +9 -8
- package/dist/openai.js.map +1 -1
- package/dist/phrases.d.ts +87 -0
- package/dist/phrases.d.ts.map +1 -0
- package/dist/phrases.js +236 -0
- package/dist/phrases.js.map +1 -0
- package/dist/sequence.d.ts +52 -0
- package/dist/sequence.d.ts.map +1 -0
- package/dist/sequence.js +121 -0
- package/dist/sequence.js.map +1 -0
- package/dist/snapshot.d.ts +50 -36
- package/dist/snapshot.d.ts.map +1 -1
- package/dist/snapshot.js +90 -48
- package/dist/snapshot.js.map +1 -1
- package/dist/ssoGroups.d.ts +6 -0
- package/dist/ssoGroups.d.ts.map +1 -1
- package/dist/ssoGroups.js +27 -7
- package/dist/ssoGroups.js.map +1 -1
- package/dist/workflow.d.ts +5 -3
- package/dist/workflow.d.ts.map +1 -1
- package/dist/workflow.js +8 -4
- package/dist/workflow.js.map +1 -1
- package/package.json +1 -1
package/dist/sequence.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sequence rules: a gate rule `A.*B` run as "find A, then find B after it" in
|
|
3
|
+
* linear time.
|
|
4
|
+
*
|
|
5
|
+
* A rule like ` git .*reset +--hard` is a regex. `grep -E` runs it as an
|
|
6
|
+
* automaton, in time linear in the command. JavaScript's and Python's engines
|
|
7
|
+
* backtrack: for every ` git ` they try every end of `.*`, so 200 KB of
|
|
8
|
+
* ` git git git …` took 9.5 s, which is past the point where a harness that
|
|
9
|
+
* treats a hook timeout as "allow" runs the call. A rule marked `sequence`
|
|
10
|
+
* (`s` in a `.rules` line's flags column) is the same regex, read differently:
|
|
11
|
+
*
|
|
12
|
+
* - its top-level `|` alternatives are tried in turn;
|
|
13
|
+
* - each alternative is cut at its top-level `.*` into steps;
|
|
14
|
+
* - each step is searched for once, starting where the previous one ended.
|
|
15
|
+
*
|
|
16
|
+
* Each search is one pass over the text, so a rule costs at most its number of
|
|
17
|
+
* steps times the length of the text. It means the same as the regex provided
|
|
18
|
+
* the first match of every step but the last also ends first, which holds for
|
|
19
|
+
* every step the rule tables use: a step that starts and ends at a space with
|
|
20
|
+
* no space inside, or a fixed word. `.` does not match a newline and neither
|
|
21
|
+
* does a step search cross one in the regex, but the gates normalise every
|
|
22
|
+
* command subject to single spaces first, so there is none. A test fuzzes each
|
|
23
|
+
* sequence rule against its own regex.
|
|
24
|
+
*
|
|
25
|
+
* Self-contained on purpose — no imports, no module state — because the
|
|
26
|
+
* JavaScript gates emit it as source ({@link SEQUENCE_JS_SOURCE}).
|
|
27
|
+
* `packages/gate-js/src/sequence.ts` is a byte-identical copy and
|
|
28
|
+
* `intutic_clawde/gate/sequence.py` a transliteration; all of them run
|
|
29
|
+
* `fixtures/gate-rule-vectors.json`.
|
|
30
|
+
*
|
|
31
|
+
* @module
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* A sequence rule's source as alternatives of steps: split at every top-level
|
|
35
|
+
* `|`, then each alternative at every top-level `.*`. ` a .*b| c .*d` is
|
|
36
|
+
* `[[' a ', 'b'], [' c ', 'd']]`. Outside a group or a class only, so `(x|y)`
|
|
37
|
+
* stays inside its step. Empty steps are dropped.
|
|
38
|
+
*/
|
|
39
|
+
export function sequenceAlternatives(source) {
|
|
40
|
+
const alternatives = [];
|
|
41
|
+
let steps = [];
|
|
42
|
+
let current = '';
|
|
43
|
+
let depth = 0;
|
|
44
|
+
let inClass = false;
|
|
45
|
+
for (let i = 0; i < source.length; i++) {
|
|
46
|
+
const c = source.charAt(i);
|
|
47
|
+
if (c === '\\') {
|
|
48
|
+
current += c + source.charAt(i + 1);
|
|
49
|
+
i++;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (inClass) {
|
|
53
|
+
current += c;
|
|
54
|
+
if (c === ']')
|
|
55
|
+
inClass = false;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (c === '[') {
|
|
59
|
+
inClass = true;
|
|
60
|
+
current += c;
|
|
61
|
+
if (source.charAt(i + 1) === '^')
|
|
62
|
+
current += source.charAt(++i);
|
|
63
|
+
if (source.charAt(i + 1) === ']')
|
|
64
|
+
current += source.charAt(++i);
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (c === '(')
|
|
68
|
+
depth++;
|
|
69
|
+
if (c === ')')
|
|
70
|
+
depth--;
|
|
71
|
+
if (depth === 0 && c === '|') {
|
|
72
|
+
steps.push(current);
|
|
73
|
+
alternatives.push(steps.filter((step) => step !== ''));
|
|
74
|
+
steps = [];
|
|
75
|
+
current = '';
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (depth === 0 && c === '.' && source.charAt(i + 1) === '*') {
|
|
79
|
+
steps.push(current);
|
|
80
|
+
current = '';
|
|
81
|
+
i++;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
current += c;
|
|
85
|
+
}
|
|
86
|
+
steps.push(current);
|
|
87
|
+
alternatives.push(steps.filter((step) => step !== ''));
|
|
88
|
+
return alternatives;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Compiles a sequence rule's source for {@link sequenceMatch}: each step with
|
|
92
|
+
* the `g` flag, which is what lets a search start at `lastIndex`.
|
|
93
|
+
*/
|
|
94
|
+
export function compileSequence(source, ignoreCase) {
|
|
95
|
+
return sequenceAlternatives(source).map((steps) => steps.map((step) => new RegExp(step, ignoreCase ? 'gi' : 'g')));
|
|
96
|
+
}
|
|
97
|
+
/** Whether `text` matches a compiled sequence rule: some alternative's steps occur in order. */
|
|
98
|
+
export function sequenceMatch(alternatives, text) {
|
|
99
|
+
for (const steps of alternatives) {
|
|
100
|
+
let pos = 0;
|
|
101
|
+
let ok = true;
|
|
102
|
+
for (const step of steps) {
|
|
103
|
+
step.lastIndex = pos;
|
|
104
|
+
const m = step.exec(text);
|
|
105
|
+
if (!m) {
|
|
106
|
+
ok = false;
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
pos = m.index + m[0].length;
|
|
110
|
+
}
|
|
111
|
+
if (ok)
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* The three functions as JavaScript source, for a gate to emit: the gates run
|
|
118
|
+
* this exact code, not a retyped copy.
|
|
119
|
+
*/
|
|
120
|
+
export const SEQUENCE_JS_SOURCE = `${sequenceAlternatives.toString()}\n${compileSequence.toString()}\n${sequenceMatch.toString()}`;
|
|
121
|
+
//# sourceMappingURL=sequence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sequence.js","sourceRoot":"","sources":["../src/sequence.ts"],"names":[],"mappings":"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"}
|
package/dist/snapshot.d.ts
CHANGED
|
@@ -29,41 +29,20 @@
|
|
|
29
29
|
* * Snapshot health is reported as an event — "snapshot missing on 400
|
|
30
30
|
* machines" must not look identical to "snapshot present and healthy".
|
|
31
31
|
*
|
|
32
|
-
* ##
|
|
32
|
+
* ## Padding and case
|
|
33
33
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* `^` (`' rm( +-[a-zA-Z-]+)+ +/( |\\*)'` requires a literal space before
|
|
47
|
-
* `rm`) — POSIX ERE has no `\b` and no reliable `^`/`$` inside the emitted
|
|
48
|
-
* shell gates, so the whole pattern table is authored against the padded
|
|
49
|
-
* contract. It is also why `policySnapshot.ts`'s `toGuardPattern` strips
|
|
50
|
-
* the `^`/`$` off an SOP `toolPattern` and re-wraps it as `' (name) '`
|
|
51
|
-
* before shipping it as a `subject: 'tool'` snapshot rule — that
|
|
52
|
-
* transformation only makes sense against a padded reader. Without
|
|
53
|
-
* padding, a command that BEGINS with the dangerous verb (`"rm -rf /"`,
|
|
54
|
-
* no leading space) never matches `' rm...'` at all, and the block
|
|
55
|
-
* silently never fires.
|
|
56
|
-
* 2. **Forced lowercasing.** `_normalise()` lowercases unconditionally; the
|
|
57
|
-
* real `NORMALISE_CONTRACT.jsSource` does not — case sensitivity is
|
|
58
|
-
* governed entirely by each rule's own `ignoreCase`/`i`-flag column.
|
|
59
|
-
* `bypass.env_kill_switch` (` [A-Z][A-Z0-9_]*_HOOKS?=`) and
|
|
60
|
-
* `destructive.chmod_recursive_root`/`chown_recursive_root`
|
|
61
|
-
* (`[a-zA-Z]*R[a-zA-Z]*`, a literal uppercase `R` for the recursive flag)
|
|
62
|
-
* both key on case WITHOUT setting that flag; forcing the subject to
|
|
63
|
-
* lowercase first makes them never fire, on real production patterns.
|
|
64
|
-
*
|
|
65
|
-
* This reader pads and preserves case, matching the real shipped contract;
|
|
66
|
-
* see the fidelity suite for the evidence.
|
|
34
|
+
* Normalisation pads the subject with a space at each end and collapses
|
|
35
|
+
* whitespace, and does not lowercase, as the shipped gates do
|
|
36
|
+
* (`NORMALISE_CONTRACT` in `protectedPaths.ts`). Padding is what lets a
|
|
37
|
+
* floor/destructive pattern use a plain leading space or non-word character as
|
|
38
|
+
* a stand-in for `^` (POSIX ERE has no `\b` and no reliable `^`/`$` inside the
|
|
39
|
+
* emitted shell gates), so without it a command that BEGINS with the dangerous
|
|
40
|
+
* verb (`"rm -rf /"`, `"DROP TABLE users"`) never matches. Case sensitivity is
|
|
41
|
+
* each rule's own `ignoreCase` flag: `bypass.env_kill_switch` and the
|
|
42
|
+
* recursive chmod/chown rules key on an uppercase letter without one. The
|
|
43
|
+
* Python SDK's reader once lowercased and did not pad, and missed both; it now
|
|
44
|
+
* follows the same contract, and `destructive-sql-vectors.json` in
|
|
45
|
+
* shared-types runs both readers over the same commands.
|
|
67
46
|
*
|
|
68
47
|
* The regex-dialect divergence the Python module documents (`.rules` patterns
|
|
69
48
|
* are authored as JavaScript regexes; compiling them with a different engine
|
|
@@ -71,14 +50,26 @@
|
|
|
71
50
|
* here — this reader compiles them as native JS `RegExp`, the dialect they
|
|
72
51
|
* were authored in.
|
|
73
52
|
*/
|
|
53
|
+
import { type McpAllowlistRecord, type McpRegistryRecord } from './mcpRegistryRecord.js';
|
|
74
54
|
import { type SsoGroupRecord } from './ssoGroups.js';
|
|
75
55
|
export declare const SNAPSHOT_STALE_AFTER_DAYS = 7;
|
|
76
56
|
/** Severity tiers, in the order the shipped gate handles them. */
|
|
77
57
|
export declare const SEV_SHADOW: "shadow";
|
|
78
58
|
export declare const SEV_WARN: "warn";
|
|
79
59
|
export declare const SEV_BLOCK: "block";
|
|
80
|
-
|
|
81
|
-
|
|
60
|
+
/**
|
|
61
|
+
* A hold rule (a `REQUIRE_APPROVAL:` SOP, or a local `review_before:` token):
|
|
62
|
+
* refuses like a block, but asks a person rather than denying — see hold.ts.
|
|
63
|
+
*/
|
|
64
|
+
export declare const SEV_HOLD: "hold";
|
|
65
|
+
export type Severity = typeof SEV_SHADOW | typeof SEV_WARN | typeof SEV_BLOCK | typeof SEV_HOLD;
|
|
66
|
+
/**
|
|
67
|
+
* `phrase`: the source is `|`-separated phrases matched as words (phrases.ts),
|
|
68
|
+
* not a regex. `action`: the source is matched against the action tokens the
|
|
69
|
+
* command classifies to (`" action:deploy "`, actions.ts) — what a local
|
|
70
|
+
* `review_before: action:<name>` compiles to.
|
|
71
|
+
*/
|
|
72
|
+
export type RuleSubject = 'tool' | 'command' | 'target' | 'phrase' | 'action' | 'any';
|
|
82
73
|
export type SnapshotState = 'ok' | 'absent' | 'invalid' | 'empty' | 'stale';
|
|
83
74
|
export interface Rule {
|
|
84
75
|
id: string;
|
|
@@ -86,6 +77,14 @@ export interface Rule {
|
|
|
86
77
|
subject: RuleSubject;
|
|
87
78
|
reason: string;
|
|
88
79
|
pattern: RegExp;
|
|
80
|
+
/**
|
|
81
|
+
* A sequence rule's compiled steps (flags `s`, sequence.ts), or null. The
|
|
82
|
+
* rule is matched by searching for its steps in order, in linear time,
|
|
83
|
+
* rather than by {@link pattern}, which a backtracking engine runs in time
|
|
84
|
+
* growing with the square of the text. Absent on a rule built by hand,
|
|
85
|
+
* which is matched by {@link pattern}.
|
|
86
|
+
*/
|
|
87
|
+
steps?: RegExp[][] | null;
|
|
89
88
|
}
|
|
90
89
|
export declare class Snapshot {
|
|
91
90
|
rules: Rule[];
|
|
@@ -103,11 +102,26 @@ export declare class Snapshot {
|
|
|
103
102
|
* edited group list in the file clears nothing.
|
|
104
103
|
*/
|
|
105
104
|
ssoGroups: SsoGroupRecord | null;
|
|
105
|
+
/**
|
|
106
|
+
* The workspace's MCP server registry decisions (the `@mcp_registry`
|
|
107
|
+
* record), or null when it made none. Null on a snapshot that fails its
|
|
108
|
+
* integrity check, on which the gate admits no MCP server at all
|
|
109
|
+
* (`mcpSnapshotUnverifiedRefusal`): a deleted record looks like one never
|
|
110
|
+
* set, so neither record can be vouched for.
|
|
111
|
+
*/
|
|
112
|
+
mcpRegistry: McpRegistryRecord | null;
|
|
113
|
+
/**
|
|
114
|
+
* The workspace's `mcpAllowedServers` list (the `@mcp_allowlist` record),
|
|
115
|
+
* or null when it set none. Null on a snapshot that fails its integrity
|
|
116
|
+
* check, as {@link mcpRegistry} is.
|
|
117
|
+
*/
|
|
118
|
+
mcpAllowlist: McpAllowlistRecord | null;
|
|
106
119
|
get healthMessage(): string;
|
|
107
120
|
}
|
|
108
121
|
export interface Decision {
|
|
109
122
|
/** `null` means allow. */
|
|
110
123
|
severity: Severity | null;
|
|
124
|
+
/** The rule's reason and `[id]`; for a hold, the reason alone, which the gate words as a hold. */
|
|
111
125
|
reason: string;
|
|
112
126
|
ruleId: string;
|
|
113
127
|
}
|
package/dist/snapshot.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAMH,OAAO,EAKL,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACvB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAA8C,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAKhG,eAAO,MAAM,yBAAyB,IAAI,CAAA;AAE1C,kEAAkE;AAClE,eAAO,MAAM,UAAU,EAAG,QAAiB,CAAA;AAC3C,eAAO,MAAM,QAAQ,EAAG,MAAe,CAAA;AACvC,eAAO,MAAM,SAAS,EAAG,OAAgB,CAAA;AACzC;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAG,MAAe,CAAA;AAEvC,MAAM,MAAM,QAAQ,GAAG,OAAO,UAAU,GAAG,OAAO,QAAQ,GAAG,OAAO,SAAS,GAAG,OAAO,QAAQ,CAAA;AAC/F;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK,CAAA;AACrF,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAA;AAE3E,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,WAAW,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI,CAAA;CAC1B;AAED,qBAAa,QAAQ;IACnB,KAAK,EAAE,IAAI,EAAE,CAAK;IAClB,MAAM,SAAS;IACf,KAAK,EAAE,aAAa,CAAW;IAC/B,WAAW,SAAK;IAChB,WAAW,SAAK;IAChB,OAAO,SAAI;IACX,sCAAsC;IACtC,YAAY,SAAI;IAChB;;;;;OAKG;IACH,SAAS,EAAE,cAAc,GAAG,IAAI,CAAO;IACvC;;;;;;OAMG;IACH,WAAW,EAAE,iBAAiB,GAAG,IAAI,CAAO;IAC5C;;;;OAIG;IACH,YAAY,EAAE,kBAAkB,GAAG,IAAI,CAAO;IAE9C,IAAI,aAAa,IAAI,MAAM,CAa1B;CACF;AAED,MAAM,WAAW,QAAQ;IACvB,0BAA0B;IAC1B,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAA;IACzB,kGAAkG;IAClG,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AAMD,wBAAgB,YAAY,IAAI,MAAM,CAKrC;AAYD,wBAAgB,YAAY,CAAC,WAAW,SAAK,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,CAuGtE;AAED,qEAAqE;AACrE,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,QAAQ,EACd,aAAa,UAAQ,GACpB,QAAQ,CAiEV;AAED,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C"}
|
package/dist/snapshot.js
CHANGED
|
@@ -29,41 +29,20 @@
|
|
|
29
29
|
* * Snapshot health is reported as an event — "snapshot missing on 400
|
|
30
30
|
* machines" must not look identical to "snapshot present and healthy".
|
|
31
31
|
*
|
|
32
|
-
* ##
|
|
32
|
+
* ## Padding and case
|
|
33
33
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* `^` (`' rm( +-[a-zA-Z-]+)+ +/( |\\*)'` requires a literal space before
|
|
47
|
-
* `rm`) — POSIX ERE has no `\b` and no reliable `^`/`$` inside the emitted
|
|
48
|
-
* shell gates, so the whole pattern table is authored against the padded
|
|
49
|
-
* contract. It is also why `policySnapshot.ts`'s `toGuardPattern` strips
|
|
50
|
-
* the `^`/`$` off an SOP `toolPattern` and re-wraps it as `' (name) '`
|
|
51
|
-
* before shipping it as a `subject: 'tool'` snapshot rule — that
|
|
52
|
-
* transformation only makes sense against a padded reader. Without
|
|
53
|
-
* padding, a command that BEGINS with the dangerous verb (`"rm -rf /"`,
|
|
54
|
-
* no leading space) never matches `' rm...'` at all, and the block
|
|
55
|
-
* silently never fires.
|
|
56
|
-
* 2. **Forced lowercasing.** `_normalise()` lowercases unconditionally; the
|
|
57
|
-
* real `NORMALISE_CONTRACT.jsSource` does not — case sensitivity is
|
|
58
|
-
* governed entirely by each rule's own `ignoreCase`/`i`-flag column.
|
|
59
|
-
* `bypass.env_kill_switch` (` [A-Z][A-Z0-9_]*_HOOKS?=`) and
|
|
60
|
-
* `destructive.chmod_recursive_root`/`chown_recursive_root`
|
|
61
|
-
* (`[a-zA-Z]*R[a-zA-Z]*`, a literal uppercase `R` for the recursive flag)
|
|
62
|
-
* both key on case WITHOUT setting that flag; forcing the subject to
|
|
63
|
-
* lowercase first makes them never fire, on real production patterns.
|
|
64
|
-
*
|
|
65
|
-
* This reader pads and preserves case, matching the real shipped contract;
|
|
66
|
-
* see the fidelity suite for the evidence.
|
|
34
|
+
* Normalisation pads the subject with a space at each end and collapses
|
|
35
|
+
* whitespace, and does not lowercase, as the shipped gates do
|
|
36
|
+
* (`NORMALISE_CONTRACT` in `protectedPaths.ts`). Padding is what lets a
|
|
37
|
+
* floor/destructive pattern use a plain leading space or non-word character as
|
|
38
|
+
* a stand-in for `^` (POSIX ERE has no `\b` and no reliable `^`/`$` inside the
|
|
39
|
+
* emitted shell gates), so without it a command that BEGINS with the dangerous
|
|
40
|
+
* verb (`"rm -rf /"`, `"DROP TABLE users"`) never matches. Case sensitivity is
|
|
41
|
+
* each rule's own `ignoreCase` flag: `bypass.env_kill_switch` and the
|
|
42
|
+
* recursive chmod/chown rules key on an uppercase letter without one. The
|
|
43
|
+
* Python SDK's reader once lowercased and did not pad, and missed both; it now
|
|
44
|
+
* follows the same contract, and `destructive-sql-vectors.json` in
|
|
45
|
+
* shared-types runs both readers over the same commands.
|
|
67
46
|
*
|
|
68
47
|
* The regex-dialect divergence the Python module documents (`.rules` patterns
|
|
69
48
|
* are authored as JavaScript regexes; compiling them with a different engine
|
|
@@ -75,12 +54,21 @@ import { createHash } from 'node:crypto';
|
|
|
75
54
|
import { readFileSync } from 'node:fs';
|
|
76
55
|
import { homedir } from 'node:os';
|
|
77
56
|
import { join } from 'node:path';
|
|
57
|
+
import { decodeMcpAllowlistRecord, decodeMcpRegistryRecord, MCP_ALLOWLIST_RECORD_TAG, MCP_REGISTRY_RECORD_TAG, } from './mcpRegistryRecord.js';
|
|
78
58
|
import { decodeSsoGroupRecord, SSO_GROUP_RECORD_TAG } from './ssoGroups.js';
|
|
59
|
+
import { hasPhrase, phraseText } from './phrases.js';
|
|
60
|
+
import { classify } from './actions.js';
|
|
61
|
+
import { compileSequence, sequenceMatch } from './sequence.js';
|
|
79
62
|
export const SNAPSHOT_STALE_AFTER_DAYS = 7;
|
|
80
63
|
/** Severity tiers, in the order the shipped gate handles them. */
|
|
81
64
|
export const SEV_SHADOW = 'shadow';
|
|
82
65
|
export const SEV_WARN = 'warn';
|
|
83
66
|
export const SEV_BLOCK = 'block';
|
|
67
|
+
/**
|
|
68
|
+
* A hold rule (a `REQUIRE_APPROVAL:` SOP, or a local `review_before:` token):
|
|
69
|
+
* refuses like a block, but asks a person rather than denying — see hold.ts.
|
|
70
|
+
*/
|
|
71
|
+
export const SEV_HOLD = 'hold';
|
|
84
72
|
export class Snapshot {
|
|
85
73
|
rules = [];
|
|
86
74
|
digest = 'none';
|
|
@@ -97,12 +85,26 @@ export class Snapshot {
|
|
|
97
85
|
* edited group list in the file clears nothing.
|
|
98
86
|
*/
|
|
99
87
|
ssoGroups = null;
|
|
88
|
+
/**
|
|
89
|
+
* The workspace's MCP server registry decisions (the `@mcp_registry`
|
|
90
|
+
* record), or null when it made none. Null on a snapshot that fails its
|
|
91
|
+
* integrity check, on which the gate admits no MCP server at all
|
|
92
|
+
* (`mcpSnapshotUnverifiedRefusal`): a deleted record looks like one never
|
|
93
|
+
* set, so neither record can be vouched for.
|
|
94
|
+
*/
|
|
95
|
+
mcpRegistry = null;
|
|
96
|
+
/**
|
|
97
|
+
* The workspace's `mcpAllowedServers` list (the `@mcp_allowlist` record),
|
|
98
|
+
* or null when it set none. Null on a snapshot that fails its integrity
|
|
99
|
+
* check, as {@link mcpRegistry} is.
|
|
100
|
+
*/
|
|
101
|
+
mcpAllowlist = null;
|
|
100
102
|
get healthMessage() {
|
|
101
103
|
switch (this.state) {
|
|
102
104
|
case 'absent':
|
|
103
105
|
return 'No policy snapshot — built-in protections only';
|
|
104
106
|
case 'invalid':
|
|
105
|
-
return 'Policy snapshot failed its digest or workspace check — dynamic rules dropped except SSO-group refusals';
|
|
107
|
+
return 'Policy snapshot failed its digest or workspace check — dynamic rules dropped except SSO-group refusals, and every MCP call refused';
|
|
106
108
|
case 'empty':
|
|
107
109
|
return 'Policy snapshot contains no rules — the compile produced nothing';
|
|
108
110
|
case 'stale':
|
|
@@ -122,8 +124,7 @@ export function snapshotPath() {
|
|
|
122
124
|
/**
|
|
123
125
|
* Collapse and pad whitespace, as the shipped gates do — case is
|
|
124
126
|
* DELIBERATELY left untouched; a rule that wants case-insensitivity sets its
|
|
125
|
-
* own `ignoreCase` flag. See the module doc comment
|
|
126
|
-
* SDK's reader diverges from this.
|
|
127
|
+
* own `ignoreCase` flag. See the module doc comment.
|
|
127
128
|
*/
|
|
128
129
|
function normalise(value) {
|
|
129
130
|
const s = value === null || value === undefined ? '' : String(value);
|
|
@@ -159,17 +160,28 @@ export function loadSnapshot(workspaceId = '', path) {
|
|
|
159
160
|
snap.ssoGroups = decodeSsoGroupRecord(line);
|
|
160
161
|
continue;
|
|
161
162
|
}
|
|
163
|
+
if (line.startsWith(`${MCP_REGISTRY_RECORD_TAG}\t`)) {
|
|
164
|
+
snap.mcpRegistry = decodeMcpRegistryRecord(line);
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (line.startsWith(`${MCP_ALLOWLIST_RECORD_TAG}\t`)) {
|
|
168
|
+
snap.mcpAllowlist = decodeMcpAllowlistRecord(line);
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
162
171
|
const f = line.split('\t');
|
|
163
172
|
// Column order: id, severity, flags, subject, reason, source(regex), [argPatternB64].
|
|
173
|
+
// Flags: i = case-insensitive, s = a sequence rule.
|
|
164
174
|
if (f.length < 6 || !f[5])
|
|
165
175
|
continue;
|
|
176
|
+
const ic = f[2].includes('i');
|
|
166
177
|
try {
|
|
167
178
|
snap.rules.push({
|
|
168
179
|
id: f[0],
|
|
169
180
|
severity: f[1],
|
|
170
181
|
subject: f[3] || 'any',
|
|
171
182
|
reason: f[4],
|
|
172
|
-
pattern: new RegExp(f[5],
|
|
183
|
+
pattern: new RegExp(f[5], ic ? 'i' : ''),
|
|
184
|
+
steps: f[2].includes('s') ? compileSequence(f[5], ic) : null,
|
|
173
185
|
});
|
|
174
186
|
}
|
|
175
187
|
catch {
|
|
@@ -184,7 +196,9 @@ export function loadSnapshot(workspaceId = '', path) {
|
|
|
184
196
|
.filter((l) => l && !l.startsWith('#'))
|
|
185
197
|
.join('\n');
|
|
186
198
|
const actual = createHash('sha256').update(body, 'utf-8').digest('hex').slice(0, 32);
|
|
187
|
-
|
|
199
|
+
// No digest line is unverified too: the sync daemon always writes one, so
|
|
200
|
+
// its absence means the file was edited.
|
|
201
|
+
if (actual !== snap.digest) {
|
|
188
202
|
snap.state = 'invalid';
|
|
189
203
|
}
|
|
190
204
|
if (snap.state === 'ok' && snap.workspaceId && workspaceId && snap.workspaceId !== workspaceId) {
|
|
@@ -201,6 +215,9 @@ export function loadSnapshot(workspaceId = '', path) {
|
|
|
201
215
|
// member whose groups this gate can no longer vouch for.
|
|
202
216
|
if (snap.ssoGroups)
|
|
203
217
|
snap.ssoGroups = { ...snap.ssoGroups, member: null };
|
|
218
|
+
// Neither MCP record can be vouched for: the gate admits no MCP server.
|
|
219
|
+
snap.mcpRegistry = null;
|
|
220
|
+
snap.mcpAllowlist = null;
|
|
204
221
|
}
|
|
205
222
|
if (snap.state === 'ok' && snap.generatedAt) {
|
|
206
223
|
const t = Date.parse(snap.generatedAt);
|
|
@@ -225,16 +242,36 @@ export function evaluate(toolName, target, command, snap, guardDisabled = false)
|
|
|
225
242
|
const nTool = normalise(toolName);
|
|
226
243
|
const nCommand = normalise(command);
|
|
227
244
|
const nTarget = normalise(target);
|
|
245
|
+
let words = null;
|
|
246
|
+
// The command's action tokens, space-padded as the hook gates write them, so
|
|
247
|
+
// a hold on `action:deploy` matches whole tokens. Classified with the same
|
|
248
|
+
// needles and phrase matcher as the hook gates and the proxy's actions.rs.
|
|
249
|
+
let actions = null;
|
|
228
250
|
for (const rule of rules) {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
251
|
+
if (rule.subject === 'phrase') {
|
|
252
|
+
// The source is `|`-separated phrases matched as words against the raw
|
|
253
|
+
// command (phrases.ts), not a regex: a backtracking regex for "whatever
|
|
254
|
+
// separates the words" is super-linear on crafted input.
|
|
255
|
+
words ??= phraseText(command);
|
|
256
|
+
const w = words;
|
|
257
|
+
if (!rule.pattern.source.split('|').some((p) => hasPhrase(w, p, true)))
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
if (rule.subject === 'action')
|
|
261
|
+
actions ??= ' ' + classify(toolName, { command }).join(' ') + ' ';
|
|
262
|
+
const subjects = rule.subject === 'phrase'
|
|
263
|
+
? [nCommand]
|
|
264
|
+
: rule.subject === 'action'
|
|
265
|
+
? [actions]
|
|
266
|
+
: rule.subject === 'tool'
|
|
267
|
+
? [nTool]
|
|
268
|
+
: rule.subject === 'command'
|
|
269
|
+
? [nCommand]
|
|
270
|
+
: rule.subject === 'target'
|
|
271
|
+
? [nTarget]
|
|
272
|
+
: [nCommand, nTarget];
|
|
236
273
|
for (const subject of subjects) {
|
|
237
|
-
if (!rule.pattern.test(subject))
|
|
274
|
+
if (rule.subject !== 'phrase' && !(rule.steps ? sequenceMatch(rule.steps, subject) : rule.pattern.test(subject)))
|
|
238
275
|
continue;
|
|
239
276
|
if (rule.severity === SEV_SHADOW) {
|
|
240
277
|
return { severity: SEV_SHADOW, reason: `${rule.reason} [${rule.id}]`, ruleId: rule.id };
|
|
@@ -247,7 +284,12 @@ export function evaluate(toolName, target, command, snap, guardDisabled = false)
|
|
|
247
284
|
ruleId: rule.id,
|
|
248
285
|
};
|
|
249
286
|
}
|
|
250
|
-
|
|
287
|
+
if (rule.severity === SEV_HOLD) {
|
|
288
|
+
return { severity: SEV_HOLD, reason: rule.reason, ruleId: rule.id };
|
|
289
|
+
}
|
|
290
|
+
// Any other severity blocks, as an unknown one does in the shipped
|
|
291
|
+
// gates: a severity this reader does not know must not allow. The
|
|
292
|
+
// rule's own reason, not a generic one — resolveSeverity reads it.
|
|
251
293
|
return { severity: SEV_BLOCK, reason: `${rule.reason} [${rule.id}]`, ruleId: rule.id };
|
|
252
294
|
}
|
|
253
295
|
}
|
package/dist/snapshot.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"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"}
|
package/dist/ssoGroups.d.ts
CHANGED
|
@@ -37,6 +37,12 @@ export interface SsoGroupDecision {
|
|
|
37
37
|
}
|
|
38
38
|
export declare const SSO_GROUP_RECORD_TAG = "@sso_groups";
|
|
39
39
|
export declare function parseSsoGroupPolicy(value: unknown): SsoGroupPolicy | null;
|
|
40
|
+
/**
|
|
41
|
+
* Whether a call named `name` is the tool a policy entry names: exactly, or,
|
|
42
|
+
* for an entry that is an MCP tool's own name (not starting with `mcp__`), as
|
|
43
|
+
* the name a harness gives it on any server, `mcp__<server>__<entry>`.
|
|
44
|
+
*/
|
|
45
|
+
export declare function ssoGroupToolMatches(entry: string, name: string): boolean;
|
|
40
46
|
/** `memberGroups` null means the groups are unknown — a high-risk tool is then refused. */
|
|
41
47
|
export declare function evaluateSsoGroupClearance(policy: SsoGroupPolicy | null, toolName: string, memberGroups: readonly string[] | null): SsoGroupDecision;
|
|
42
48
|
/** Reads the snapshot's record line; null for any other line or a damaged one. */
|
package/dist/ssoGroups.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssoGroups.d.ts","sourceRoot":"","sources":["../src/ssoGroups.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,QAAQ,GAAG,cAAc,CAAA;AAErE,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,aAAa,EAAE,MAAM,EAAE,CAAA;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,cAAc,CAAA;IACtB,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,IAAI,CAAA;IACxD,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,iBAAiB,CAAA;IAC5B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,eAAO,MAAM,oBAAoB,gBAAgB,CAAA;AAMjD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,GAAG,IAAI,CAQzE;AAMD,2FAA2F;AAC3F,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,cAAc,GAAG,IAAI,EAC7B,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,GACrC,gBAAgB,
|
|
1
|
+
{"version":3,"file":"ssoGroups.d.ts","sourceRoot":"","sources":["../src/ssoGroups.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,QAAQ,GAAG,cAAc,CAAA;AAErE,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,aAAa,EAAE,MAAM,EAAE,CAAA;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,cAAc,CAAA;IACtB,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,IAAI,CAAA;IACxD,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,iBAAiB,CAAA;IAC5B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,eAAO,MAAM,oBAAoB,gBAAgB,CAAA;AAMjD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,GAAG,IAAI,CAQzE;AAMD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAKxE;AAOD,2FAA2F;AAC3F,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,cAAc,GAAG,IAAI,EAC7B,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,GACrC,gBAAgB,CAuBlB;AAED,kFAAkF;AAClF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAgBxE"}
|
package/dist/ssoGroups.js
CHANGED
|
@@ -33,18 +33,38 @@ export function parseSsoGroupPolicy(value) {
|
|
|
33
33
|
function ruleId(kind, toolName) {
|
|
34
34
|
return `sso_group.${kind}.${toolName.replace(/[^A-Za-z0-9_.:-]/g, '_')}`;
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Whether a call named `name` is the tool a policy entry names: exactly, or,
|
|
38
|
+
* for an entry that is an MCP tool's own name (not starting with `mcp__`), as
|
|
39
|
+
* the name a harness gives it on any server, `mcp__<server>__<entry>`.
|
|
40
|
+
*/
|
|
41
|
+
export function ssoGroupToolMatches(entry, name) {
|
|
42
|
+
if (name === entry)
|
|
43
|
+
return true;
|
|
44
|
+
if (entry.startsWith('mcp__') || !name.startsWith('mcp__'))
|
|
45
|
+
return false;
|
|
46
|
+
const suffix = `__${entry}`;
|
|
47
|
+
return name.length > 'mcp__'.length + suffix.length && name.endsWith(suffix);
|
|
48
|
+
}
|
|
49
|
+
function matchingEntry(list, toolName) {
|
|
50
|
+
if (list.includes(toolName))
|
|
51
|
+
return toolName;
|
|
52
|
+
return list.find((e) => ssoGroupToolMatches(e, toolName));
|
|
53
|
+
}
|
|
36
54
|
/** `memberGroups` null means the groups are unknown — a high-risk tool is then refused. */
|
|
37
55
|
export function evaluateSsoGroupClearance(policy, toolName, memberGroups) {
|
|
38
56
|
if (!policy)
|
|
39
57
|
return { clearance: 'GRANTED', ruleId: null, reason: '' };
|
|
40
|
-
|
|
58
|
+
const obo = matchingEntry(policy.requireOboFor, toolName);
|
|
59
|
+
if (obo !== undefined) {
|
|
41
60
|
return {
|
|
42
61
|
clearance: 'REQUIRES_OBO',
|
|
43
|
-
ruleId: ruleId('require_obo',
|
|
44
|
-
reason: `SSO group policy: ${
|
|
62
|
+
ruleId: ruleId('require_obo', obo),
|
|
63
|
+
reason: `SSO group policy: ${obo} is on-behalf-of only, and a tool-call gate has no OBO token to present`,
|
|
45
64
|
};
|
|
46
65
|
}
|
|
47
|
-
|
|
66
|
+
const risky = matchingEntry(policy.highRiskTools, toolName);
|
|
67
|
+
if (risky === undefined)
|
|
48
68
|
return { clearance: 'GRANTED', ruleId: null, reason: '' };
|
|
49
69
|
if (memberGroups && policy.requiredGroups.some((g) => memberGroups.includes(g))) {
|
|
50
70
|
return { clearance: 'GRANTED', ruleId: null, reason: '' };
|
|
@@ -52,10 +72,10 @@ export function evaluateSsoGroupClearance(policy, toolName, memberGroups) {
|
|
|
52
72
|
const groups = policy.requiredGroups.length > 0 ? policy.requiredGroups.join(', ') : '(none configured)';
|
|
53
73
|
return {
|
|
54
74
|
clearance: 'DENIED',
|
|
55
|
-
ruleId: ruleId('high_risk',
|
|
75
|
+
ruleId: ruleId('high_risk', risky),
|
|
56
76
|
reason: memberGroups
|
|
57
|
-
? `SSO group policy: ${
|
|
58
|
-
: `SSO group policy: ${
|
|
77
|
+
? `SSO group policy: ${risky} requires one of the SSO groups ${groups}, and this member holds none of them`
|
|
78
|
+
: `SSO group policy: ${risky} requires one of the SSO groups ${groups}, and this gate does not know the member's groups`,
|
|
59
79
|
};
|
|
60
80
|
}
|
|
61
81
|
/** Reads the snapshot's record line; null for any other line or a damaged one. */
|
package/dist/ssoGroups.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssoGroups.js","sourceRoot":"","sources":["../src/ssoGroups.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAsBH,MAAM,CAAC,MAAM,oBAAoB,GAAG,aAAa,CAAA;AAEjD,SAAS,UAAU,CAAC,KAAc;IAChC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AAC5F,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IACpF,MAAM,CAAC,GAAG,KAAgC,CAAA;IAC1C,OAAO;QACL,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;QAC7C,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;QAC/C,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;KAC9C,CAAA;AACH,CAAC;AAED,SAAS,MAAM,CAAC,IAAiC,EAAE,QAAgB;IACjE,OAAO,aAAa,IAAI,IAAI,QAAQ,CAAC,OAAO,CAAC,mBAAmB,EAAE,GAAG,CAAC,EAAE,CAAA;AAC1E,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,yBAAyB,CACvC,MAA6B,EAC7B,QAAgB,EAChB,YAAsC;IAEtC,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;IACtE,
|
|
1
|
+
{"version":3,"file":"ssoGroups.js","sourceRoot":"","sources":["../src/ssoGroups.ts"],"names":[],"mappings":"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"}
|