@automagik/omni 2.260717.3 → 2.260717.5

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/dist/index.js CHANGED
@@ -125164,7 +125164,7 @@ import { fileURLToPath } from "url";
125164
125164
  // package.json
125165
125165
  var package_default = {
125166
125166
  name: "@automagik/omni",
125167
- version: "2.260717.3",
125167
+ version: "2.260717.5",
125168
125168
  description: "LLM-optimized CLI for Omni",
125169
125169
  type: "module",
125170
125170
  bin: {
@@ -225883,7 +225883,7 @@ var init_sentry_scrub = __esm(() => {
225883
225883
  var require_package7 = __commonJS((exports, module) => {
225884
225884
  module.exports = {
225885
225885
  name: "@omni/api",
225886
- version: "2.260717.3",
225886
+ version: "2.260717.5",
225887
225887
  type: "module",
225888
225888
  exports: {
225889
225889
  ".": {
@@ -285026,11 +285026,9 @@ var init_genie_signature = __esm(() => {
285026
285026
  }
285027
285027
  }, 401);
285028
285028
  }
285029
- if (outcome.status === "verified" && outcome.hostId) {
285029
+ if (outcome.status === "verified") {
285030
285030
  c.set("signedBy", outcome.hostId);
285031
- if (outcome.hostScopes) {
285032
- c.set("signedByScopes", outcome.hostScopes);
285033
- }
285031
+ c.set("signedByScopes", outcome.hostScopes);
285034
285032
  services.genieHosts.touchLastSeen(outcome.hostId).catch((err) => {
285035
285033
  log59.warn("touchLastSeen failed (non-fatal)", { hostId: outcome.hostId, err: String(err) });
285036
285034
  });
@@ -285685,6 +285683,18 @@ var init_scopes = __esm(() => {
285685
285683
  };
285686
285684
  });
285687
285685
 
285686
+ // ../api/src/lib/signed-host-scope-context.ts
285687
+ function readSignedHostScopeContext(c) {
285688
+ const hostId = c.get("signedBy");
285689
+ if (!hostId)
285690
+ return { kind: "unsigned" };
285691
+ const scopes = c.get("signedByScopes");
285692
+ if (!Array.isArray(scopes) || !scopes.every((scope) => typeof scope === "string")) {
285693
+ return { kind: "invalid", hostId };
285694
+ }
285695
+ return { kind: "valid", hostId, scopes };
285696
+ }
285697
+
285688
285698
  // ../api/src/middleware/scope-enforcer.ts
285689
285699
  function buildSegmentRegex(patternPath) {
285690
285700
  const escaped = patternPath.split("/").map((seg) => seg.startsWith(":") ? "[^/]+" : seg.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("/");
@@ -285852,6 +285862,16 @@ function lockDenyResponse(c, lock, result) {
285852
285862
  }
285853
285863
  }, 403);
285854
285864
  }
285865
+ function invalidSignedHostScopeContextResponse(c, hostId) {
285866
+ log61.warn(`DENIED: signedBy=${hostId} route=${c.req.method.toUpperCase()} ${c.req.path} host-scopes=INVALID`);
285867
+ return c.json({
285868
+ error: {
285869
+ code: "FORBIDDEN",
285870
+ message: "Signing host scope context is missing.",
285871
+ host: hostId
285872
+ }
285873
+ }, 403);
285874
+ }
285855
285875
  var log61, OUTBOUND_SEND_PREFIXES, PATH_INSTANCE_PREFIXES, PATH_CHAT_PREFIXES, PATH_MEDIA_INSTANCE_PREFIX = "/media/", scopeEnforcerMiddleware;
285856
285876
  var init_scope_enforcer = __esm(() => {
285857
285877
  init_src();
@@ -285875,8 +285895,9 @@ var init_scope_enforcer = __esm(() => {
285875
285895
  }
285876
285896
  const method = c.req.method.toUpperCase();
285877
285897
  const path2 = c.req.path;
285878
- const signedBy = c.get("signedBy");
285879
- const signedByScopes = c.get("signedByScopes");
285898
+ const signedHost = readSignedHostScopeContext(c);
285899
+ if (signedHost.kind === "invalid")
285900
+ return invalidSignedHostScopeContextResponse(c, signedHost.hostId);
285880
285901
  const wildcard = ApiKeyService.scopeAllows(apiKey.scopes, "*");
285881
285902
  let requiredScope;
285882
285903
  if (!wildcard) {
@@ -285900,8 +285921,9 @@ var init_scope_enforcer = __esm(() => {
285900
285921
  }, 403);
285901
285922
  }
285902
285923
  }
285903
- if (signedBy && signedByScopes) {
285904
- const hostWildcard = ApiKeyService.scopeAllows(signedByScopes, "*");
285924
+ if (signedHost.kind === "valid") {
285925
+ const { hostId: signedBy, scopes: hostScopes } = signedHost;
285926
+ const hostWildcard = ApiKeyService.scopeAllows(hostScopes, "*");
285905
285927
  if (!hostWildcard) {
285906
285928
  const needed = requiredScope ?? findRequiredScope(method, path2);
285907
285929
  if (!needed) {
@@ -285913,8 +285935,8 @@ var init_scope_enforcer = __esm(() => {
285913
285935
  }
285914
285936
  }, 403);
285915
285937
  }
285916
- if (!ApiKeyService.scopeAllows(signedByScopes, needed)) {
285917
- log61.warn(`DENIED: signedBy=${signedBy} route=${method} ${path2} required=${needed} host-scopes=${signedByScopes.join(",")}`);
285938
+ if (!ApiKeyService.scopeAllows(hostScopes, needed)) {
285939
+ log61.warn(`DENIED: signedBy=${signedBy} route=${method} ${path2} required=${needed} host-scopes=${hostScopes.join(",")}`);
285918
285940
  return c.json({
285919
285941
  error: {
285920
285942
  code: "FORBIDDEN",
@@ -356775,10 +356797,22 @@ function normalizeOverrides(overrides) {
356775
356797
  denylistPresetKey: overrides.denylistPresetKey === null ? undefined : overrides.denylistPresetKey
356776
356798
  };
356777
356799
  }
356800
+ function invalidSignedHostScopeContextResponse2(c, hostId) {
356801
+ return c.json({
356802
+ error: {
356803
+ code: "FORBIDDEN",
356804
+ message: "Signing host scope context is missing.",
356805
+ host: hostId
356806
+ }
356807
+ }, 403);
356808
+ }
356778
356809
  function enforceScopeCeiling(c, requestedScopes) {
356779
- const callerScopes = c.get("apiKey")?.scopes ?? [];
356780
- const signedByScopes = c.get("signedBy") ? c.get("signedByScopes") : undefined;
356781
- const authorizerScopeSets = signedByScopes ? [callerScopes, signedByScopes] : [callerScopes];
356810
+ const authorizerScopeSets = [c.get("apiKey")?.scopes ?? []];
356811
+ const signedHost = readSignedHostScopeContext(c);
356812
+ if (signedHost.kind === "invalid")
356813
+ return invalidSignedHostScopeContextResponse2(c, signedHost.hostId);
356814
+ if (signedHost.kind === "valid")
356815
+ authorizerScopeSets.push(signedHost.scopes);
356782
356816
  const exceeding = requestedScopes.filter((scope) => authorizerScopeSets.some((authorizerScopes) => !ApiKeyService.scopeAllows(authorizerScopes, scope)));
356783
356817
  if (exceeding.length === 0)
356784
356818
  return null;
@@ -356789,6 +356823,20 @@ function enforceScopeCeiling(c, requestedScopes) {
356789
356823
  }
356790
356824
  }, 403);
356791
356825
  }
356826
+ function enforceInstanceCeiling(c, requestedInstanceIds) {
356827
+ const apiKey = c.get("apiKey");
356828
+ if (apiKey?.instanceIds === null)
356829
+ return null;
356830
+ const exceedsCaller = !apiKey || !Array.isArray(apiKey.instanceIds) || requestedInstanceIds === null || requestedInstanceIds.some((instanceId) => !apiKey.instanceIds?.includes(instanceId));
356831
+ if (!exceedsCaller)
356832
+ return null;
356833
+ return c.json({
356834
+ error: {
356835
+ code: "FORBIDDEN",
356836
+ message: "Cannot grant instance access that exceeds the caller's own."
356837
+ }
356838
+ }, 403);
356839
+ }
356792
356840
  async function handleProfileCreate(c, data, services) {
356793
356841
  try {
356794
356842
  const resolved = resolveProfile({
@@ -356803,6 +356851,9 @@ async function handleProfileCreate(c, data, services) {
356803
356851
  const ceilingDenied = enforceScopeCeiling(c, resolved.scopes);
356804
356852
  if (ceilingDenied)
356805
356853
  return ceilingDenied;
356854
+ const instanceCeilingDenied = enforceInstanceCeiling(c, data.instanceIds ?? null);
356855
+ if (instanceCeilingDenied)
356856
+ return instanceCeilingDenied;
356806
356857
  const result = await services.apiKeys.create({
356807
356858
  name: data.name,
356808
356859
  description: data.description,
@@ -356838,6 +356889,9 @@ async function handleLegacyCreate(c, data, services) {
356838
356889
  const ceilingDenied = enforceScopeCeiling(c, data.scopes);
356839
356890
  if (ceilingDenied)
356840
356891
  return ceilingDenied;
356892
+ const instanceCeilingDenied = enforceInstanceCeiling(c, data.instanceIds ?? null);
356893
+ if (instanceCeilingDenied)
356894
+ return instanceCeilingDenied;
356841
356895
  const result = await services.apiKeys.create({
356842
356896
  name: data.name,
356843
356897
  description: data.description,
@@ -356964,6 +357018,11 @@ var init_keys = __esm(() => {
356964
357018
  if (ceilingDenied)
356965
357019
  return ceilingDenied;
356966
357020
  }
357021
+ if (data.instanceIds !== undefined) {
357022
+ const instanceCeilingDenied = enforceInstanceCeiling(c, data.instanceIds);
357023
+ if (instanceCeilingDenied)
357024
+ return instanceCeilingDenied;
357025
+ }
356967
357026
  try {
356968
357027
  const updated = await services.apiKeys.update(id, {
356969
357028
  ...data,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/omni",
3
- "version": "2.260717.3",
3
+ "version": "2.260717.5",
4
4
  "description": "LLM-optimized CLI for Omni",
5
5
  "type": "module",
6
6
  "bin": {