@automagik/omni 2.260717.2 → 2.260717.4

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.2",
125167
+ version: "2.260717.4",
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.2",
225886
+ version: "2.260717.4",
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,15 +356797,29 @@ function normalizeOverrides(overrides) {
356775
356797
  denylistPresetKey: overrides.denylistPresetKey === null ? undefined : overrides.denylistPresetKey
356776
356798
  };
356777
356799
  }
356778
- function enforceMintCeiling(c, requestedScopes) {
356779
- const callerScopes = c.get("apiKey")?.scopes ?? [];
356780
- const exceeding = requestedScopes.filter((scope) => !ApiKeyService.scopeAllows(callerScopes, scope));
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
+ }
356809
+ function enforceScopeCeiling(c, requestedScopes) {
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);
356816
+ const exceeding = requestedScopes.filter((scope) => authorizerScopeSets.some((authorizerScopes) => !ApiKeyService.scopeAllows(authorizerScopes, scope)));
356781
356817
  if (exceeding.length === 0)
356782
356818
  return null;
356783
356819
  return c.json({
356784
356820
  error: {
356785
356821
  code: "FORBIDDEN",
356786
- message: `Cannot mint a key whose scopes exceed the caller's own. Disallowed: ${exceeding.join(", ")}`
356822
+ message: `Cannot grant scopes that exceed the caller's own. Disallowed: ${exceeding.join(", ")}`
356787
356823
  }
356788
356824
  }, 403);
356789
356825
  }
@@ -356798,7 +356834,7 @@ async function handleProfileCreate(c, data, services) {
356798
356834
  overrides: normalizeOverrides(data.overrides),
356799
356835
  denylistPresetKey: data.denylistPresetKey
356800
356836
  });
356801
- const ceilingDenied = enforceMintCeiling(c, resolved.scopes);
356837
+ const ceilingDenied = enforceScopeCeiling(c, resolved.scopes);
356802
356838
  if (ceilingDenied)
356803
356839
  return ceilingDenied;
356804
356840
  const result = await services.apiKeys.create({
@@ -356833,7 +356869,7 @@ async function handleLegacyCreate(c, data, services) {
356833
356869
  if (!data.scopes || data.scopes.length === 0) {
356834
356870
  return c.json({ error: { code: "VALIDATION_ERROR", message: "scopes is required when no profile is supplied" } }, 400);
356835
356871
  }
356836
- const ceilingDenied = enforceMintCeiling(c, data.scopes);
356872
+ const ceilingDenied = enforceScopeCeiling(c, data.scopes);
356837
356873
  if (ceilingDenied)
356838
356874
  return ceilingDenied;
356839
356875
  const result = await services.apiKeys.create({
@@ -356957,6 +356993,11 @@ var init_keys = __esm(() => {
356957
356993
  const id = c.req.param("id");
356958
356994
  const data = c.req.valid("json");
356959
356995
  const services = c.get("services");
356996
+ if (data.scopes) {
356997
+ const ceilingDenied = enforceScopeCeiling(c, data.scopes);
356998
+ if (ceilingDenied)
356999
+ return ceilingDenied;
357000
+ }
356960
357001
  try {
356961
357002
  const updated = await services.apiKeys.update(id, {
356962
357003
  ...data,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/omni",
3
- "version": "2.260717.2",
3
+ "version": "2.260717.4",
4
4
  "description": "LLM-optimized CLI for Omni",
5
5
  "type": "module",
6
6
  "bin": {