{"version":3,"file":"validate-WjV-0T7w.cjs","names":["ALLOWED_ROOTS"],"sources":["../src/core/rbac/rbac.ts","../src/core/validate/validate.libs.ts","../src/core/validate/validate.ts"],"sourcesContent":["import type { AccessControl } from '../types'\n/**\n * Maximum depth of the inheritance chain walked by {@link collectPermissions}\n * and {@link resolveEffectiveRoles}. Cycles are cut by the `visited` set, but\n * a linear N-deep chain (or a malformed import) would still blow the stack  -\n * the bound makes traversal cost predictable.\n *\n * Roles past this depth are silently dropped from the resolved set. Override\n * is intentionally not exposed: a single hard limit keeps every adapter and\n * validator in agreement. Bump here if your role graph legitimately exceeds 32.\n */\nexport const MAX_INHERITANCE_DEPTH = 32\n\n/**\n * Flatten role inheritance, returning permissions in parent-first order.\n * Cycles short-circuit via `visited`; depth is bounded by {@link MAX_INHERITANCE_DEPTH}.\n */\nfunction collectPermissions(\n  roleId: string,\n  rolesMap: Map<string, AccessControl.IRole>,\n  visited = new Set<string>(),\n  depth = 0,\n): AccessControl.IRole['permissions'][number][] {\n  if (depth > MAX_INHERITANCE_DEPTH) return []\n  if (visited.has(roleId)) return []\n  visited.add(roleId)\n\n  const role = rolesMap.get(roleId)\n  if (!role) return []\n\n  const inherited = (role.inherits ?? []).flatMap((parent) => collectPermissions(parent, rolesMap, visited, depth + 1))\n\n  return [...inherited, ...role.permissions]\n}\n\n/**\n * Convert RBAC role definitions into an ABAC policy.\n *\n * Each permission becomes a rule with a condition that checks\n * `subject.roles` contains the role ID. This lets RBAC and ABAC\n * coexist in the same evaluation pipeline.\n *\n * @param roles - Every role definition (resolved separately of subject assignment).\n * @returns A synthetic {@link AccessControl.IPolicy} with one allow rule per permission.\n */\nexport function rolesToPolicy(roles: AccessControl.IRole[]): AccessControl.IPolicy {\n  const rolesMap = new Map(roles.map((r) => [r.id, r]))\n  const rules: AccessControl.IRule[] = []\n  // Monotonic counter for rule ids: stable + unique regardless of role / action\n  // / resource names. Previous `rbac.${role}.${action}.${resource}.${i}` format\n  // produced ambiguous ids when any segment contained a `.`.\n  let ruleSeq = 0\n\n  for (const role of roles) {\n    const allPerms = collectPermissions(role.id, rolesMap)\n\n    for (const [_i, perm] of allPerms.entries()) {\n      const baseConditions: (AccessControl.ICondition | AccessControl.IConditionGroup)[] = [\n        { field: 'subject.roles', operator: 'contains' as const, value: role.id },\n      ]\n\n      // Add scope condition if permission or role has a scope\n      const effectiveScope = perm.scope ?? role.scope\n      if (effectiveScope && effectiveScope !== '*') {\n        baseConditions.push({ field: 'scope', operator: 'eq' as const, value: effectiveScope })\n      }\n\n      const conditions = perm.conditions\n        ? {\n            all: [\n              ...baseConditions,\n              ...('all' in perm.conditions\n                ? perm.conditions.all\n                : 'any' in perm.conditions\n                  ? [perm.conditions]\n                  : 'none' in perm.conditions\n                    ? [perm.conditions]\n                    : []),\n            ],\n          }\n        : { all: baseConditions }\n\n      rules.push({\n        id: `__rbac__#${ruleSeq++}`,\n        effect: 'allow',\n        description: `${role.name}: ${perm.action} on ${perm.resource}`,\n        priority: 10,\n        actions: [perm.action],\n        resources: [perm.resource],\n        conditions,\n      })\n    }\n  }\n\n  return {\n    id: '__rbac__',\n    name: 'RBAC Policies',\n    description: 'Auto-generated from role definitions',\n    algorithm: 'allow-overrides',\n    rules,\n  }\n}\n\n/**\n * Walks `inherits` chains from each assigned role and returns the closed set\n * of effective role IDs. Cycles are cut by the `effective` set; depth is\n * bounded by {@link MAX_INHERITANCE_DEPTH} so a runaway chain can't recurse\n * past the JS stack.\n *\n * @param assignedRoles Role IDs directly assigned to the subject.\n * @param allRoles      Every role definition, used to resolve `inherits`.\n * @returns Closed set of effective role IDs (assigned + inherited).\n */\nexport function resolveEffectiveRoles(assignedRoles: string[], allRoles: AccessControl.IRole[]): string[] {\n  const rolesMap = new Map(allRoles.map((r) => [r.id, r]))\n  const effective = new Set<string>()\n\n  function walk(roleId: string, depth: number) {\n    if (depth > MAX_INHERITANCE_DEPTH) return\n    if (effective.has(roleId)) return\n    effective.add(roleId)\n    const role = rolesMap.get(roleId)\n    for (const parent of role?.inherits ?? []) walk(parent, depth + 1)\n  }\n\n  for (const r of assignedRoles) walk(r, 0)\n  return [...effective]\n}\n","import type { IamEngine } from '..'\nimport { MAX_CONDITION_DEPTH, MAX_REGEX_LENGTH } from '../conditions/conditions.libs'\nimport { ALLOWED_ROOTS } from '../resolve/resolve'\nimport type { IamValidate } from './validate.types'\n\nfunction isPlainObjectLike(v: unknown): v is Record<string, unknown> {\n  return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n\n/**\n * Maximum number of unbounded quantifiers (`+`, `*`, `{n,}`) allowed in a\n * single `matches` pattern. Beyond this the surface area for catastrophic\n * backtracking gets impractical to reason about, so we refuse outright.\n */\nexport const MAX_UNBOUNDED_QUANTIFIERS = 4\n\n/**\n * Largest finite upper bound permitted in a `{n,m}` quantifier. The matcher\n * walks `m` iterations worst-case, so anything above ~1000 starts to look\n * like a DoS vector even though it isn't technically unbounded.\n */\nexport const MAX_BOUNDED_QUANTIFIER = 1_000\n\n/**\n * Cheap heuristic for catastrophic-backtracking regex (nested quantifiers, large bounds, backref-quantifier, etc).\n *\n * @param pattern - Raw regex source.\n * @returns `{ safe: true }` when the pattern looks benign, otherwise `{ safe: false, reason }`.\n */\nexport function detectCatastrophicRegex(pattern: string): { safe: boolean; reason?: string } {\n  if (typeof pattern !== 'string') return { safe: false, reason: 'pattern must be a string' }\n  if (pattern.length > MAX_REGEX_LENGTH) {\n    return {\n      safe: false,\n      reason: `pattern length ${pattern.length} exceeds MAX_REGEX_LENGTH (${MAX_REGEX_LENGTH})`,\n    }\n  }\n\n  // Backreference followed by a quantifier - run before the nested-quantifier\n  // scan so the more specific reason wins for shapes like `(\\w+)\\1+`. Numeric\n  // (`\\1+`, `\\3*`, `\\2{1,5}`) and named (`\\k<name>+`) forms can drive\n  // exponential backtracking when the captured group matches a variable-length\n  // pattern. Flag any backref+quantifier pair.\n  if (/\\\\[1-9]\\d*\\s*[+*?{]/.test(pattern) || /\\\\k<[^>]+>\\s*[+*?{]/.test(pattern)) {\n    return { safe: false, reason: 'backref-quantifier' }\n  }\n\n  // Lookaround group whose body contains a quantifier. Run before the\n  // nested-quantifier scan so `(?=(a+)+)` is reported with the more specific\n  // reason. JS supports `(?=...)`, `(?!...)`, `(?<=...)`, `(?<!...)`. Walk\n  // paren depth and inspect the body of any lookaround for `+`, `*`, or\n  // `{...}`.\n  for (let i = 0; i < pattern.length; i++) {\n    const ch = pattern[i]\n    if (ch === '\\\\') {\n      i++\n      continue\n    }\n    if (ch !== '(') continue\n    const tail3 = pattern.slice(i, i + 3)\n    const tail4 = pattern.slice(i, i + 4)\n    const isLookahead = tail3 === '(?=' || tail3 === '(?!'\n    const isLookbehind = tail4 === '(?<=' || tail4 === '(?<!'\n    if (!isLookahead && !isLookbehind) continue\n    const bodyStart = i + (isLookahead ? 3 : 4)\n    let depth = 1\n    let j = bodyStart\n    while (j < pattern.length && depth > 0) {\n      const cj = pattern[j]\n      if (cj === '\\\\') {\n        j += 2\n        continue\n      }\n      if (cj === '(') depth++\n      else if (cj === ')') depth--\n      if (depth === 0) break\n      j++\n    }\n    if (depth !== 0) continue\n    const body = pattern.slice(bodyStart, j)\n    const bodyStripped = body.replace(/\\\\./g, '')\n    if (/[+*]/.test(bodyStripped) || /\\{\\d+,?\\d*\\}/.test(bodyStripped)) {\n      return { safe: false, reason: 'lookaround-with-quantifier' }\n    }\n    i = j\n  }\n\n  // Bounded `{n,m}` with a very large upper bound, or `{n,}` with a very\n  // large lower bound. Lone repetitions like `a{5}` are fine; only the\n  // comma-form is a range.\n  {\n    const re = /(?<!\\\\)\\{(\\d+)(?:,(\\d*))?\\}/g\n    let m: RegExpExecArray | null\n    // biome-ignore lint/suspicious/noAssignInExpressions: classic regex iteration\n    while ((m = re.exec(pattern)) !== null) {\n      const low = Number(m[1])\n      const upperStr = m[2]\n      if (upperStr === undefined) continue // `{n}` exact count - not a range.\n      if (upperStr === '') {\n        if (low > MAX_BOUNDED_QUANTIFIER) {\n          return { safe: false, reason: 'bounded-large-quantifier' }\n        }\n        continue\n      }\n      const high = Number(upperStr)\n      if (Number.isFinite(high) && high > MAX_BOUNDED_QUANTIFIER) {\n        return { safe: false, reason: 'bounded-large-quantifier' }\n      }\n    }\n  }\n\n  // Nested quantifiers: a group whose closing `)` is immediately followed by\n  // `+`, `*`, or `{n,}` AND whose body itself contains an unbounded quantifier.\n  // We walk parens with a depth counter so nested groups are inspected too.\n  const stack: number[] = []\n  for (let i = 0; i < pattern.length; i++) {\n    const ch = pattern[i]\n    if (ch === '\\\\') {\n      i++\n      continue\n    }\n    if (ch === '(') {\n      stack.push(i)\n      continue\n    }\n    if (ch === ')') {\n      const openIdx = stack.pop()\n      if (openIdx === undefined) continue\n      const next = pattern[i + 1]\n      const isUnboundedQuant = next === '+' || next === '*' || (next === '{' && /^\\{\\d+,\\}?/.test(pattern.slice(i + 1)))\n      if (!isUnboundedQuant) continue\n      const body = pattern.slice(openIdx + 1, i)\n      // Strip escapes from body before scanning so `\\+` doesn't trigger.\n      const bodyStripped = body.replace(/\\\\./g, '')\n      if (/[+*]/.test(bodyStripped) || /\\{\\d+,\\d*\\}/.test(bodyStripped)) {\n        return { safe: false, reason: 'nested quantifier (e.g. `(a+)+`) - catastrophic backtracking risk' }\n      }\n      if (bodyStripped.includes('|')) {\n        return { safe: false, reason: 'alternation inside a quantified group - catastrophic backtracking risk' }\n      }\n    }\n  }\n\n  // Count unbounded quantifiers outside of escapes. `+`, `*`, and `{n,}`\n  // each count once.\n  let unbounded = 0\n  for (let i = 0; i < pattern.length; i++) {\n    const ch = pattern[i]\n    if (ch === '\\\\') {\n      i++\n      continue\n    }\n    if (ch === '+' || ch === '*') {\n      unbounded++\n      continue\n    }\n    if (ch === '{') {\n      // `{n,}` or `{n,m}` - only `{n,}` (no upper bound) is unbounded.\n      const close = pattern.indexOf('}', i)\n      if (close === -1) continue\n      const inner = pattern.slice(i + 1, close)\n      if (/^\\d+,\\s*$/.test(inner)) unbounded++\n      i = close\n    }\n  }\n  if (unbounded > MAX_UNBOUNDED_QUANTIFIERS) {\n    return {\n      safe: false,\n      reason: `${unbounded} unbounded quantifiers exceed limit of ${MAX_UNBOUNDED_QUANTIFIERS}`,\n    }\n  }\n\n  return { safe: true }\n}\n\n/**\n * Field paths longer than this are refused. The runtime DotPath resolver\n * splits on dots, so an enormous field string would cost O(length) work\n * per evaluation with no upside.\n */\nexport const MAX_FIELD_LENGTH = 256\n\n/** Max allowed length for a string `value` on a condition. */\nexport const MAX_CONDITION_VALUE_LENGTH = 1024\n/** Valid combining algorithm names. */\nexport const VALID_ALGORITHMS = new Set(['deny-overrides', 'allow-overrides', 'first-match', 'highest-priority'])\n\n/** Valid rule effect values. */\nexport const VALID_EFFECTS = new Set(['allow', 'deny'])\n\n/**\n * IamValidate-time policy size caps.\n *\n * `indexPolicy()` builds an `actions x resources` cartesian per rule, so an\n * unbounded policy can stall the event loop. Limits also cap memory growth\n * in {@link IamEngine}'s LRU caches.\n */\nexport const POLICY_LIMITS = {\n  rulesPerPolicy: 1_000,\n  actionsPerRule: 100,\n  resourcesPerRule: 100,\n  /** Worst-case cartesian product per rule. */\n  cartesianPerRule: 1_000,\n} as const\n\n/** Whole-path shorthands accepted alongside the dotted roots. */\nconst RESOLVABLE_SHORTHANDS = new Set(['action', 'scope'])\n\n/**\n * True when `path` would resolve to a real attribute at evaluation time.\n * Shares {@link ALLOWED_ROOTS} with the resolver so the two stay in lock-step.\n *\n * @param path - Dot-path string to check.\n * @returns `true` when the path's root is a known resolvable root.\n */\nexport function isResolvablePath(path: string): boolean {\n  if (RESOLVABLE_SHORTHANDS.has(path)) return true\n  const root = path.split('.', 1)[0]\n  return !!root && ALLOWED_ROOTS.has(root)\n}\n\n/** Set of valid condition operator names supported by the condition evaluator. */\nexport const VALID_OPERATORS = new Set([\n  'eq',\n  'neq',\n  'gt',\n  'gte',\n  'lt',\n  'lte',\n  'in',\n  'nin',\n  'contains',\n  'not_contains',\n  'starts_with',\n  'ends_with',\n  'matches',\n  'exists',\n  'not_exists',\n  'subset_of',\n  'superset_of',\n])\n\n/**\n * IamValidate one condition item (leaf or group); groups delegate to {@link validateConditionGroup}.\n *\n * @param input  - The condition item to validate.\n * @param path   - Dot-path prefix used in reported issues.\n * @param issues - Array to push validation issues into.\n * @param depth  - Current nesting depth (defaults to `0`; bounded by `MAX_CONDITION_DEPTH`).\n */\nexport function validateConditionItem(input: unknown, path: string, issues: IamValidate.IIssue[], depth = 0): void {\n  if (!isPlainObjectLike(input)) {\n    issues.push({\n      type: 'error',\n      code: 'INVALID_CONDITION',\n      message: 'Condition must be an object',\n      path,\n    })\n    return\n  }\n\n  const obj = input\n\n  if ('field' in obj) {\n    if (typeof obj.field !== 'string' || !obj.field) {\n      issues.push({\n        type: 'error',\n        code: 'MISSING_FIELD',\n        message: 'Condition must have a non-empty string \"field\"',\n        path: `${path}.field`,\n      })\n    } else if (obj.field.length > MAX_FIELD_LENGTH) {\n      issues.push({\n        type: 'error',\n        code: 'LIMIT_EXCEEDED',\n        message: `Condition field is ${obj.field.length} chars; limit is ${MAX_FIELD_LENGTH}`,\n        path: `${path}.field`,\n      })\n    } else if (!isResolvablePath(obj.field)) {\n      issues.push({\n        type: 'warning',\n        code: 'UNRESOLVABLE_FIELD',\n        message: `Condition field \"${obj.field}\" has no resolvable root (expected subject/resource/environment, or shorthand action/scope)`,\n        path: `${path}.field`,\n      })\n    }\n    if (typeof obj.operator !== 'string' || !VALID_OPERATORS.has(obj.operator)) {\n      issues.push({\n        type: 'error',\n        code: 'INVALID_OPERATOR',\n        message: `Invalid operator \"${String(obj.operator)}\"`,\n        path: `${path}.operator`,\n      })\n    }\n    if (typeof obj.value === 'string' && obj.value.length > MAX_CONDITION_VALUE_LENGTH) {\n      issues.push({\n        type: 'error',\n        code: 'LIMIT_EXCEEDED',\n        message: `Condition value is ${obj.value.length} chars; limit is ${MAX_CONDITION_VALUE_LENGTH}`,\n        path: `${path}.value`,\n      })\n    } else if (Array.isArray(obj.value)) {\n      for (const [i, entry] of obj.value.entries()) {\n        if (typeof entry === 'string' && entry.length > MAX_CONDITION_VALUE_LENGTH) {\n          issues.push({\n            type: 'error',\n            code: 'LIMIT_EXCEEDED',\n            message: `Condition value[${i}] is ${entry.length} chars; limit is ${MAX_CONDITION_VALUE_LENGTH}`,\n            path: `${path}.value[${i}]`,\n          })\n          break\n        }\n      }\n    }\n    if (typeof obj.value === 'string' && obj.value.startsWith('$') && !isResolvablePath(obj.value.slice(1))) {\n      issues.push({\n        type: 'warning',\n        code: 'UNRESOLVABLE_VALUE',\n        message: `Condition value \"${obj.value}\" references an unresolvable path`,\n        path: `${path}.value`,\n      })\n    }\n    // `matches` is the only operator that compiles its value into a regex.\n    // Refuse catastrophic patterns at validate-time so they never reach the\n    // policy store. Non-string / $-resolved values are caught elsewhere.\n    if (obj.operator === 'matches' && typeof obj.value === 'string' && !obj.value.startsWith('$')) {\n      const result = detectCatastrophicRegex(obj.value)\n      if (!result.safe) {\n        issues.push({\n          type: 'error',\n          code: 'ERR_REGEX_CATASTROPHIC',\n          message: `Condition \"matches\" pattern rejected: ${result.reason}`,\n          path: `${path}.value`,\n        })\n      }\n    }\n  } else {\n    validateConditionGroup(input, path, issues, depth)\n  }\n}\n\n/**\n * IamValidate a condition group `{ all | any | none: ConditionItem[] }`; depth-bounded.\n *\n * @param input  - The condition group to validate.\n * @param path   - Dot-path prefix used in reported issues.\n * @param issues - Array to push validation issues into.\n * @param depth  - Current nesting depth (defaults to `0`; bounded by `MAX_CONDITION_DEPTH`).\n */\nexport function validateConditionGroup(input: unknown, path: string, issues: IamValidate.IIssue[], depth = 0): void {\n  if (depth > MAX_CONDITION_DEPTH) {\n    issues.push({\n      type: 'error',\n      code: 'LIMIT_EXCEEDED',\n      message: `Condition nesting exceeds MAX_CONDITION_DEPTH (${MAX_CONDITION_DEPTH})`,\n      path,\n    })\n    return\n  }\n  if (typeof input !== 'object' || input === null) {\n    issues.push({\n      type: 'error',\n      code: 'INVALID_CONDITION',\n      message: 'Condition group must be an object',\n      path,\n    })\n    return\n  }\n\n  const groupKey = (['all', 'any', 'none'] as const).find((k) => k in input)\n\n  if (!groupKey) {\n    issues.push({\n      type: 'error',\n      code: 'INVALID_CONDITION',\n      message: 'Condition group must have \"all\", \"any\", or \"none\" key',\n      path,\n    })\n    return\n  }\n\n  const items = Reflect.get(input, groupKey)\n  if (!Array.isArray(items)) {\n    issues.push({\n      type: 'error',\n      code: 'INVALID_CONDITION',\n      message: `\"${groupKey}\" must be an array`,\n      path: `${path}.${groupKey}`,\n    })\n    return\n  }\n\n  for (const [i, item] of items.entries()) {\n    validateConditionItem(item, `${path}.${groupKey}[${i}]`, issues, depth + 1)\n  }\n}\n\n/**\n * IamValidate a Rule's shape (id, effect, priority, actions, resources, optional conditions).\n *\n * @param input  - The rule object to validate.\n * @param path   - Dot-path prefix used in reported issues.\n * @param issues - Array to push validation issues into.\n */\nexport function validateRuleShape(input: unknown, path: string, issues: IamValidate.IIssue[]): void {\n  if (!isPlainObjectLike(input)) {\n    issues.push({ type: 'error', code: 'INVALID_RULE', message: 'Rule must be an object', path })\n    return\n  }\n\n  const rule = input\n\n  if (typeof rule.id !== 'string' || !rule.id) {\n    issues.push({\n      type: 'error',\n      code: 'MISSING_FIELD',\n      message: 'Rule must have a non-empty string \"id\"',\n      path: `${path}.id`,\n    })\n  }\n\n  if (typeof rule.effect !== 'string' || !VALID_EFFECTS.has(rule.effect)) {\n    issues.push({\n      type: 'error',\n      code: 'INVALID_EFFECT',\n      message: `Invalid effect \"${String(rule.effect)}\". Must be \"allow\" or \"deny\"`,\n      path: `${path}.effect`,\n    })\n  }\n\n  if (typeof rule.priority !== 'number' || !Number.isFinite(rule.priority)) {\n    issues.push({\n      type: 'error',\n      code: 'INVALID_TYPE',\n      message: 'Rule \"priority\" must be a finite number (NaN/Infinity break highest-priority ranking)',\n      path: `${path}.priority`,\n    })\n  }\n\n  if (!Array.isArray(rule.actions) || rule.actions.length === 0) {\n    issues.push({\n      type: 'error',\n      code: 'MISSING_FIELD',\n      message: 'Rule must have a non-empty \"actions\" array',\n      path: `${path}.actions`,\n    })\n  } else {\n    if (rule.actions.length > POLICY_LIMITS.actionsPerRule) {\n      issues.push({\n        type: 'error',\n        code: 'LIMIT_EXCEEDED',\n        message: `Rule has ${rule.actions.length} actions; limit is ${POLICY_LIMITS.actionsPerRule}`,\n        path: `${path}.actions`,\n      })\n    }\n    for (const [i, action] of rule.actions.entries()) {\n      if (typeof action !== 'string') {\n        issues.push({\n          type: 'error',\n          code: 'INVALID_TYPE',\n          message: 'Action must be a string',\n          path: `${path}.actions[${i}]`,\n        })\n      }\n    }\n  }\n\n  if (!Array.isArray(rule.resources) || rule.resources.length === 0) {\n    issues.push({\n      type: 'error',\n      code: 'MISSING_FIELD',\n      message: 'Rule must have a non-empty \"resources\" array',\n      path: `${path}.resources`,\n    })\n  } else {\n    if (rule.resources.length > POLICY_LIMITS.resourcesPerRule) {\n      issues.push({\n        type: 'error',\n        code: 'LIMIT_EXCEEDED',\n        message: `Rule has ${rule.resources.length} resources; limit is ${POLICY_LIMITS.resourcesPerRule}`,\n        path: `${path}.resources`,\n      })\n    }\n    for (const [i, resource] of rule.resources.entries()) {\n      if (typeof resource !== 'string') {\n        issues.push({\n          type: 'error',\n          code: 'INVALID_TYPE',\n          message: 'Resource must be a string',\n          path: `${path}.resources[${i}]`,\n        })\n      }\n    }\n  }\n\n  // Warn on unconditional allow * * (super-admin vs. mistake ambiguity).\n  if (rule.effect === 'allow' && Array.isArray(rule.actions) && Array.isArray(rule.resources)) {\n    const allActions = rule.actions.length === 1 && rule.actions[0] === '*'\n    const allResources = rule.resources.length === 1 && rule.resources[0] === '*'\n    const conditionArrLen = (cond: unknown, key: string): number => {\n      if (cond === null || typeof cond !== 'object') return 0\n      const arr = Reflect.get(cond, key)\n      return Array.isArray(arr) ? arr.length : 0\n    }\n    const cond = rule.conditions\n    const hasConditions =\n      conditionArrLen(cond, 'all') > 0 || conditionArrLen(cond, 'any') > 0 || conditionArrLen(cond, 'none') > 0\n    if (allActions && allResources && !hasConditions) {\n      issues.push({\n        type: 'warning',\n        code: 'BROAD_ALLOW',\n        message:\n          'Rule allows every action on every resource with no conditions. This is the broadest possible grant - confirm it is intentional.',\n        path,\n      })\n    }\n  }\n\n  // Indexer cost is actions x resources per rule. Bound the cartesian even when\n  // each list passes its own cap, so a 99x99 rule doesn't slip through.\n  if (Array.isArray(rule.actions) && Array.isArray(rule.resources)) {\n    const cartesian = rule.actions.length * rule.resources.length\n    if (cartesian > POLICY_LIMITS.cartesianPerRule) {\n      issues.push({\n        type: 'error',\n        code: 'LIMIT_EXCEEDED',\n        message: `Rule actionxresource cartesian is ${cartesian}; limit is ${POLICY_LIMITS.cartesianPerRule}`,\n        path,\n      })\n    }\n  }\n\n  if (rule.conditions !== undefined) {\n    validateConditionGroup(rule.conditions, `${path}.conditions`, issues)\n  }\n}\n","import { MAX_INHERITANCE_DEPTH } from '../rbac'\nimport type { AccessControl } from '../types'\nimport { POLICY_LIMITS, VALID_ALGORITHMS, validateRuleShape } from './validate.libs'\nimport type { IamValidate } from './validate.types'\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n  return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n/**\n * IamValidate role defs: duplicate ids, dangling/circular inherits, empty roles.\n *\n * @param roles - The role definitions to validate.\n * @returns A {@link IamValidate.IResult} listing any issues found.\n */\nexport function validateRoles(roles: readonly AccessControl.IRole[]): IamValidate.IResult {\n  const issues: IamValidate.IIssue[] = []\n  const roleIds = new Set<string>()\n\n  for (const role of roles) {\n    if (roleIds.has(role.id)) {\n      issues.push({\n        type: 'error',\n        code: 'DUPLICATE_ROLE_ID',\n        message: `Duplicate role ID \"${role.id}\"`,\n        roleId: role.id,\n      })\n    }\n    roleIds.add(role.id)\n  }\n\n  for (const role of roles) {\n    for (const parentId of role.inherits ?? []) {\n      if (!roleIds.has(parentId)) {\n        issues.push({\n          type: 'error',\n          code: 'DANGLING_INHERIT',\n          message: `Role \"${role.id}\" inherits from \"${parentId}\" which does not exist`,\n          roleId: role.id,\n        })\n      }\n    }\n  }\n\n  // Cycles are runtime-safe (handled by visited-set in inheritance walk), so emit as warnings.\n  const rolesMap = new Map(roles.map((r) => [r.id, r]))\n\n  for (const role of roles) {\n    if (!role.inherits?.length) continue\n\n    const visited = new Set<string>()\n    const stack = [role.id]\n\n    while (stack.length > 0) {\n      const current = stack.pop()\n      if (current === undefined) break\n      if (visited.has(current)) {\n        issues.push({\n          type: 'warning',\n          code: 'CIRCULAR_INHERIT',\n          message: `Circular inheritance detected involving role \"${role.id}\" (cycle includes \"${current}\")`,\n          roleId: role.id,\n        })\n        break\n      }\n      visited.add(current)\n\n      const r = rolesMap.get(current)\n      if (r?.inherits) {\n        for (const parentId of r.inherits) {\n          if (roleIds.has(parentId)) stack.push(parentId)\n        }\n      }\n    }\n  }\n\n  for (const role of roles) {\n    if (role.permissions.length === 0 && (!role.inherits || role.inherits.length === 0)) {\n      issues.push({\n        type: 'warning',\n        code: 'EMPTY_ROLE',\n        message: `Role \"${role.id}\" has no permissions and no inheritance`,\n        roleId: role.id,\n      })\n    }\n  }\n\n  // Depth bound: chains deeper than MAX_INHERITANCE_DEPTH silently truncate at\n  // runtime, dropping permissions invisibly. Surface as error so the operator\n  // catches it before deploy instead of debugging missing permissions later.\n  for (const role of roles) {\n    const depth = longestInheritanceDepth(role.id, rolesMap)\n    if (depth > MAX_INHERITANCE_DEPTH) {\n      issues.push({\n        type: 'error',\n        code: 'INHERITANCE_TOO_DEEP',\n        message: `Role \"${role.id}\" has an inheritance chain ${depth} deep; the runtime caps at ${MAX_INHERITANCE_DEPTH} and silently drops anything past it`,\n        roleId: role.id,\n      })\n    }\n  }\n\n  return {\n    valid: issues.every((i) => i.type !== 'error'),\n    issues,\n  }\n}\n\n/** Longest path from `roleId` up through `inherits`; cycles cut by `seen`, depth capped at `MAX_INHERITANCE_DEPTH + 1`. */\nfunction longestInheritanceDepth(roleId: string, rolesMap: Map<string, AccessControl.IRole>): number {\n  const seen = new Set<string>()\n  function walk(id: string, depth: number): number {\n    if (seen.has(id)) return depth\n    if (depth > MAX_INHERITANCE_DEPTH + 1) return depth\n    const role = rolesMap.get(id)\n    if (!role?.inherits?.length) return depth\n    seen.add(id)\n    let max = depth\n    for (const parent of role.inherits) {\n      const d = walk(parent, depth + 1)\n      if (d > max) max = d\n    }\n    seen.delete(id)\n    return max\n  }\n  return walk(roleId, 0)\n}\n\n/**\n * Deep-validate an untrusted policy (id, name, algorithm, rules, conditions).\n *\n * @param input - The candidate policy object (typically parsed JSON or an admin form payload).\n * @returns A {@link IamValidate.IResult} with `valid: false` when any error issue was emitted.\n */\nexport function validatePolicy(input: unknown): IamValidate.IResult {\n  const issues: IamValidate.IIssue[] = []\n\n  if (!isPlainObject(input)) {\n    issues.push({ type: 'error', code: 'INVALID_TYPE', message: 'Policy must be a non-null object', path: '' })\n    return { valid: false, issues }\n  }\n\n  const p = input\n\n  if (typeof p.id !== 'string' || !p.id) {\n    issues.push({\n      type: 'error',\n      code: 'MISSING_FIELD',\n      message: 'Policy must have a non-empty string \"id\"',\n      path: 'id',\n    })\n  }\n\n  if (typeof p.name !== 'string' || !p.name) {\n    issues.push({\n      type: 'error',\n      code: 'MISSING_FIELD',\n      message: 'Policy must have a non-empty string \"name\"',\n      path: 'name',\n    })\n  }\n\n  if (typeof p.algorithm !== 'string' || !VALID_ALGORITHMS.has(p.algorithm)) {\n    issues.push({\n      type: 'error',\n      code: 'INVALID_ALGORITHM',\n      message: `Invalid algorithm \"${String(p.algorithm)}\". Must be one of: ${[...VALID_ALGORITHMS].join(', ')}`,\n      path: 'algorithm',\n    })\n  }\n\n  if (p.version !== undefined && typeof p.version !== 'number') {\n    issues.push({\n      type: 'error',\n      code: 'INVALID_TYPE',\n      message: '\"version\" must be a number if provided',\n      path: 'version',\n    })\n  }\n\n  if (!Array.isArray(p.rules)) {\n    issues.push({ type: 'error', code: 'MISSING_FIELD', message: 'Policy must have a \"rules\" array', path: 'rules' })\n  } else {\n    if (p.rules.length > POLICY_LIMITS.rulesPerPolicy) {\n      issues.push({\n        type: 'error',\n        code: 'LIMIT_EXCEEDED',\n        message: `Policy has ${p.rules.length} rules; limit is ${POLICY_LIMITS.rulesPerPolicy}`,\n        path: 'rules',\n      })\n    }\n    for (const [i, rule] of p.rules.entries()) {\n      validateRuleShape(rule, `rules[${i}]`, issues)\n    }\n\n    // Check for duplicate rule IDs\n    const ruleIds = new Set<string>()\n    for (const rule of p.rules) {\n      if (typeof rule !== 'object' || rule === null) continue\n      const ruleId = Reflect.get(rule, 'id')\n      if (typeof ruleId === 'string') {\n        if (ruleIds.has(ruleId)) {\n          issues.push({\n            type: 'warning',\n            code: 'DUPLICATE_RULE_ID',\n            message: `Duplicate rule ID \"${ruleId}\"`,\n            path: 'rules',\n          })\n        }\n        ruleIds.add(ruleId)\n      }\n    }\n  }\n\n  if (p.targets !== undefined && p.targets !== null) {\n    if (typeof p.targets !== 'object' || Array.isArray(p.targets)) {\n      issues.push({\n        type: 'error',\n        code: 'INVALID_TYPE',\n        message: '\"targets\" must be an object if provided',\n        path: 'targets',\n      })\n    } else {\n      const targets = p.targets\n      for (const key of ['actions', 'resources', 'roles'] as const) {\n        const value = Reflect.get(targets, key)\n        if (value !== undefined && !Array.isArray(value)) {\n          issues.push({\n            type: 'error',\n            code: 'INVALID_TYPE',\n            message: `targets.${key} must be an array`,\n            path: `targets.${key}`,\n          })\n        }\n      }\n    }\n  }\n\n  return { valid: issues.every((i) => i.type !== 'error'), issues }\n}\n\n/**\n * Shape guard for a single Role: `id` non-empty, `permissions` array, optional `inherits: string[]`.\n *\n * @param input - The candidate role object (typically parsed JSON).\n * @returns A {@link IamValidate.IResult} with `valid: false` when any error issue was emitted.\n */\nexport function validateRole(input: unknown): IamValidate.IResult {\n  const issues: IamValidate.IIssue[] = []\n\n  if (!isPlainObject(input)) {\n    issues.push({ type: 'error', code: 'INVALID_TYPE', message: 'Role must be a non-null object', path: '' })\n    return { valid: false, issues }\n  }\n\n  const r = input\n\n  if (typeof r.id !== 'string' || !r.id) {\n    issues.push({\n      type: 'error',\n      code: 'MISSING_FIELD',\n      message: 'Role must have a non-empty string \"id\"',\n      path: 'id',\n    })\n  }\n\n  if (!Array.isArray(r.permissions)) {\n    issues.push({\n      type: 'error',\n      code: 'MISSING_FIELD',\n      message: 'Role must have a \"permissions\" array',\n      path: 'permissions',\n    })\n  }\n\n  if (r.inherits !== undefined && r.inherits !== null) {\n    if (!Array.isArray(r.inherits)) {\n      issues.push({\n        type: 'error',\n        code: 'INVALID_TYPE',\n        message: '\"inherits\" must be an array of strings if provided',\n        path: 'inherits',\n      })\n    } else {\n      for (const [i, v] of r.inherits.entries()) {\n        if (typeof v !== 'string') {\n          issues.push({\n            type: 'error',\n            code: 'INVALID_TYPE',\n            message: `\"inherits[${i}]\" must be a string`,\n            path: `inherits[${i}]`,\n          })\n        }\n      }\n    }\n  }\n\n  return { valid: issues.every((i) => i.type !== 'error'), issues }\n}\n\n/**\n * Parse a single policy row from `unknown`; returns the typed row or `null` on validation failure.\n *\n * @template TAction   - Action string union (TS-only constraint; trusted at the adapter boundary).\n * @template TResource - Resource string union (TS-only constraint; trusted at the adapter boundary).\n * @template TRole     - Role string union (TS-only constraint; trusted at the adapter boundary).\n */\nexport function parsePolicyRow<\n  TAction extends string = string,\n  TResource extends string = string,\n  TRole extends string = string,\n>(raw: unknown): AccessControl.IPolicy<TAction, TResource, TRole> | null {\n  if (!validatePolicy(raw).valid) return null\n  return raw as AccessControl.IPolicy<TAction, TResource, TRole>\n}\n\n/** Parse a single role row. Mirror of {@link parsePolicyRow}. */\nexport function parseRoleRow<\n  TAction extends string = string,\n  TResource extends string = string,\n  TRole extends string = string,\n  TScope extends string = string,\n>(raw: unknown): AccessControl.IRole<TAction, TResource, TRole, TScope> | null {\n  if (!validateRole(raw).valid) return null\n  return raw as AccessControl.IRole<TAction, TResource, TRole, TScope>\n}\n"],"mappings":"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"}