@malloy-publisher/server 0.0.241 → 0.0.242

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.
Files changed (2) hide show
  1. package/dist/server.mjs +39 -8
  2. package/package.json +1 -1
package/dist/server.mjs CHANGED
@@ -269317,7 +269317,7 @@ class QueryController {
269317
269317
  constructor(environmentStore) {
269318
269318
  this.environmentStore = environmentStore;
269319
269319
  }
269320
- async getQuery(environmentName, packageName, modelPath, sourceName, queryName, query, compactJson = false, filterParams, bypassFilters, givens, metadata) {
269320
+ async getQuery(environmentName, packageName, modelPath, sourceName, queryName, query, compactJson = false, filterParams, bypassFilters, givens, metadata, bypassAuthorize) {
269321
269321
  let requestMetadata;
269322
269322
  let queryClass;
269323
269323
  try {
@@ -269357,7 +269357,7 @@ class QueryController {
269357
269357
  return null;
269358
269358
  }
269359
269359
  }
269360
- }, compactJson ? "compact" : "full"), getQueryTimeoutMs());
269360
+ }, compactJson ? "compact" : "full", bypassAuthorize), getQueryTimeoutMs());
269361
269361
  const renderLogs = import_render_validator.validateRenderTags(result);
269362
269362
  return {
269363
269363
  result: serializedResult,
@@ -277169,12 +277169,19 @@ function unwrapQuotedExpression(body) {
277169
277169
 
277170
277170
  // src/authorize_metrics.ts
277171
277171
  var guardRejectionCounter = null;
277172
+ var bypassCounter = null;
277172
277173
  function recordAuthorizeGuardRejection(field) {
277173
277174
  guardRejectionCounter ??= publisherMeter().createCounter("publisher_authorize_guard_rejected_total", {
277174
277175
  description: "Requests rejected with 400 for declaring an `#(authorize)` annotation in caller-submitted Malloy text. Label: field ('query'|'source_name'|'query_name'|'compile_source')."
277175
277176
  });
277176
277177
  guardRejectionCounter.add(1, { field });
277177
277178
  }
277179
+ function recordAuthorizeBypass(entryPoint) {
277180
+ bypassCounter ??= publisherMeter().createCounter("publisher_authorize_bypass_total", {
277181
+ description: "Gate evaluations skipped because the request carried an authorize bypass (private data-management path). Label: entry_point ('source'|'runnable'). Any nonzero value on a path that should not use the bypass is a finding — see the paired `authorize bypass` audit log line for org/package/model/source."
277182
+ });
277183
+ bypassCounter.add(1, { entry_point: entryPoint });
277184
+ }
277178
277185
 
277179
277186
  // src/service/environment.ts
277180
277187
  init_logger();
@@ -278733,7 +278740,11 @@ class Model {
278733
278740
  }
278734
278741
  return this.fileLevelAuthorize;
278735
278742
  }
278736
- async assertAuthorized(sourceName, givens) {
278743
+ async assertAuthorized(sourceName, givens, bypassAuthorize = false) {
278744
+ if (bypassAuthorize) {
278745
+ this.noteAuthorizeBypass("source", sourceName);
278746
+ return;
278747
+ }
278737
278748
  const gates = sourceName ? this.entryPointGatesBySource.get(sourceName) : undefined;
278738
278749
  if (gates) {
278739
278750
  for (const { label, exprs, selfContained, ambientPrefix } of gates) {
@@ -278743,6 +278754,15 @@ class Model {
278743
278754
  }
278744
278755
  await this.assertAuthorizedExprs(sourceName ?? "(query)", this.effectiveAuthorizeFor(sourceName), givens);
278745
278756
  }
278757
+ noteAuthorizeBypass(entryPoint, sourceName) {
278758
+ recordAuthorizeBypass(entryPoint);
278759
+ logger.info("authorize bypass", {
278760
+ entryPoint,
278761
+ sourceName: sourceName ?? "(query)",
278762
+ modelPath: this.modelPath,
278763
+ packageName: this.packageName
278764
+ });
278765
+ }
278746
278766
  async assertAuthorizedExprs(label, exprs, givens, selfContainedFirst = false, ambientPrefix = 0) {
278747
278767
  if (exprs.length === 0)
278748
278768
  return;
@@ -278765,7 +278785,11 @@ class Model {
278765
278785
  if (!passed)
278766
278786
  deny();
278767
278787
  }
278768
- async assertAuthorizedForAllSources(runnable, givens) {
278788
+ async assertAuthorizedForAllSources(runnable, givens, bypassAuthorize = false) {
278789
+ if (bypassAuthorize) {
278790
+ this.noteAuthorizeBypass("runnable", await this.resolveAuthorizeSourceFromRunnable(runnable));
278791
+ return;
278792
+ }
278769
278793
  const ownSourceName = await this.resolveAuthorizeSourceFromRunnable(runnable);
278770
278794
  await this.assertAuthorized(ownSourceName, givens);
278771
278795
  const { struct, modelDef, compositeResolvedSourceDef } = await this.resolveRunTargetStruct(runnable);
@@ -279342,7 +279366,7 @@ class Model {
279342
279366
  return { ...b, schema, refinements };
279343
279367
  }).filter((b) => b.schema.length > 0);
279344
279368
  }
279345
- async getQueryResults(sourceName, queryName, query, filterParams, bypassFilters, givens, abortSignal, queryMetadataInput, responseShape = "full") {
279369
+ async getQueryResults(sourceName, queryName, query, filterParams, bypassFilters, givens, abortSignal, queryMetadataInput, responseShape = "full", bypassAuthorize = false) {
279346
279370
  const startTime = performance.now();
279347
279371
  if (this.compilationError) {
279348
279372
  if (this.compilationError instanceof MalloyError2 || this.compilationError instanceof ModelCompilationError) {
@@ -279361,7 +279385,7 @@ class Model {
279361
279385
  const surfaceName = extractRunTargetSourceName(query);
279362
279386
  const earlySource = sourceName || (queryName ? this.queries?.find((q) => q.name === queryName)?.sourceName : undefined) || (surfaceName && !this.sources?.some((s) => s.name === surfaceName) ? this.queries?.find((q) => q.name === surfaceName)?.sourceName : undefined) || surfaceName;
279363
279387
  if (earlySource) {
279364
- await this.assertAuthorized(earlySource, givens ?? {});
279388
+ await this.assertAuthorized(earlySource, givens ?? {}, bypassAuthorize);
279365
279389
  }
279366
279390
  try {
279367
279391
  for (const [field, callerText] of [
@@ -279456,7 +279480,7 @@ run: ${sourceName ? `${quoteMalloyIdentifier(sourceName)} -> ` : ""}${quoteMallo
279456
279480
  if (boundary === "deferred") {
279457
279481
  this.assertQueryBoundaryCompiled(compiledSource, query);
279458
279482
  }
279459
- await this.assertAuthorizedForAllSources(runnable, givens ?? {});
279483
+ await this.assertAuthorizedForAllSources(runnable, givens ?? {}, bypassAuthorize);
279460
279484
  const maxRows = getMaxQueryRows();
279461
279485
  const maxBytes = getMaxResponseBytes();
279462
279486
  const buildManifest = this.resolveFreshBuildManifest();
@@ -284408,6 +284432,13 @@ class WatchModeController {
284408
284432
  init_errors();
284409
284433
  init_logger();
284410
284434
 
284435
+ // src/authorize_bypass_header.ts
284436
+ var BYPASS_AUTHORIZE_HEADER = "x-publisher-bypass-authorize";
284437
+ var readBypassAuthorize = (req) => {
284438
+ const raw = req.headers[BYPASS_AUTHORIZE_HEADER];
284439
+ return typeof raw === "string" && raw.trim().toLowerCase() === "true" ? true : undefined;
284440
+ };
284441
+
284411
284442
  // src/filter_deprecation.ts
284412
284443
  var setFilterDeprecationHeaders = (res, options) => {
284413
284444
  const hasFilterParams = options.filterParams !== undefined && options.filterParams !== null && !(typeof options.filterParams === "object" && !Array.isArray(options.filterParams) && Object.keys(options.filterParams).length === 0);
@@ -295580,7 +295611,7 @@ app.post(`${API_PREFIX2}/environments/:environmentName/packages/:packageName/mod
295580
295611
  queryMetadata: req.body?.queryMetadata,
295581
295612
  queryClass: req.body?.queryClass,
295582
295613
  versionId: req.body?.versionId
295583
- });
295614
+ }, readBypassAuthorize(req));
295584
295615
  setFilterDeprecationHeaders(res, {
295585
295616
  filterParams: req.body.filterParams ?? req.body.sourceFilters,
295586
295617
  bypassFilters: req.body.bypassFilters === true ? true : undefined
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@malloy-publisher/server",
3
3
  "description": "Malloy Publisher Server",
4
- "version": "0.0.241",
4
+ "version": "0.0.242",
5
5
  "main": "dist/server.mjs",
6
6
  "bin": {
7
7
  "malloy-publisher": "dist/server.mjs"