@knowttl/artium-axi 0.0.16 → 0.0.17
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 +7 -1
- package/bin/artium-axi.mjs +22 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -163,7 +163,13 @@ Artium's authenticated setup fetches managed skills; a standalone skill installe
|
|
|
163
163
|
All tools start disabled; write access defaults to off.
|
|
164
164
|
Administrator capability alone grants no tool access; upstream permissions remain an additional boundary.
|
|
165
165
|
|
|
166
|
-
Microsoft Graph
|
|
166
|
+
Microsoft Graph defaults to the `entra` pack.
|
|
167
|
+
Administrators can opt in to the single read-only `security hunting query` command for Defender XDR advanced hunting with `enabledPacks: ["entra", "security"]` in the managed tool settings.
|
|
168
|
+
Hunting accepts exactly one UTF-8 plain-text upload named `query.kql`, at most 64 KiB, through `artium-axi mg-axi security hunting query --file query.kql`.
|
|
169
|
+
See [client input handling](docs/client-reference.md#command-surface-and-subcommands) for local file paths and upload restrictions.
|
|
170
|
+
Queries must use the upstream restricted read-only KQL subset.
|
|
171
|
+
The existing mg-axi role grant is required; other security commands remain unavailable.
|
|
172
|
+
See [Graph credential setup](docs/tool-credentials.md#microsoft-graph) for hunting permissions and consent; tenant acceptance remains unverified.
|
|
167
173
|
|
|
168
174
|
Falcon investigation reads include detection lineage, process details and trees, existing sandbox reports, FileVantage changes and device-control policy details.
|
|
169
175
|
|
package/bin/artium-axi.mjs
CHANGED
|
@@ -20191,10 +20191,14 @@ var nativeSettingsSchemas = {
|
|
|
20191
20191
|
"awx-axi": external_exports.strictObject({ allowWrites: external_exports.boolean().optional() }),
|
|
20192
20192
|
"ldap-axi": external_exports.strictObject({}),
|
|
20193
20193
|
"ado-axi": external_exports.strictObject({ allowWrites: external_exports.boolean().optional() }),
|
|
20194
|
-
"mg-axi": external_exports.strictObject({
|
|
20195
|
-
|
|
20196
|
-
|
|
20197
|
-
|
|
20194
|
+
"mg-axi": external_exports.strictObject({
|
|
20195
|
+
enabledPacks: external_exports.array(external_exports.enum(["entra", "security"])).min(1).max(2).refine((packs) => packs.includes("entra") && new Set(packs).size === packs.length).optional(),
|
|
20196
|
+
preview: external_exports.boolean().optional(),
|
|
20197
|
+
writes: external_exports.strictObject({
|
|
20198
|
+
allowWrites: external_exports.boolean(),
|
|
20199
|
+
operations: external_exports.array(external_exports.string().min(1).max(256)).min(1).max(64)
|
|
20200
|
+
}).optional()
|
|
20201
|
+
}),
|
|
20198
20202
|
"falcon-axi": external_exports.strictObject({
|
|
20199
20203
|
allowWrites: external_exports.boolean().optional(),
|
|
20200
20204
|
rtr: falconRtrSettingsSchema.optional(),
|
|
@@ -20744,7 +20748,7 @@ import { resolve } from "node:path";
|
|
|
20744
20748
|
// package.json
|
|
20745
20749
|
var package_default = {
|
|
20746
20750
|
name: "artium-axi",
|
|
20747
|
-
version: "0.0.
|
|
20751
|
+
version: "0.0.17",
|
|
20748
20752
|
private: true,
|
|
20749
20753
|
license: "MIT",
|
|
20750
20754
|
type: "module",
|
|
@@ -29837,7 +29841,8 @@ var mg_axi_default = {
|
|
|
29837
29841
|
"home",
|
|
29838
29842
|
"doctor",
|
|
29839
29843
|
"entra",
|
|
29840
|
-
"api get"
|
|
29844
|
+
"api get",
|
|
29845
|
+
"security hunting query"
|
|
29841
29846
|
],
|
|
29842
29847
|
example: [
|
|
29843
29848
|
"entra",
|
|
@@ -29937,11 +29942,12 @@ var mg_axi_default = {
|
|
|
29937
29942
|
"home",
|
|
29938
29943
|
"doctor",
|
|
29939
29944
|
"entra",
|
|
29940
|
-
"api get"
|
|
29945
|
+
"api get",
|
|
29946
|
+
"security hunting query"
|
|
29941
29947
|
],
|
|
29942
29948
|
inputs: {
|
|
29943
29949
|
stdin: "cursor - only",
|
|
29944
|
-
files: "
|
|
29950
|
+
files: "security hunting query only: one UTF-8 query.kql upload, at most 64 KiB; fixed runner leaf name",
|
|
29945
29951
|
cursor: "opaque token or stdin; never a path",
|
|
29946
29952
|
api: "reviewed GET routes only; pinned Graph destination and operation gates retained"
|
|
29947
29953
|
},
|
|
@@ -29956,7 +29962,8 @@ var mg_axi_default = {
|
|
|
29956
29962
|
],
|
|
29957
29963
|
knownOutputScanValues: [
|
|
29958
29964
|
"clientSecret and trimmed clientSecret",
|
|
29959
|
-
"privateKey and normalized PEM"
|
|
29965
|
+
"privateKey and normalized PEM",
|
|
29966
|
+
"hunting query text"
|
|
29960
29967
|
],
|
|
29961
29968
|
outputScanLimit: "Upstream-minted Graph tokens and assertions are not available during prepare; live redaction remains unverified.",
|
|
29962
29969
|
resources: {
|
|
@@ -44372,8 +44379,9 @@ async function toolInput(tool, original) {
|
|
|
44372
44379
|
const args = [...original];
|
|
44373
44380
|
const input2 = {};
|
|
44374
44381
|
let totalFileBytes = 0;
|
|
44375
|
-
|
|
44376
|
-
|
|
44382
|
+
const hunting = tool === "mg-axi" && args.slice(0, 3).join(" ") === "security hunting query";
|
|
44383
|
+
if ((tool === "az-axi" || tool === "hybrid-axi" || hunting) && !args.some((arg) => ["--help", "-h", "--version", "-v", "-V"].includes(arg))) {
|
|
44384
|
+
const fileFlags = hunting ? ["file"] : tool === "hybrid-axi" ? hybrid_axi_default.adapterBoundary.inputFileFlags : az_axi_default.adapterBoundary.inputFileFlags;
|
|
44377
44385
|
for (let index = 0; index < args.length; index++) {
|
|
44378
44386
|
if (args[index] === "--") break;
|
|
44379
44387
|
const [flag] = args[index].split("=");
|
|
@@ -44385,10 +44393,11 @@ async function toolInput(tool, original) {
|
|
|
44385
44393
|
continue;
|
|
44386
44394
|
}
|
|
44387
44395
|
if (!path || path === "-") throw new ArtiumError("UNSUPPORTED_INPUT", "A file flag requires a local file path.");
|
|
44388
|
-
|
|
44396
|
+
if (hunting && (path.split(/[\\/]/).includes("..") || input2.files?.length)) throw new ArtiumError("INVALID_INPUT");
|
|
44397
|
+
const name = hunting ? "query.kql" : basename(path);
|
|
44389
44398
|
if (input2.files?.some((file2) => file2.name === name)) throw new ArtiumError("INVALID_INPUT", "Upload file names must be distinct.");
|
|
44390
44399
|
if ((input2.files?.length ?? 0) >= inputLimits.files) throw new ArtiumError("INVALID_INPUT", "Too many upload files.");
|
|
44391
|
-
const content = await readBounded(createReadStream(path), inputLimits.fileBytes);
|
|
44400
|
+
const content = await readBounded(createReadStream(path), hunting ? 65536 : inputLimits.fileBytes);
|
|
44392
44401
|
totalFileBytes += content.length;
|
|
44393
44402
|
if (totalFileBytes > inputLimits.totalFileBytes) throw new ArtiumError("INVALID_INPUT", "Uploads exceed the total byte limit.");
|
|
44394
44403
|
input2.files ??= [];
|