@seanmozeik/tripwire 0.7.2 → 0.9.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 +20 -2
- package/dist/index.js +22 -27
- package/dist/tripwire-cli.js +1 -1
- package/dist/tripwire-hook.js +1 -1
- package/dist/tripwire-pi.js +16 -6
- package/dist/tripwire.js +109 -121
- package/dist/types/dispatch.d.ts +4 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/types/lib/bash/analyze.d.ts +3 -0
- package/dist/types/lib/bash/carriers.d.ts +11 -0
- package/dist/types/lib/bash/config.d.ts +17 -0
- package/dist/types/lib/bash/execution-types.d.ts +13 -0
- package/dist/types/lib/bash/execution.d.ts +13 -0
- package/dist/types/lib/bash/index.d.ts +8 -0
- package/dist/types/lib/bash/pipeline-inputs.d.ts +10 -0
- package/dist/types/lib/bash/static-command.d.ts +9 -0
- package/dist/types/lib/bash/types.d.ts +64 -0
- package/dist/types/lib/bash/values.d.ts +25 -0
- package/dist/types/lib/bash/wrappers.d.ts +21 -0
- package/dist/types/lib/code/analyze.d.ts +3 -0
- package/dist/types/lib/code/calls.d.ts +8 -0
- package/dist/types/lib/code/carriers.d.ts +18 -0
- package/dist/types/lib/code/containers.d.ts +4 -0
- package/dist/types/lib/code/control.d.ts +13 -0
- package/dist/types/lib/code/data.d.ts +9 -0
- package/dist/types/lib/code/imports.d.ts +5 -0
- package/dist/types/lib/code/members.d.ts +4 -0
- package/dist/types/lib/code/syntax.d.ts +10 -0
- package/dist/types/lib/code/types.d.ts +51 -0
- package/dist/types/lib/code/uv.d.ts +13 -0
- package/dist/types/lib/code/values.d.ts +9 -0
- package/dist/types/lib/config.d.ts +32 -0
- package/dist/types/lib/event.d.ts +7 -1
- package/dist/types/lib/rule-actions.d.ts +27 -0
- package/dist/types/rules/bash-bypass.d.ts +5 -0
- package/dist/types/rules/bash-deny.d.ts +4 -4
- package/dist/types/rules/bash-git.d.ts +2 -2
- package/dist/types/rules/bash-network-install.d.ts +2 -2
- package/dist/types/rules/bash-redirect.d.ts +2 -2
- package/dist/types/rules/bash-scoped-rm.d.ts +2 -2
- package/dist/types/rules/bash-tar-explosion.d.ts +2 -2
- package/dist/types/rules/config-custom.d.ts +3 -3
- package/dist/types/rules/embedded-code.d.ts +15 -0
- package/dist/types/rules/tool-policy.d.ts +2 -2
- package/package.json +11 -8
- package/dist/types/lib/bash.d.ts +0 -27
package/dist/types/dispatch.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
import { Effect } from 'effect';
|
|
3
|
+
import { type BashAnalysisOptions } from './lib/bash';
|
|
3
4
|
import { type Config, type ResolvedConfig, type SecretScannerConfig } from './lib/config';
|
|
4
5
|
import { type Decision } from './lib/decision';
|
|
5
6
|
import { type HookEvent } from './lib/event.ts';
|
|
@@ -9,10 +10,11 @@ interface Rule {
|
|
|
9
10
|
readonly name: string;
|
|
10
11
|
readonly fn: RuleFn;
|
|
11
12
|
}
|
|
12
|
-
declare const collectPreToolUseRules: (tool: string, input: unknown, config: ResolvedConfig) => Rule[];
|
|
13
|
+
declare const collectPreToolUseRules: (tool: string, input: unknown, config: ResolvedConfig, cwd?: string) => Rule[];
|
|
13
14
|
declare const collectPostToolUseRules: (tool: string, response: unknown, secretScanner: SecretScannerConfig) => Rule[];
|
|
14
15
|
declare const runRules: (rules: readonly Rule[], timeoutMs: number) => Effect.Effect<Decision>;
|
|
15
16
|
declare const runRulesSync: (rules: readonly Rule[]) => Decision;
|
|
16
17
|
declare const decide: (event: HookEvent, config?: Config) => Decision;
|
|
18
|
+
declare const decideBash: (command: string, config?: Config, options?: BashAnalysisOptions) => Decision;
|
|
17
19
|
declare const runHook: () => void;
|
|
18
|
-
export { collectPostToolUseRules, collectPreToolUseRules, decide, normalizeToolName, runHook, runRules, runRulesSync, };
|
|
20
|
+
export { collectPostToolUseRules, collectPreToolUseRules, decide, decideBash, normalizeToolName, runHook, runRules, runRulesSync, };
|
package/dist/types/index.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ export type { Decision } from './lib/decision';
|
|
|
2
2
|
export type { HookEvent } from './lib/event';
|
|
3
3
|
export type { Config, ConfigLoad, ResolvedConfig } from './lib/config';
|
|
4
4
|
export { allow, deny, ask, warn } from './lib/decision';
|
|
5
|
-
export { decide } from './dispatch';
|
|
5
|
+
export { decide, decideBash } from './dispatch';
|
|
6
6
|
export { getDefaultConfig, loadConfig, loadConfigResult, mergeWithDefaults } from './lib/config';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Command } from 'unbash';
|
|
2
|
+
import type { ExecutionContext, ExecutionHost } from './execution-types';
|
|
3
|
+
import type { ExecutionCarrierAlias, ShellInvocation } from './types';
|
|
4
|
+
import type { Environment } from './values';
|
|
5
|
+
declare class ExecutionCarriers {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(host: ExecutionHost, aliases: readonly ExecutionCarrierAlias[]);
|
|
8
|
+
isCarrierCommand(command: Command): boolean;
|
|
9
|
+
inspect(invocation: ShellInvocation, environment: Environment, context: ExecutionContext): boolean;
|
|
10
|
+
}
|
|
11
|
+
export { ExecutionCarriers };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Schema } from 'effect';
|
|
2
|
+
declare const ExecutionCarrierKindSchema: Schema.Literal<"ssh">;
|
|
3
|
+
declare const ExecutionCarrierAliasSchema: Schema.Struct<{
|
|
4
|
+
readonly command: Schema.$Array<Schema.NonEmptyString>;
|
|
5
|
+
readonly equivalentTo: Schema.Literal<"ssh">;
|
|
6
|
+
}>;
|
|
7
|
+
declare const ShellConfigSchema: Schema.Struct<{
|
|
8
|
+
readonly executionCarrierAliases: Schema.optional<Schema.$Array<Schema.Struct<{
|
|
9
|
+
readonly command: Schema.$Array<Schema.NonEmptyString>;
|
|
10
|
+
readonly equivalentTo: Schema.Literal<"ssh">;
|
|
11
|
+
}>>>;
|
|
12
|
+
}>;
|
|
13
|
+
type ExecutionCarrierAlias = typeof ExecutionCarrierAliasSchema.Type;
|
|
14
|
+
type ExecutionCarrierKind = typeof ExecutionCarrierKindSchema.Type;
|
|
15
|
+
type ShellConfig = typeof ShellConfigSchema.Type;
|
|
16
|
+
export type { ExecutionCarrierAlias, ExecutionCarrierKind, ShellConfig };
|
|
17
|
+
export { ExecutionCarrierAliasSchema, ExecutionCarrierKindSchema, ShellConfigSchema };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ShellDiagnosticKind, ShellInvocation, ShellWord, SourceRange } from './types';
|
|
2
|
+
import type { Environment } from './values';
|
|
3
|
+
interface ExecutionContext {
|
|
4
|
+
readonly inspectedPipelineInput: boolean;
|
|
5
|
+
readonly source: string;
|
|
6
|
+
readonly pipeline: ShellInvocation['pipeline'];
|
|
7
|
+
}
|
|
8
|
+
interface ExecutionHost {
|
|
9
|
+
readonly addDiagnostic: (kind: ShellDiagnosticKind, message: string, range: SourceRange) => void;
|
|
10
|
+
readonly emitSynthetic: (words: readonly ShellWord[], parent: ShellInvocation, environment: Environment, context: ExecutionContext) => void;
|
|
11
|
+
readonly inspectShellSource: (word: ShellWord | undefined, environment: Environment, context: ExecutionContext) => void;
|
|
12
|
+
}
|
|
13
|
+
export type { ExecutionContext, ExecutionHost };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Node, Redirect } from 'unbash';
|
|
2
|
+
import type { ExecutionContext, ExecutionHost } from './execution-types';
|
|
3
|
+
import type { ExecutionCarrierAlias, ShellInvocation } from './types';
|
|
4
|
+
import { type Environment } from './values';
|
|
5
|
+
declare class ExecutionInspector {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(host: ExecutionHost, carrierAliases: readonly ExecutionCarrierAlias[]);
|
|
8
|
+
inspectShellInput(invocation: ShellInvocation, redirects: readonly Redirect[], environment: Environment, context: ExecutionContext): boolean;
|
|
9
|
+
inspectWrapper(invocation: ShellInvocation, environment: Environment, context: ExecutionContext, inlineShellSource?: boolean): void;
|
|
10
|
+
inspectPipelineInputs(commands: readonly Node[], environment: Environment, context: ExecutionContext): ReadonlySet<number>;
|
|
11
|
+
}
|
|
12
|
+
export { ExecutionInspector };
|
|
13
|
+
export type { ExecutionContext } from './execution-types';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ShellProgram } from './types';
|
|
2
|
+
declare const isSafePathTarget: (raw: string, extraRelative?: readonly string[], extraAbsolute?: readonly string[]) => boolean;
|
|
3
|
+
declare const safeScopesSummary: (extraRelative?: readonly string[], extraAbsolute?: readonly string[]) => string;
|
|
4
|
+
declare const hasBypass: (program: ShellProgram) => boolean;
|
|
5
|
+
export type { BashAnalysisOptions, ExecutionCarrierAlias, ExecutionCarrierKind, PipelinePosition, ShellDiagnostic, ShellDiagnosticKind, ShellInvocation, ShellProgram, ShellRedirect, ShellWord, ShellWordKind, SourceRange, } from './types';
|
|
6
|
+
export { analyzeBash } from './analyze';
|
|
7
|
+
export { DYNAMIC_VALUE } from './values';
|
|
8
|
+
export { hasBypass, isSafePathTarget, safeScopesSummary };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Node } from 'unbash';
|
|
2
|
+
import type { ExecutionCarriers } from './carriers';
|
|
3
|
+
import type { ExecutionContext, ExecutionHost } from './execution-types';
|
|
4
|
+
import type { Environment } from './values';
|
|
5
|
+
declare class PipelineInputInspector {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(host: ExecutionHost, carriers: ExecutionCarriers);
|
|
8
|
+
inspect(commands: readonly Node[], environment: Environment, context: ExecutionContext): ReadonlySet<number>;
|
|
9
|
+
}
|
|
10
|
+
export { PipelineInputInspector };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Command } from 'unbash';
|
|
2
|
+
import type { ShellWord, SourceRange } from './types';
|
|
3
|
+
declare const rangeOf: (node: {
|
|
4
|
+
readonly pos: number;
|
|
5
|
+
readonly end: number;
|
|
6
|
+
}) => SourceRange;
|
|
7
|
+
declare const basename: (value: string) => string;
|
|
8
|
+
declare const staticCommandWords: (command: Command) => ShellWord[] | null;
|
|
9
|
+
export { basename, rangeOf, staticCommandWords };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { ExecutionCarrierAlias } from './config';
|
|
2
|
+
interface SourceRange {
|
|
3
|
+
readonly start: number;
|
|
4
|
+
readonly end: number;
|
|
5
|
+
}
|
|
6
|
+
type ShellWordKind = 'literal' | 'dynamic' | 'trusted-temp-path' | 'background-pid';
|
|
7
|
+
interface BashAnalysisOptions {
|
|
8
|
+
readonly cwd?: string;
|
|
9
|
+
readonly executionCarrierAliases?: readonly ExecutionCarrierAlias[];
|
|
10
|
+
readonly positionalArguments?: readonly string[];
|
|
11
|
+
}
|
|
12
|
+
interface ShellWord {
|
|
13
|
+
/** Raw shell source for this word. */
|
|
14
|
+
readonly source: string;
|
|
15
|
+
/** Dequoted policy value. Dynamic values use a fail-closed sentinel. */
|
|
16
|
+
readonly value: string;
|
|
17
|
+
readonly kind: ShellWordKind;
|
|
18
|
+
readonly range: SourceRange;
|
|
19
|
+
readonly quoted: boolean;
|
|
20
|
+
readonly variable?: string;
|
|
21
|
+
}
|
|
22
|
+
interface ShellRedirect {
|
|
23
|
+
/** Source bytes for a heredoc; never execute these bytes during inspection. */
|
|
24
|
+
readonly heredoc?: {
|
|
25
|
+
readonly content: string;
|
|
26
|
+
readonly quoted: boolean;
|
|
27
|
+
};
|
|
28
|
+
readonly op: '>' | '>>' | '<' | '<<' | '<<<' | '<>' | '>&' | '<&' | '&>' | '&>>';
|
|
29
|
+
readonly target: ShellWord;
|
|
30
|
+
readonly range: SourceRange;
|
|
31
|
+
}
|
|
32
|
+
interface PipelinePosition {
|
|
33
|
+
readonly id: number;
|
|
34
|
+
readonly index: number;
|
|
35
|
+
}
|
|
36
|
+
interface ShellInvocation {
|
|
37
|
+
readonly id: number;
|
|
38
|
+
readonly head: string;
|
|
39
|
+
readonly words: readonly ShellWord[];
|
|
40
|
+
readonly tokens: readonly string[];
|
|
41
|
+
readonly args: readonly string[];
|
|
42
|
+
readonly flags: readonly string[];
|
|
43
|
+
readonly redirects: readonly ShellRedirect[];
|
|
44
|
+
readonly raw: string;
|
|
45
|
+
readonly range: SourceRange;
|
|
46
|
+
readonly pipeline: PipelinePosition | undefined;
|
|
47
|
+
readonly synthetic: boolean;
|
|
48
|
+
}
|
|
49
|
+
type ShellDiagnosticKind = 'parse-error' | 'dynamic-executable' | 'dynamic-shell-source' | 'eval' | 'function' | 'alias';
|
|
50
|
+
interface ShellDiagnostic {
|
|
51
|
+
readonly kind: ShellDiagnosticKind;
|
|
52
|
+
readonly message: string;
|
|
53
|
+
readonly range: SourceRange;
|
|
54
|
+
}
|
|
55
|
+
interface ShellProgram {
|
|
56
|
+
readonly environmentAssignments?: readonly string[];
|
|
57
|
+
readonly source: string;
|
|
58
|
+
readonly invocations: readonly ShellInvocation[];
|
|
59
|
+
readonly redirects: readonly ShellRedirect[];
|
|
60
|
+
readonly diagnostics: readonly ShellDiagnostic[];
|
|
61
|
+
readonly hasBypass: boolean;
|
|
62
|
+
}
|
|
63
|
+
export type { BashAnalysisOptions, PipelinePosition, ShellDiagnostic, ShellDiagnosticKind, ShellInvocation, ShellProgram, ShellRedirect, ShellWord, ShellWordKind, SourceRange, };
|
|
64
|
+
export type { ExecutionCarrierAlias, ExecutionCarrierKind } from './config';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Function as BashFunction, Word, WordPart } from 'unbash';
|
|
2
|
+
import type { ShellWord } from './types';
|
|
3
|
+
declare const DYNAMIC_VALUE = "__tripwire_dynamic_shell_value__";
|
|
4
|
+
declare const BACKGROUND_PID_VALUE = "__tripwire_background_pid__";
|
|
5
|
+
interface TrustedTempValue {
|
|
6
|
+
readonly variable: string;
|
|
7
|
+
}
|
|
8
|
+
interface Environment {
|
|
9
|
+
readonly aliases: Map<string, string>;
|
|
10
|
+
backgroundPidAvailable: boolean;
|
|
11
|
+
readonly bindings: Map<string, ShellWord>;
|
|
12
|
+
readonly functions: Map<string, BashFunction>;
|
|
13
|
+
readonly temps: Map<string, TrustedTempValue>;
|
|
14
|
+
}
|
|
15
|
+
declare const emptyEnvironment: () => Environment;
|
|
16
|
+
declare const cloneEnvironment: (environment: Environment) => Environment;
|
|
17
|
+
declare const isQuotedPart: (part: WordPart) => boolean;
|
|
18
|
+
declare const wordIsStatic: (word: Word) => boolean;
|
|
19
|
+
declare const staticGeneratedValue: (word: Word, environment: Environment) => string | null;
|
|
20
|
+
declare const isTrustedMktemp: (word: Word, environment: Environment) => boolean;
|
|
21
|
+
declare const trustedTempWord: (word: Word, environment: Environment) => ShellWord | null;
|
|
22
|
+
declare const boundWord: (word: Word, environment: Environment) => ShellWord | null;
|
|
23
|
+
declare const backgroundPidWord: (word: Word, environment: Environment) => ShellWord | null;
|
|
24
|
+
export { DYNAMIC_VALUE, BACKGROUND_PID_VALUE, backgroundPidWord, boundWord, cloneEnvironment, emptyEnvironment, isQuotedPart, isTrustedMktemp, staticGeneratedValue, trustedTempWord, wordIsStatic, };
|
|
25
|
+
export type { Environment };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ShellInvocation, ShellWord } from './types';
|
|
2
|
+
declare const SHELL_WRAPPER_HEADS: ReadonlySet<string>;
|
|
3
|
+
declare const HEAD_RENAMING_HEADS: ReadonlySet<string>;
|
|
4
|
+
declare const skipOptions: (words: readonly ShellWord[], start: number, valueFlags: ReadonlySet<string>) => number;
|
|
5
|
+
declare const skipHeadRenamingPrefix: (invocation: ShellInvocation) => number;
|
|
6
|
+
declare const commandFlagValueIndex: (words: readonly ShellWord[], flag: string) => number | null;
|
|
7
|
+
declare const namedFlagValueIndex: (words: readonly ShellWord[], flags: ReadonlySet<string>, start?: number) => number | null;
|
|
8
|
+
declare const pickExecRoot: (words: readonly ShellWord[], execFlagIndex: number, kind: 'fd' | 'find') => ShellWord;
|
|
9
|
+
declare const FD_EXEC_FLAGS: ReadonlySet<string>;
|
|
10
|
+
declare const FD_PLACEHOLDERS: ReadonlySet<string>;
|
|
11
|
+
declare const FIND_EXEC_FLAGS: ReadonlySet<string>;
|
|
12
|
+
declare const FIND_PLACEHOLDERS: ReadonlySet<string>;
|
|
13
|
+
declare const RTK_WRAPPER_SUBCOMMANDS: ReadonlySet<string>;
|
|
14
|
+
interface PrefixWrapper {
|
|
15
|
+
readonly valueFlags: ReadonlySet<string>;
|
|
16
|
+
readonly skipPositionals: number;
|
|
17
|
+
readonly shellFlag: boolean;
|
|
18
|
+
}
|
|
19
|
+
declare const PREFIX_WRAPPERS: Readonly<Record<string, PrefixWrapper>>;
|
|
20
|
+
export type { PrefixWrapper };
|
|
21
|
+
export { FD_EXEC_FLAGS, FD_PLACEHOLDERS, FIND_EXEC_FLAGS, FIND_PLACEHOLDERS, HEAD_RENAMING_HEADS, PREFIX_WRAPPERS, RTK_WRAPPER_SUBCOMMANDS, SHELL_WRAPPER_HEADS, commandFlagValueIndex, namedFlagValueIndex, pickExecRoot, skipHeadRenamingPrefix, skipOptions, };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CodeLanguage, CodeOperation, CodeRange, Value } from './types';
|
|
2
|
+
interface CallContext {
|
|
3
|
+
readonly language: CodeLanguage;
|
|
4
|
+
readonly range: CodeRange;
|
|
5
|
+
readonly operations: CodeOperation[];
|
|
6
|
+
}
|
|
7
|
+
declare const resolveCall: (fn: Value, args: readonly Value[], context: CallContext) => Value;
|
|
8
|
+
export { resolveCall };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ShellInvocation } from '../bash';
|
|
2
|
+
import type { CodeLanguage } from './types';
|
|
3
|
+
type CodeInput = {
|
|
4
|
+
readonly kind: 'source';
|
|
5
|
+
readonly language: CodeLanguage;
|
|
6
|
+
readonly source: string;
|
|
7
|
+
} | {
|
|
8
|
+
readonly kind: 'command';
|
|
9
|
+
readonly argv: readonly string[];
|
|
10
|
+
} | {
|
|
11
|
+
readonly kind: 'blocked';
|
|
12
|
+
readonly reason: string;
|
|
13
|
+
} | {
|
|
14
|
+
readonly kind: 'irrelevant';
|
|
15
|
+
};
|
|
16
|
+
declare const interpreterLanguage: (head: string) => CodeLanguage | null;
|
|
17
|
+
declare const interpreterInput: (invocation: ShellInvocation) => CodeInput;
|
|
18
|
+
export { interpreterInput, interpreterLanguage };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { SyntaxNode } from '@lezer/common';
|
|
2
|
+
import type { Value } from './types';
|
|
3
|
+
interface ControlContext {
|
|
4
|
+
readonly bindings: Map<string, Value>;
|
|
5
|
+
readonly text: (node: SyntaxNode) => string;
|
|
6
|
+
readonly evaluate: (node: SyntaxNode) => Value;
|
|
7
|
+
readonly statement: (node: SyntaxNode) => void;
|
|
8
|
+
}
|
|
9
|
+
declare const inspectBranches: (node: SyntaxNode, context: ControlContext) => void;
|
|
10
|
+
declare const inspectLoop: (node: SyntaxNode, context: ControlContext) => void;
|
|
11
|
+
declare const inspectComprehension: (parts: readonly SyntaxNode[], context: ControlContext) => Value;
|
|
12
|
+
export { inspectBranches, inspectComprehension, inspectLoop };
|
|
13
|
+
export type { ControlContext };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CodeLanguage, Value } from './types';
|
|
2
|
+
declare const data: Value;
|
|
3
|
+
declare const fileText: (path: string) => Value;
|
|
4
|
+
declare const isData: (value: Value) => boolean;
|
|
5
|
+
declare const requireData: (values: readonly Value[]) => void;
|
|
6
|
+
declare const writeKind: (target: string, value: Value | undefined) => 'write' | 'truncate';
|
|
7
|
+
declare const dataMethod: (receiver: Value, name: string, args: readonly Value[], language: CodeLanguage) => Value;
|
|
8
|
+
declare const dataCall: (name: string, args: readonly Value[]) => Value | null;
|
|
9
|
+
export { data, dataCall, dataMethod, fileText, isData, requireData, writeKind };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SyntaxNode } from '@lezer/common';
|
|
2
|
+
import type { CodeLanguage, Value } from './types';
|
|
3
|
+
declare const pythonImport: (parts: readonly SyntaxNode[], text: (node: SyntaxNode) => string) => ReadonlyMap<string, Value>;
|
|
4
|
+
declare const javascriptImport: (parts: readonly SyntaxNode[], text: (node: SyntaxNode) => string, language: CodeLanguage) => ReadonlyMap<string, Value>;
|
|
5
|
+
export { javascriptImport, pythonImport };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { SyntaxNode } from '@lezer/common';
|
|
2
|
+
import type { CodeLanguage } from './types';
|
|
3
|
+
declare class CodeInspectionError extends Error {
|
|
4
|
+
name: string;
|
|
5
|
+
}
|
|
6
|
+
declare const failInspection: (message: string) => never;
|
|
7
|
+
declare const children: (node: SyntaxNode) => SyntaxNode[];
|
|
8
|
+
declare const parseCode: (language: CodeLanguage, source: string) => SyntaxNode;
|
|
9
|
+
declare const stringLiteral: (text: string, language?: CodeLanguage) => string;
|
|
10
|
+
export { CodeInspectionError, children, failInspection, parseCode, stringLiteral };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
type CodeLanguage = 'python' | 'javascript' | 'typescript';
|
|
2
|
+
interface CodeRange {
|
|
3
|
+
readonly start: number;
|
|
4
|
+
readonly end: number;
|
|
5
|
+
}
|
|
6
|
+
type CodeOperation = {
|
|
7
|
+
readonly kind: 'read' | 'write' | 'delete' | 'truncate';
|
|
8
|
+
readonly path: string;
|
|
9
|
+
readonly range: CodeRange;
|
|
10
|
+
} | {
|
|
11
|
+
readonly kind: 'process';
|
|
12
|
+
readonly argv: readonly string[];
|
|
13
|
+
readonly range: CodeRange;
|
|
14
|
+
};
|
|
15
|
+
interface CodeReport {
|
|
16
|
+
readonly operations: readonly CodeOperation[];
|
|
17
|
+
/** Any gap blocks authorization, including parser recovery and budget exhaustion. */
|
|
18
|
+
readonly gap: string | null;
|
|
19
|
+
}
|
|
20
|
+
type Value = {
|
|
21
|
+
readonly kind: 'data';
|
|
22
|
+
} | {
|
|
23
|
+
readonly kind: 'text';
|
|
24
|
+
readonly path: string | null;
|
|
25
|
+
readonly preservesNonempty: boolean;
|
|
26
|
+
} | {
|
|
27
|
+
readonly kind: 'string';
|
|
28
|
+
readonly value: string;
|
|
29
|
+
} | {
|
|
30
|
+
readonly kind: 'number';
|
|
31
|
+
readonly value: number;
|
|
32
|
+
} | {
|
|
33
|
+
readonly kind: 'symbol';
|
|
34
|
+
readonly name: string;
|
|
35
|
+
} | {
|
|
36
|
+
readonly kind: 'path' | 'file';
|
|
37
|
+
readonly path: string;
|
|
38
|
+
} | {
|
|
39
|
+
readonly kind: 'method';
|
|
40
|
+
readonly receiver: Value;
|
|
41
|
+
readonly name: string;
|
|
42
|
+
} | {
|
|
43
|
+
readonly kind: 'list';
|
|
44
|
+
readonly items: readonly Value[];
|
|
45
|
+
} | {
|
|
46
|
+
readonly kind: 'object';
|
|
47
|
+
readonly entries: ReadonlyMap<string, Value>;
|
|
48
|
+
} | {
|
|
49
|
+
readonly kind: 'unknown';
|
|
50
|
+
};
|
|
51
|
+
export type { CodeLanguage, CodeOperation, CodeRange, CodeReport, Value };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ShellInvocation } from '../bash';
|
|
2
|
+
type UvInvocation = {
|
|
3
|
+
readonly kind: 'command';
|
|
4
|
+
readonly argv: readonly string[];
|
|
5
|
+
readonly noSync: boolean;
|
|
6
|
+
} | {
|
|
7
|
+
readonly kind: 'blocked';
|
|
8
|
+
readonly reason: string;
|
|
9
|
+
} | {
|
|
10
|
+
readonly kind: 'irrelevant';
|
|
11
|
+
};
|
|
12
|
+
declare const uvInvocation: (invocation: ShellInvocation) => UvInvocation;
|
|
13
|
+
export { uvInvocation };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CodeLanguage, Value } from './types';
|
|
2
|
+
declare const unknown: Value;
|
|
3
|
+
declare const symbol: (name: string) => Value;
|
|
4
|
+
declare const textValue: (value: string) => Value;
|
|
5
|
+
declare const valueString: (value: Value | undefined) => string;
|
|
6
|
+
declare const initialBindings: (language: CodeLanguage) => Map<string, Value>;
|
|
7
|
+
declare const moduleName: (name: string, language: CodeLanguage) => string;
|
|
8
|
+
declare const pythonJoin: (parts: readonly string[]) => string;
|
|
9
|
+
export { initialBindings, moduleName, pythonJoin, symbol, textValue, unknown, valueString };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { Effect, Schema } from 'effect';
|
|
2
|
+
import { type ExecutionCarrierAlias } from './bash/config';
|
|
3
|
+
import { type RuleActions } from './rule-actions';
|
|
2
4
|
declare const BlockRuleSchema: Schema.Struct<{
|
|
3
5
|
readonly pattern: Schema.String;
|
|
4
6
|
readonly message: Schema.String;
|
|
@@ -72,10 +74,35 @@ declare const ConfigSchema: Schema.Struct<{
|
|
|
72
74
|
readonly values: Schema.$Array<Schema.String>;
|
|
73
75
|
}>>>;
|
|
74
76
|
}>>>;
|
|
77
|
+
readonly ruleActions: Schema.optional<Schema.Struct<{
|
|
78
|
+
readonly 'brew-mutation': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
79
|
+
readonly 'chmod-777-recursive': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
80
|
+
readonly 'defaults-write': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
81
|
+
readonly 'dscl-mutate': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
82
|
+
readonly 'launchctl-mutation': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
83
|
+
readonly 'mas-mutation': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
84
|
+
readonly 'no-gpg-sign': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
85
|
+
readonly 'no-verify': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
86
|
+
readonly osascript: Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
87
|
+
readonly 'pmset-write': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
88
|
+
readonly 'rsync-delete': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
89
|
+
readonly 'scutil-set': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
90
|
+
readonly 'security-keychain-add-write': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
91
|
+
readonly 'softwareupdate-install': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
92
|
+
readonly sudo: Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
93
|
+
readonly systemsetup: Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
94
|
+
readonly topgrade: Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
95
|
+
}>>;
|
|
75
96
|
readonly secretScanner: Schema.optional<Schema.Struct<{
|
|
76
97
|
readonly executable: Schema.String;
|
|
77
98
|
readonly timeoutMs: Schema.Finite;
|
|
78
99
|
}>>;
|
|
100
|
+
readonly shell: Schema.optional<Schema.Struct<{
|
|
101
|
+
readonly executionCarrierAliases: Schema.optional<Schema.$Array<Schema.Struct<{
|
|
102
|
+
readonly command: Schema.$Array<Schema.NonEmptyString>;
|
|
103
|
+
readonly equivalentTo: Schema.Literal<"ssh">;
|
|
104
|
+
}>>>;
|
|
105
|
+
}>>;
|
|
79
106
|
}>;
|
|
80
107
|
declare const CONFIG_PATH: string;
|
|
81
108
|
declare const getDefaultConfig: () => ResolvedConfig;
|
|
@@ -94,6 +121,7 @@ export type GitConfig = typeof GitConfigSchema.Type;
|
|
|
94
121
|
export type SafePathsConfig = typeof SafePathsConfigSchema.Type;
|
|
95
122
|
export type ToolPolicy = typeof ToolPolicySchema.Type;
|
|
96
123
|
export type SecretScannerConfig = typeof SecretScannerConfigSchema.Type;
|
|
124
|
+
export type { ExecutionCarrierAlias, ShellConfig } from './bash/config';
|
|
97
125
|
export type Config = typeof ConfigSchema.Type;
|
|
98
126
|
export interface ResolvedConfig {
|
|
99
127
|
readonly git: {
|
|
@@ -104,7 +132,11 @@ export interface ResolvedConfig {
|
|
|
104
132
|
readonly toolPolicies: readonly ToolPolicy[];
|
|
105
133
|
readonly blockedCommands: readonly BlockRule[];
|
|
106
134
|
readonly allowedCommands: readonly BlockRule[];
|
|
135
|
+
readonly ruleActions: RuleActions;
|
|
107
136
|
readonly secretScanner: SecretScannerConfig;
|
|
137
|
+
readonly shell: {
|
|
138
|
+
readonly executionCarrierAliases: readonly ExecutionCarrierAlias[];
|
|
139
|
+
};
|
|
108
140
|
}
|
|
109
141
|
export type { ConfigLoad };
|
|
110
142
|
export { CONFIG_PATH, ConfigSchema, SecretScannerConfigSchema, getDefaultConfig, mergeWithDefaults, };
|
|
@@ -37,9 +37,15 @@ interface ReadResponse {
|
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
39
|
declare const isBashInput: (x: unknown) => x is BashInput;
|
|
40
|
+
declare const decodeCodeInput: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => import("effect/Option").Option<string | {
|
|
41
|
+
readonly code: string;
|
|
42
|
+
}>;
|
|
43
|
+
declare const decodeExecInput: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => import("effect/Option").Option<{
|
|
44
|
+
readonly cmd: string;
|
|
45
|
+
}>;
|
|
40
46
|
declare const isEditInput: (x: unknown) => x is EditInput;
|
|
41
47
|
declare const isWriteInput: (x: unknown) => x is WriteInput;
|
|
42
48
|
declare const isReadInput: (x: unknown) => x is ReadInput;
|
|
43
49
|
declare const extractResponseText: (toolName: string, response: unknown) => string;
|
|
44
50
|
export type { BashInput, BashResponse, EditInput, HookEventType as HookEvent, ReadInput, ReadResponse, WriteInput, };
|
|
45
|
-
export { HookEvent as HookEventSchema, extractResponseText, isBashInput, isEditInput, isReadInput, isWriteInput, };
|
|
51
|
+
export { HookEvent as HookEventSchema, extractResponseText, isBashInput, isEditInput, isReadInput, isWriteInput, decodeCodeInput, decodeExecInput, };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Schema } from 'effect';
|
|
2
|
+
import { type Decision } from './decision';
|
|
3
|
+
declare const RuleActionSchema: Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>;
|
|
4
|
+
declare const RuleActionsSchema: Schema.Struct<{
|
|
5
|
+
readonly 'brew-mutation': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
6
|
+
readonly 'chmod-777-recursive': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
7
|
+
readonly 'defaults-write': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
8
|
+
readonly 'dscl-mutate': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
9
|
+
readonly 'launchctl-mutation': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
10
|
+
readonly 'mas-mutation': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
11
|
+
readonly 'no-gpg-sign': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
12
|
+
readonly 'no-verify': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
13
|
+
readonly osascript: Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
14
|
+
readonly 'pmset-write': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
15
|
+
readonly 'rsync-delete': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
16
|
+
readonly 'scutil-set': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
17
|
+
readonly 'security-keychain-add-write': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
18
|
+
readonly 'softwareupdate-install': Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
19
|
+
readonly sudo: Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
20
|
+
readonly systemsetup: Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
21
|
+
readonly topgrade: Schema.optional<Schema.Literals<readonly ["allow", "warn", "ask", "deny"]>>;
|
|
22
|
+
}>;
|
|
23
|
+
type RuleAction = typeof RuleActionSchema.Type;
|
|
24
|
+
type RuleActions = typeof RuleActionsSchema.Type;
|
|
25
|
+
declare const applyRuleAction: (decision: Decision, actions: RuleActions) => Decision;
|
|
26
|
+
export type { RuleAction, RuleActions };
|
|
27
|
+
export { applyRuleAction, RuleActionSchema, RuleActionsSchema };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ShellProgram } from '../lib/bash';
|
|
2
|
+
import { type Decision } from '../lib/decision';
|
|
3
|
+
declare const NON_BYPASSABLE_RULES: ReadonlySet<string>;
|
|
4
|
+
declare const applyShellBypass: (program: ShellProgram, decision: Decision) => Decision;
|
|
5
|
+
export { applyShellBypass, NON_BYPASSABLE_RULES };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ShellProgram } from '../lib/bash';
|
|
2
2
|
import { type Decision } from '../lib/decision';
|
|
3
|
-
|
|
4
|
-
declare const bashDeny: (
|
|
5
|
-
export { bashDeny
|
|
3
|
+
import { type RuleActions } from '../lib/rule-actions';
|
|
4
|
+
declare const bashDeny: (program: ShellProgram, ruleActions?: RuleActions) => Decision;
|
|
5
|
+
export { bashDeny };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ShellProgram } from '../lib/bash';
|
|
2
2
|
import type { GitConfig } from '../lib/config';
|
|
3
3
|
import { type Decision } from '../lib/decision';
|
|
4
|
-
declare const bashGit: (
|
|
4
|
+
declare const bashGit: (program: ShellProgram, config: GitConfig) => Decision;
|
|
5
5
|
export { bashGit };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ShellProgram } from '../lib/bash';
|
|
2
2
|
import { type Decision } from '../lib/decision';
|
|
3
|
-
declare const bashNetworkInstall: (
|
|
3
|
+
declare const bashNetworkInstall: (program: ShellProgram) => Decision;
|
|
4
4
|
export { bashNetworkInstall };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ShellProgram } from '../lib/bash';
|
|
2
2
|
import { type Decision } from '../lib/decision';
|
|
3
|
-
declare const bashRedirect: (
|
|
3
|
+
declare const bashRedirect: (program: ShellProgram) => Decision;
|
|
4
4
|
export { bashRedirect };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type ShellProgram } from '../lib/bash';
|
|
2
2
|
import type { SafePathsConfig } from '../lib/config';
|
|
3
3
|
import { type Decision } from '../lib/decision';
|
|
4
|
-
declare const bashScopedRm: (
|
|
4
|
+
declare const bashScopedRm: (program: ShellProgram, config: SafePathsConfig) => Decision;
|
|
5
5
|
export { bashScopedRm };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ShellProgram } from '../lib/bash';
|
|
2
2
|
import { type Decision } from '../lib/decision';
|
|
3
|
-
declare const bashTarExplosion: (
|
|
3
|
+
declare const bashTarExplosion: (program: ShellProgram) => Decision;
|
|
4
4
|
export { bashTarExplosion };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type ShellProgram } from '../lib/bash';
|
|
2
2
|
import type { BlockRule } from '../lib/config';
|
|
3
3
|
import { type Decision } from '../lib/decision';
|
|
4
|
-
declare const matchPattern: (
|
|
5
|
-
export declare const configCustom: (
|
|
4
|
+
declare const matchPattern: (program: ShellProgram, rule: BlockRule) => boolean;
|
|
5
|
+
export declare const configCustom: (program: ShellProgram, blockedCommands: readonly BlockRule[], allowedCommands: readonly BlockRule[]) => Decision;
|
|
6
6
|
export { matchPattern };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ShellProgram } from '../lib/bash';
|
|
2
|
+
import type { CodeLanguage } from '../lib/code/types';
|
|
3
|
+
import type { SafePathsConfig } from '../lib/config';
|
|
4
|
+
import { type Decision } from '../lib/decision';
|
|
5
|
+
interface CodePolicy {
|
|
6
|
+
readonly safePaths: SafePathsConfig;
|
|
7
|
+
readonly cwd: string;
|
|
8
|
+
readonly inspectCommand: (command: string) => Decision;
|
|
9
|
+
readonly remoteHeads: ReadonlySet<string>;
|
|
10
|
+
}
|
|
11
|
+
declare const codeDeny: (message: string) => Decision;
|
|
12
|
+
declare const inspectCode: (language: CodeLanguage, source: string, policy: CodePolicy) => Decision;
|
|
13
|
+
declare const embeddedCode: (program: ShellProgram, policy: CodePolicy) => Decision;
|
|
14
|
+
export { codeDeny, embeddedCode, inspectCode };
|
|
15
|
+
export type { CodePolicy };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ShellProgram } from '../lib/bash';
|
|
2
2
|
import type { ToolPolicy } from '../lib/config';
|
|
3
3
|
import { type Decision } from '../lib/decision';
|
|
4
|
-
declare const toolPolicy: (
|
|
4
|
+
declare const toolPolicy: (program: ShellProgram, policies: readonly ToolPolicy[]) => Decision;
|
|
5
5
|
export { toolPolicy };
|