@automagik/omni 2.260914.11 → 2.260914.13
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/db/drizzle/0070_config_audit_logs.sql +41 -0
- package/db/drizzle/meta/_journal.json +7 -0
- package/dist/client.d.ts +8 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/commands/audit.d.ts +11 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/index.js +92 -2
- package/dist/server/index.js +1135 -802
- package/package.json +1 -1
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
-- Config-mutation audit log (issue #1152).
|
|
2
|
+
--
|
|
3
|
+
-- api_key_audit_logs records method/path/status only and is dominated by
|
|
4
|
+
-- polling GETs. tenant_audit_logs needs a tenant FK + credential uuid, so it
|
|
5
|
+
-- does not fit single-tenant legacy keys. This table holds one row per
|
|
6
|
+
-- POST/PATCH/PUT/DELETE on config resources (instances, agents, providers,
|
|
7
|
+
-- routes, automations, keys, settings) with actor, request id, client IP,
|
|
8
|
+
-- user agent, target, and before/after of changed fields. Secret-bearing
|
|
9
|
+
-- values are stored only as sha256 prefix fingerprints.
|
|
10
|
+
--
|
|
11
|
+
-- Retention: reads are never written here; keep ~180d.
|
|
12
|
+
--
|
|
13
|
+
-- Hand-written following the 0043/0044/0052 precedent (additive, idempotent).
|
|
14
|
+
-- No explicit BEGIN/COMMIT — the boot migrator executes this file on a pooled
|
|
15
|
+
-- postgres-js connection, which rejects raw transaction control.
|
|
16
|
+
|
|
17
|
+
CREATE TABLE IF NOT EXISTS "config_audit_logs" (
|
|
18
|
+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
19
|
+
"api_key_id" varchar(100),
|
|
20
|
+
"api_key_name" varchar(255),
|
|
21
|
+
"actor" varchar(255),
|
|
22
|
+
"request_id" varchar(100),
|
|
23
|
+
"ip_address" varchar(64),
|
|
24
|
+
"user_agent" text,
|
|
25
|
+
"method" varchar(10) NOT NULL,
|
|
26
|
+
"path" varchar(500) NOT NULL,
|
|
27
|
+
"status_code" integer NOT NULL,
|
|
28
|
+
"action" varchar(100) NOT NULL,
|
|
29
|
+
"target_type" varchar(50) NOT NULL,
|
|
30
|
+
"target_id" varchar(255),
|
|
31
|
+
"changed_fields" text[] DEFAULT '{}'::text[] NOT NULL,
|
|
32
|
+
"changes" jsonb DEFAULT '{}'::jsonb NOT NULL,
|
|
33
|
+
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
CREATE INDEX IF NOT EXISTS "config_audit_logs_target_idx"
|
|
37
|
+
ON "config_audit_logs" ("target_type", "target_id");
|
|
38
|
+
CREATE INDEX IF NOT EXISTS "config_audit_logs_actor_idx"
|
|
39
|
+
ON "config_audit_logs" ("actor");
|
|
40
|
+
CREATE INDEX IF NOT EXISTS "config_audit_logs_created_at_idx"
|
|
41
|
+
ON "config_audit_logs" ("created_at");
|
|
@@ -491,6 +491,13 @@
|
|
|
491
491
|
"when": 1786900000000,
|
|
492
492
|
"tag": "0069_automation_allow_instance_senders",
|
|
493
493
|
"breakpoints": true
|
|
494
|
+
},
|
|
495
|
+
{
|
|
496
|
+
"idx": 70,
|
|
497
|
+
"version": "7",
|
|
498
|
+
"when": 1787000000000,
|
|
499
|
+
"tag": "0070_config_audit_logs",
|
|
500
|
+
"breakpoints": true
|
|
494
501
|
}
|
|
495
502
|
]
|
|
496
503
|
}
|
package/dist/client.d.ts
CHANGED
|
@@ -24,4 +24,12 @@ export declare function getClient(): OmniClient;
|
|
|
24
24
|
* Returns null if not authenticated.
|
|
25
25
|
*/
|
|
26
26
|
export declare function getOptionalClient(): OmniClient | null;
|
|
27
|
+
/**
|
|
28
|
+
* Tag every request to the configured Omni server with `X-Omni-Actor` from
|
|
29
|
+
* `OMNI_ACTOR` (e.g. `claude-session:<id>`, `cli:alice`) so the config audit
|
|
30
|
+
* log (#1152) can tell agents and humans apart. Wraps global fetch because many
|
|
31
|
+
* commands call the API directly instead of through the SDK; requests to any
|
|
32
|
+
* other host are left untouched.
|
|
33
|
+
*/
|
|
34
|
+
export declare function installActorHeader(): void;
|
|
27
35
|
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,UAAU,EAAoB,MAAM,WAAW,CAAC;AAW9D;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,IAAI,KAAK,CAQ5C;AAED;;;GAGG;AACH,wBAAgB,SAAS,IAAI,UAAU,CAyBtC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,UAAU,GAAG,IAAI,CAyBrD"}
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,UAAU,EAAoB,MAAM,WAAW,CAAC;AAW9D;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,IAAI,KAAK,CAQ5C;AAED;;;GAGG;AACH,wBAAgB,SAAS,IAAI,UAAU,CAyBtC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,UAAU,GAAG,IAAI,CAyBrD;AA2BD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAazC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit Commands (issue #1152)
|
|
3
|
+
*
|
|
4
|
+
* omni audit list [--target <id>] [--type <type>] [--actor <x>] [--since <iso>] [--limit <n>]
|
|
5
|
+
* omni audit show <id>
|
|
6
|
+
*
|
|
7
|
+
* Reads the config-mutation audit log. Set OMNI_ACTOR to tag your own calls.
|
|
8
|
+
*/
|
|
9
|
+
import { Command } from 'commander';
|
|
10
|
+
export declare function createAuditCommand(): Command;
|
|
11
|
+
//# sourceMappingURL=audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA6BpC,wBAAgB,kBAAkB,IAAI,OAAO,CAyC5C"}
|
package/dist/index.js
CHANGED
|
@@ -81874,6 +81874,7 @@ __export(exports_schema, {
|
|
|
81874
81874
|
connectorWindowSemanticsValues: () => connectorWindowSemanticsValues,
|
|
81875
81875
|
connectorMutationPolicies: () => connectorMutationPolicies,
|
|
81876
81876
|
connectorLivenessStatuses: () => connectorLivenessStatuses,
|
|
81877
|
+
configAuditLogs: () => configAuditLogs,
|
|
81877
81878
|
conditionOperators: () => conditionOperators,
|
|
81878
81879
|
closeContactOutcomes: () => closeContactOutcomes,
|
|
81879
81880
|
closeContactLogs: () => closeContactLogs,
|
|
@@ -81922,7 +81923,7 @@ __export(exports_schema, {
|
|
|
81922
81923
|
accessRules: () => accessRules,
|
|
81923
81924
|
accessModes: () => accessModes
|
|
81924
81925
|
});
|
|
81925
|
-
var channelTypes, agentTypes, agentSystems, agentEntityTypes, debounceMode, splitDelayMode, supersedeMode, replyFilterMode, agentSessionStrategies, ruleTypes, accessModes, settingValueTypes, apiKeyStatuses, apiKeyProfiles, eventTypes, contentTypes, chatTypes, messageSources, messageTypes, messageStatuses, deliveryStatuses, scheduledMessageDeliveryModes, scheduledMessageStatuses, jobStatuses, providerSchemas, agentProviders, agents, agentRoutes, agentSessions, apiKeys, apiKeyAuditLogs, apiKeysRelations, apiKeyAuditLogsRelations, instances, whatsappTemplates, whatsappFlowKeys, scheduledMessages, persons, platformIdentities, conversations, chats, chatParticipants, omniGroups, messages2, omniEvents, handoffLogs, closeContactOutcomes, closeContactLogs, accessRules, globalSettings, settingChangeHistory, batchJobs, syncJobTypes, syncJobs, mediaContent, chatIdMappings, pluginStorage, agentProvidersRelations, agentsRelations, instancesRelations, syncJobsRelations, personsRelations, platformIdentitiesRelations, conversationsRelations, chatsRelations, chatParticipantsRelations, messagesRelations, omniEventsRelations, accessRulesRelations, globalSettingsRelations, settingChangeHistoryRelations, batchJobsRelations, mediaContentRelations, chatIdMappingsRelations, deadLetterStatuses, deadLetterEvents, payloadStorageConfig, payloadStages, eventPayloads, webhookSignatureAlgorithms, connectorLivenessStatuses, connectorWindowSemanticsValues, connectorMutationPolicies, webhookSources, eventSchemas, conditionOperators, actionTypes, automationDebounceModes, automations2, automationLogStatuses, automationLogs, consumerOffsets, durableConsumers, automationsRelations, automationLogsRelations, triggerLogs, triggerLogsRelations, agentRoutesRelations, agentTaskStatuses, agentTasks, agentTasksRelations, turnStatuses, turnActions, turns, turnsRelations, followUpDisarmReasons, chatFollowUpState, chatFollowUpStateRelations, processedEvents, genieHosts, tenantStatuses, principalTypes, principalStatuses, tenantRoles, membershipStatuses, credentialClasses, authCredentialStatuses, platformApiKeyStatuses, tenants, principals, tenantMemberships, tenantRolePolicies, platformApiKeys, tenantKeyLineage, authCredentials, tenantAuditLogs, platformAuditLogs, platformProviderCatalog, tenantProviderConfig, platformSettings, tenantSettings, platformSettingChangeHistory, tenantSettingChangeHistory, platformPluginStorage, tenantPluginStorage, platformPayloadStorageConfig, tenantPayloadStorageOverrides, tenantMigrationLedger, tenantMigrationLedgerHistory;
|
|
81926
|
+
var channelTypes, agentTypes, agentSystems, agentEntityTypes, debounceMode, splitDelayMode, supersedeMode, replyFilterMode, agentSessionStrategies, ruleTypes, accessModes, settingValueTypes, apiKeyStatuses, apiKeyProfiles, eventTypes, contentTypes, chatTypes, messageSources, messageTypes, messageStatuses, deliveryStatuses, scheduledMessageDeliveryModes, scheduledMessageStatuses, jobStatuses, providerSchemas, agentProviders, agents, agentRoutes, agentSessions, apiKeys, apiKeyAuditLogs, apiKeysRelations, apiKeyAuditLogsRelations, instances, whatsappTemplates, whatsappFlowKeys, scheduledMessages, persons, platformIdentities, conversations, chats, chatParticipants, omniGroups, messages2, omniEvents, handoffLogs, closeContactOutcomes, closeContactLogs, accessRules, globalSettings, settingChangeHistory, batchJobs, syncJobTypes, syncJobs, mediaContent, chatIdMappings, pluginStorage, agentProvidersRelations, agentsRelations, instancesRelations, syncJobsRelations, personsRelations, platformIdentitiesRelations, conversationsRelations, chatsRelations, chatParticipantsRelations, messagesRelations, omniEventsRelations, accessRulesRelations, globalSettingsRelations, settingChangeHistoryRelations, batchJobsRelations, mediaContentRelations, chatIdMappingsRelations, deadLetterStatuses, deadLetterEvents, payloadStorageConfig, payloadStages, eventPayloads, webhookSignatureAlgorithms, connectorLivenessStatuses, connectorWindowSemanticsValues, connectorMutationPolicies, webhookSources, eventSchemas, conditionOperators, actionTypes, automationDebounceModes, automations2, automationLogStatuses, automationLogs, consumerOffsets, durableConsumers, automationsRelations, automationLogsRelations, triggerLogs, triggerLogsRelations, agentRoutesRelations, agentTaskStatuses, agentTasks, agentTasksRelations, turnStatuses, turnActions, turns, turnsRelations, followUpDisarmReasons, chatFollowUpState, chatFollowUpStateRelations, processedEvents, genieHosts, tenantStatuses, principalTypes, principalStatuses, tenantRoles, membershipStatuses, credentialClasses, authCredentialStatuses, platformApiKeyStatuses, tenants, principals, tenantMemberships, tenantRolePolicies, platformApiKeys, tenantKeyLineage, authCredentials, tenantAuditLogs, platformAuditLogs, platformProviderCatalog, tenantProviderConfig, platformSettings, tenantSettings, platformSettingChangeHistory, tenantSettingChangeHistory, platformPluginStorage, tenantPluginStorage, platformPayloadStorageConfig, tenantPayloadStorageOverrides, tenantMigrationLedger, tenantMigrationLedgerHistory, configAuditLogs;
|
|
81926
81927
|
var init_schema2 = __esm(() => {
|
|
81927
81928
|
init_events();
|
|
81928
81929
|
init_types4();
|
|
@@ -83995,6 +83996,28 @@ var init_schema2 = __esm(() => {
|
|
|
83995
83996
|
revisionUq: uniqueIndex("tenant_migration_ledger_history_revision_uq").on(table3.ledgerId, table3.revision),
|
|
83996
83997
|
ledgerIdx: index("tenant_migration_ledger_history_ledger_idx").on(table3.ledgerId)
|
|
83997
83998
|
}));
|
|
83999
|
+
configAuditLogs = pgTable("config_audit_logs", {
|
|
84000
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
84001
|
+
apiKeyId: varchar("api_key_id", { length: 100 }),
|
|
84002
|
+
apiKeyName: varchar("api_key_name", { length: 255 }),
|
|
84003
|
+
actor: varchar("actor", { length: 255 }),
|
|
84004
|
+
requestId: varchar("request_id", { length: 100 }),
|
|
84005
|
+
ipAddress: varchar("ip_address", { length: 64 }),
|
|
84006
|
+
userAgent: text("user_agent"),
|
|
84007
|
+
method: varchar("method", { length: 10 }).notNull(),
|
|
84008
|
+
path: varchar("path", { length: 500 }).notNull(),
|
|
84009
|
+
statusCode: integer("status_code").notNull(),
|
|
84010
|
+
action: varchar("action", { length: 100 }).notNull(),
|
|
84011
|
+
targetType: varchar("target_type", { length: 50 }).notNull(),
|
|
84012
|
+
targetId: varchar("target_id", { length: 255 }),
|
|
84013
|
+
changedFields: text("changed_fields").array().notNull().default(sql`'{}'::text[]`),
|
|
84014
|
+
changes: jsonb("changes").$type().notNull().default({}),
|
|
84015
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
84016
|
+
}, (table3) => ({
|
|
84017
|
+
targetIdx: index("config_audit_logs_target_idx").on(table3.targetType, table3.targetId),
|
|
84018
|
+
actorIdx: index("config_audit_logs_actor_idx").on(table3.actor),
|
|
84019
|
+
createdAtIdx: index("config_audit_logs_created_at_idx").on(table3.createdAt)
|
|
84020
|
+
}));
|
|
83998
84021
|
});
|
|
83999
84022
|
|
|
84000
84023
|
// ../../node_modules/.bun/drizzle-orm@0.45.2+803b5ba9c660628f/node_modules/drizzle-orm/cache/core/index.js
|
|
@@ -137266,7 +137289,7 @@ import { fileURLToPath } from "url";
|
|
|
137266
137289
|
// package.json
|
|
137267
137290
|
var package_default = {
|
|
137268
137291
|
name: "@automagik/omni",
|
|
137269
|
-
version: "2.260914.
|
|
137292
|
+
version: "2.260914.13",
|
|
137270
137293
|
repository: {
|
|
137271
137294
|
type: "git",
|
|
137272
137295
|
url: "git+https://github.com/automagik-dev/omni.git",
|
|
@@ -137508,6 +137531,22 @@ function signRequestIfHandshook(baseUrl) {
|
|
|
137508
137531
|
const bound = ctx;
|
|
137509
137532
|
return (method, path, body) => bound.signRequest(method, path, body);
|
|
137510
137533
|
}
|
|
137534
|
+
function installActorHeader() {
|
|
137535
|
+
const actor = process.env.OMNI_ACTOR?.trim();
|
|
137536
|
+
if (!actor)
|
|
137537
|
+
return;
|
|
137538
|
+
const original = globalThis.fetch;
|
|
137539
|
+
const wrapped = (input, init) => {
|
|
137540
|
+
const url = input instanceof Request ? input.url : String(input);
|
|
137541
|
+
const base = (loadConfig().apiUrl ?? DEFAULT_API_URL2).replace(/\/$/, "");
|
|
137542
|
+
if (!url.startsWith(base))
|
|
137543
|
+
return original(input, init);
|
|
137544
|
+
const headers = new Headers(init?.headers ?? (input instanceof Request ? input.headers : undefined));
|
|
137545
|
+
headers.set("x-omni-actor", actor);
|
|
137546
|
+
return original(input, { ...init, headers });
|
|
137547
|
+
};
|
|
137548
|
+
globalThis.fetch = Object.assign(wrapped, original);
|
|
137549
|
+
}
|
|
137511
137550
|
|
|
137512
137551
|
// src/commands/a2a.ts
|
|
137513
137552
|
init_output();
|
|
@@ -138615,6 +138654,50 @@ function createAgentsCommand() {
|
|
|
138615
138654
|
return agents;
|
|
138616
138655
|
}
|
|
138617
138656
|
|
|
138657
|
+
// src/commands/audit.ts
|
|
138658
|
+
init_config();
|
|
138659
|
+
init_output();
|
|
138660
|
+
async function auditFetch(path) {
|
|
138661
|
+
if (!hasAuth())
|
|
138662
|
+
exitNotAuthenticated();
|
|
138663
|
+
const config2 = loadConfig();
|
|
138664
|
+
const res = await fetch(`${config2.apiUrl ?? "http://localhost:8882"}/api/v2/audit${path}`, {
|
|
138665
|
+
headers: { "x-api-key": config2.apiKey ?? "" }
|
|
138666
|
+
});
|
|
138667
|
+
if (!res.ok)
|
|
138668
|
+
error(`Audit request failed: HTTP ${res.status} ${await res.text().catch(() => "")}`);
|
|
138669
|
+
return await res.json();
|
|
138670
|
+
}
|
|
138671
|
+
function createAuditCommand() {
|
|
138672
|
+
const audit = new Command("audit").description("Config-mutation audit log (who changed what)");
|
|
138673
|
+
audit.command("list").description("List config changes, newest first").option("--target <id>", "Filter by target id (instance, agent, provider, ...)").option("--type <type>", "Filter by target type (instance|agent|provider|route|automation|api_key|setting)").option("--actor <actor>", "Filter by X-Omni-Actor or API key name").option("--since <iso>", "Only changes at or after this timestamp").option("--limit <n>", "Max results", "50").action(async (opts) => {
|
|
138674
|
+
const params = new URLSearchParams({ limit: opts.limit });
|
|
138675
|
+
if (opts.target)
|
|
138676
|
+
params.set("target", opts.target);
|
|
138677
|
+
if (opts.type)
|
|
138678
|
+
params.set("targetType", opts.type);
|
|
138679
|
+
if (opts.actor)
|
|
138680
|
+
params.set("actor", opts.actor);
|
|
138681
|
+
if (opts.since)
|
|
138682
|
+
params.set("since", opts.since);
|
|
138683
|
+
const { items } = await auditFetch(`?${params}`);
|
|
138684
|
+
list(items.map((e10) => ({
|
|
138685
|
+
id: e10.id,
|
|
138686
|
+
time: e10.createdAt,
|
|
138687
|
+
actor: e10.actor ?? e10.apiKeyName ?? "-",
|
|
138688
|
+
action: e10.action,
|
|
138689
|
+
target: e10.targetId ?? "-",
|
|
138690
|
+
status: e10.statusCode,
|
|
138691
|
+
changed: e10.changedFields.join(", ") || "-"
|
|
138692
|
+
})), { emptyMessage: "No audit entries.", rawData: items });
|
|
138693
|
+
});
|
|
138694
|
+
audit.command("show <id>").description("Show one audit entry with before/after (secrets as fingerprints)").action(async (id) => {
|
|
138695
|
+
const { data: data2 } = await auditFetch(`/${encodeURIComponent(id)}`);
|
|
138696
|
+
data(data2);
|
|
138697
|
+
});
|
|
138698
|
+
return audit;
|
|
138699
|
+
}
|
|
138700
|
+
|
|
138618
138701
|
// src/commands/auth.ts
|
|
138619
138702
|
init_config();
|
|
138620
138703
|
|
|
@@ -153996,6 +154079,12 @@ var COMMANDS = [
|
|
|
153996
154079
|
helpGroup: "Management",
|
|
153997
154080
|
helpDescription: "Agent routing configuration"
|
|
153998
154081
|
},
|
|
154082
|
+
{
|
|
154083
|
+
create: createAuditCommand,
|
|
154084
|
+
category: "core",
|
|
154085
|
+
helpGroup: "Management",
|
|
154086
|
+
helpDescription: "Config-mutation audit log"
|
|
154087
|
+
},
|
|
153999
154088
|
{
|
|
154000
154089
|
create: createKeysCommand,
|
|
154001
154090
|
category: "core",
|
|
@@ -154303,6 +154392,7 @@ program2.configureOutput({
|
|
|
154303
154392
|
}
|
|
154304
154393
|
});
|
|
154305
154394
|
selfHealManifestPin();
|
|
154395
|
+
installActorHeader();
|
|
154306
154396
|
var argv = process.argv.slice(2);
|
|
154307
154397
|
var isRootVersionOnly = argv.length > 0 && argv.every((arg) => arg === "--version" || arg === "-V");
|
|
154308
154398
|
if (isRootVersionOnly) {
|