import { AuthupError, AuthupErrorOptions } from "@authup/errors"; import { DecisionStrategy } from "@authup/kit"; import { ICondition } from "@rapiq/core"; import { Issue, IssueGroup, IssueItem } from "@ebec/core"; import { Container } from "validup"; import { z } from "zod"; import { MongoFiltersParser, MongoFiltersParserInput } from "@rapiq/parser-mongo"; //#region src/policy/data.d.ts export interface IPolicyData { set(key: string, value: unknown): void; has(key: string): boolean; get(key: string): T; delete(key: string): void; isValidated(key: string): boolean; setValidated(key: string): void; clone(): IPolicyData; } export declare class PolicyData implements IPolicyData { protected data: Record; protected validated: Set; constructor(data?: Record, validated?: Set); set(key: string, value: T): void; get(key: string): T; has(key: string): boolean; delete(key: string): void; setValidated(key: string): void; isValidated(key: string): boolean; clone(): PolicyData; } //#endregion //#region src/policy/evaluation/context/types.d.ts /** * Receives the instants at which a clock-dependent verdict could change. * * A `date` or `time` policy that fell back to the real clock (no `date` / `time` * key in the bag) reports the next strictly-future instant its own verdict could * flip, from inside the evaluation walk that already runs. A caller that caches * an answer derived from such a walk learns when to stop trusting it. Reports may * be early (conservative) but never late, and `invert` does not move them. */ export type PolicyTransitionSink = { report(at: Date): void; }; export type PolicyEvaluationContext = { readonly evaluators: Record; readonly path: (string | number)[]; readonly exclude: string[]; readonly include: string[]; readonly data: PolicyData; /** * Attach the condition form (`PolicyEvaluationResult.condition`) to pending * subtrees via `IPolicyEvaluator.toCondition`. Off by default — evaluation-only * callers (evaluate / preEvaluate hot paths) must not pay the lowering cost; * query-build callers opt in. */ readonly withConditions: boolean; /** * Row column the realm reach is LOWERED onto, for a caller whose rows carry the * realm under another name (a junction's `roleRealmId` / `clientRealmId` / …). * Default `realmId`. It reaches `RealmMatchPolicyEvaluator` scope mode as * `attributeName`, which that mode reads only while lowering — settled * evaluation takes the resource realm from the `realmMatch` data key and never * consults a column name, so this can never change an evaluate() outcome. */ readonly realmAttributeName?: string; /** * Optional receiver of clock transitions (see {@link PolicyTransitionSink}). * Nested evaluations inherit it, since every walk propagates the context by * spread. */ readonly transitions?: PolicyTransitionSink; }; export type PolicyEvaluationContextInput = Partial; //#endregion //#region src/policy/evaluation/context/define.d.ts export declare function definePolicyEvaluationContext(input?: PolicyEvaluationContextInput): PolicyEvaluationContext; //#endregion //#region src/policy/evaluation/context/transition.d.ts export type PolicyTransitionCollector = PolicyTransitionSink & { /** * The earliest reported instant, or undefined when nothing reported one. */ readonly next: Date | undefined; }; /** * A sink keeping the earliest reported instant, which is the moment an answer * built from every evaluation it was handed to stops being current. */ export declare function createPolicyTransitionCollector(): PolicyTransitionCollector; //#endregion //#region src/policy/evaluation/types.d.ts export type PolicyEvaluators = Record; export type PolicyEvaluationResult = { success: boolean; /** * The policy could not be settled yet — a data key it requires is absent from the * evaluation bag (see {@link IPolicyEvaluator.requires}). Pending always rides on * `success: false` (fail-closed: a consumer that ignores the flag behaves like a * deny); only pre-gate style consumers treat pending as a pass. * * Unknown stays unknown: `invert` is never applied to a pending result. */ pending?: boolean; /** * EXACT condition form of the pending subtree (see * {@link IPolicyEvaluator.toCondition}): a row satisfies the condition iff the * pending subtree settles true on that row's attributes, given the current bag. * Attached only on pending results, only when the evaluation context requested it * (`withConditions`), and only when the ENTIRE pending subtree is expressible — * a partially expressible tree carries no condition (fail-safe: the consumer * falls back to a per-row post-check). */ condition?: ICondition; issues?: Issue[]; }; export interface IPolicyEvaluator { /** * PolicyData keys this policy needs before it can settle (e.g. `identity`, * `attributes`). When any returned key is absent from the evaluation bag, the * engine returns a pending result instead of invoking {@link evaluate}. * * Receives the raw (unvalidated) policy configuration, since data needs may be * config-dependent (e.g. realm-match scope vs. attribute mode). Omit the method * (or return an empty array) for policies evaluable with ambient data only. */ requires?(value: Record): string[]; /** * Express the policy as a condition over row attributes (rapiq `ICondition`) * instead of waiting for the row — the WHERE-pushdown capability. The result is * a partial evaluation against the knowns in `context.data` (e.g. the actor's * realm is baked into a realm-match condition), and must be EXACT: for every * row, `condition(row)` === "this policy settles true with attributes = row". * * Return `null` when this configuration is not expressible (the policy then * stays a per-row post-check — always sound). Omit the method for policies that * never lower (identity, date/time, attributeNames). */ toCondition?(value: Record, context: PolicyEvaluationContext): Promise; /** * Execute the policy with specific data and a given context. */ evaluate(value: Record, context: PolicyEvaluationContext): Promise; } //#endregion //#region src/policy/types.d.ts /** * A policy type's configuration validator, keyed by the type it validates. */ export type PolicyValidators = Record>>; export type BasePolicy = { /** * Type describing the policy. */ type?: T; /** * Invert evaluation result of policy (true->false and false->true) */ invert?: boolean; }; export type PolicyWithType = Record, T extends string = string> = R & BasePolicy; //#endregion //#region src/policy/engine/types.d.ts export interface IPolicyEngine { evaluate(policy: BasePolicy, options: PolicyEvaluationContext): Promise; evaluateOrFail(policy: BasePolicy, options: PolicyEvaluationContext): Promise; } //#endregion //#region src/policy/engine/module.d.ts /** * The policy engine is a component that interprets defined policies and makes decisions * on whether to allow or deny a particular access. */ export declare class PolicyEngine implements IPolicyEngine { protected evaluators: Record; constructor(evaluators?: PolicyEvaluators); registerEvaluator(type: string, evaluator: IPolicyEvaluator): void; registerEvaluators(evaluators: PolicyEvaluators): void; /** * @param policy * @param ctx */ evaluate(policy: BasePolicy, ctx: PolicyEvaluationContext): Promise; evaluateOrFail(policy: BasePolicy, ctx: PolicyEvaluationContext): Promise; } //#endregion //#region src/policy/issue/constants.d.ts export declare enum PolicyIssueSeverity { WARNING = "warning", ERROR = "error" } export declare enum PolicyIssueCode { DATA_MISSING = "DATA_MISSING", DATA_INVALID = "DATA_INVALID", INVALID = "INVALID", TYPE_UNKNOWN = "TYPE_UNKNOWN", FIELD_MISSING = "FIELD_MISSING", FIELD_INVALID = "FIELD_INVALID", CHILD_INVALID = "CHILD_INVALID", CHILD_EVALUATION_FAILED = "CHILD_EVALUATION_FAILED", EVALUATION_DENIED = "EVALUATION_DENIED", EVALUATOR_NOT_FOUND = "EVALUATOR_NOT_FOUND", EVALUATOR_ERROR = "EVALUATOR_ERROR", SKIPPED_EXCLUDED = "SKIPPED_EXCLUDED", SKIPPED_NOT_INCLUDED = "SKIPPED_NOT_INCLUDED", INTERNAL_ERROR = "INTERNAL_ERROR" } //#endregion //#region src/policy/issue/types.d.ts export type PolicyIssueItem = IssueItem; export type PolicyIssueGroup = IssueGroup; export type PolicyIssue = PolicyIssueItem | PolicyIssueGroup; //#endregion //#region src/policy/issue/define.d.ts export declare function definePolicyIssueItem(input: Omit): PolicyIssueItem; export declare function definePolicyIssueGroup(input: Omit): PolicyIssueGroup; //#endregion //#region src/policy/error/module.d.ts export declare const POLICY_ERROR_INSTANCE: unique symbol; export declare class PolicyError extends AuthupError { constructor(message?: string, code?: string | null, issues?: PolicyIssue[]); static evaluatorNotFound(type: string): PolicyError; static evaluatorNotProcessable(): PolicyError; static evaluatorContextInvalid(): PolicyError; } //#endregion //#region src/policy/error/check.d.ts export declare function isPolicyError(input: unknown): input is PolicyError; //#endregion //#region src/policy/helpers/invert.d.ts type InvertFn = (input: boolean) => boolean; export declare function maybeInvertPolicyOutcome(outcome: boolean, invert?: boolean | InvertFn): boolean; //#endregion //#region src/policy/built-in/attribute-names/types.d.ts export interface AttributeNamesPolicy extends BasePolicy { names: string[]; } //#endregion //#region src/policy/built-in/attribute-names/validator.d.ts export declare class AttributeNamesPolicyValidator extends Container { initialize(): void; } //#endregion //#region src/policy/built-in/attributes/types.d.ts export type AttributesPolicyQuery = Record> = MongoFiltersParserInput; export interface AttributesPolicy = Record> extends BasePolicy { query: AttributesPolicyQuery; } //#endregion //#region src/policy/built-in/attributes/define.d.ts export declare function defineAttributesPolicy = Record>(data: AttributesPolicy): AttributesPolicy; //#endregion //#region src/policy/built-in/attributes/validator.d.ts export declare class AttributesPolicyValidator = Record> extends Container> { initialize(): void; } //#endregion //#region src/policy/built-in/attributes/evaluator.d.ts export declare class AttributesPolicyEvaluator = Record> implements IPolicyEvaluator { protected validator: AttributesPolicyValidator; protected parser: MongoFiltersParser; constructor(); requires(): string[]; toCondition(value: Record): Promise; accessData(ctx: PolicyEvaluationContext): Promise; evaluate(value: Record, ctx: PolicyEvaluationContext): Promise; protected fixQuery(query: unknown | unknown[]): void; } //#endregion //#region src/policy/built-in/attribute-names/evaluator.d.ts export declare class AttributeNamesPolicyEvaluator implements IPolicyEvaluator { protected validator: AttributeNamesPolicyValidator; protected attributesEvaluator: AttributesPolicyEvaluator; constructor(); evaluate(value: Record, ctx: PolicyEvaluationContext): Promise; } //#endregion //#region src/policy/built-in/composite/types.d.ts export interface CompositePolicy extends BasePolicy { /** * How to decide if a policy evaluates to true. */ decisionStrategy?: `${DecisionStrategy}`; /** * Child policies. */ children: BasePolicy[]; } //#endregion //#region src/policy/built-in/composite/validator.d.ts export declare class CompositePolicyValidator extends Container { initialize(): void; } //#endregion //#region src/policy/built-in/composite/evaluator.d.ts export declare class CompositePolicyEvaluator implements IPolicyEvaluator { protected validator: CompositePolicyValidator; constructor(); evaluate(value: Record, ctx: PolicyEvaluationContext): Promise; } //#endregion //#region src/policy/built-in/composite/helper.d.ts export declare function isCompositePolicy(input: PolicyWithType): input is PolicyWithType; //#endregion //#region src/policy/built-in/date/types.d.ts export interface DatePolicy extends BasePolicy { start?: string | Date | number; end?: string | Date | number; } //#endregion //#region src/policy/built-in/date/validator.d.ts export declare class DatePolicyValidator extends Container { initialize(): void; } //#endregion //#region src/policy/built-in/date/evaluator.d.ts export declare class DatePolicyEvaluator implements IPolicyEvaluator { protected validator: DatePolicyValidator; constructor(); evaluate(value: Record, ctx: PolicyEvaluationContext): Promise; } //#endregion //#region src/permission/realm-scope/constants.d.ts /** * Actor-relative realm reach of a permission grant. * * Total order (least -> most permissive): none < own < ownOrNull < any. * A missing/unknown column coerces to `own` (fail-closed); `none` is only ever an * explicit value (the grant reaches no realm at all). */ export declare enum RealmScope { /** No reach — the grant matches no resource realm. */ NONE = "none", /** Own realm only — resource realm must equal the actor's realm. */ OWN = "own", /** Own realm or null/global resources (realmId === null). */ OWN_OR_NULL = "ownOrNull", /** Any realm, including null/global. */ ANY = "any" } /** Numeric restrictiveness order — internal to the fold/compare helpers. */ export declare const REALM_SCOPE_ORDER: Record<`${RealmScope}`, number>; //#endregion //#region src/permission/realm-scope/helpers.d.ts /** * Coerce an arbitrary value to a RealmScope, defaulting to `own` for missing / * null / unknown input (fail-closed). `none` is honoured only when explicit. */ export declare function normalizeRealmScope(value?: `${RealmScope}` | null): `${RealmScope}`; /** * Numeric comparison of two realm scopes by restrictiveness. * Negative when `a` is more restrictive than `b`, positive when less. */ export declare function compareRealmScope(a?: `${RealmScope}` | null, b?: `${RealmScope}` | null): number; /** Fold scopes to the MOST permissive (ordered max). Empty folds to `own`. */ export declare function maxRealmScope(values: Array<`${RealmScope}` | null | undefined>): `${RealmScope}`; /** Fold scopes to the MORE restrictive (ordered min) — used to CAP a grant. Empty folds to `own`. */ export declare function minRealmScope(values: Array<`${RealmScope}` | null | undefined>): `${RealmScope}`; /** * Whether `scope` reaches the resource. The resource realm may be presented as a single * id, `null` (global), or an array of realm ids — the array form (a resource that spans * multiple realms) requires the scope to reach EVERY listed realm (unanimous, fail-closed), * so any app/entity can express its realm via one or many keys under the canonical contract. */ export declare function realmScopeMatches(scope: `${RealmScope}` | null | undefined, resourceRealmId: string | Array | null | undefined, identityRealmId: string | null | undefined, identityRealmName?: string | null): boolean; //#endregion //#region src/permission/types.d.ts export type BasePermission = { name: string; clientId?: string | null; realmId?: string | null; decisionStrategy?: `${DecisionStrategy}` | null; }; /** * A raw permission grant: one permission with its policies and realm reach, as loaded from a * role/identity junction. `aggregatePermissionPolicyBindings` groups these per permission into * a `PermissionPolicyBindingAggregated` (the lossless disjunction of grants). */ export type PermissionPolicyBinding = { permission: BasePermission; policies?: BasePolicy[]; /** * Relative realm reach of this grant (none/own/ownOrNull/any). Absent coerces to the * most restrictive `own` (fail-closed). NOT part of the binding identity key * (see isPermissionPolicyBindingEqual). */ realmScope?: `${RealmScope}`; }; /** * One disjunction term of an aggregated binding: a single grant's realm reach paired with its * own (single) policy. A disjunction-aware consumer ORs `realmScopeMatches(realmScope) ∧ policy` * across the grants of a permission. */ export type PermissionGrant = { /** Relative realm reach (none/own/ownOrNull/any), normalized — fail-closed default `own`. */ realmScope: `${RealmScope}`; /** * The grant's policy: the raw junction policy (its `id` preserved, for propagation) for a * single-policy grant, a composite for a multi-policy (Layer-1) binding, or `undefined` * when the grant carries no restriction. */ policy?: BasePolicy; }; /** * A permission together with the actor's disjunction of grants for it. Output of * `aggregatePermissionPolicyBindings` — the honest, lossless replacement for the collapsed * `PermissionPolicyBinding` (no top-level realmScope/policies; the access decision is the * OR over `grants`). */ export type PermissionPolicyBindingAggregated = { permission: BasePermission; grants: PermissionGrant[]; }; //#endregion //#region src/policy/built-in/identity/types.d.ts export interface IdentityPolicy extends BasePolicy { /** * Set of allowed identity types. */ types?: string[]; } export type IdentityPolicyData = { /** * user, client */ type: string; /** * UUID */ id: string; /** * Client associated with identity. */ clientId?: string | null; /** * Realm id associated with identity. */ realmId?: string | null; /** * Realm name associated with identity. */ realmName?: string | null; /** * The grants the identity holds. The permission binding evaluator reads * them from here rather than loading them, so evaluation is a function of * the data alone. Whoever places an identity in the policy data places * its grants with it, and an identity without them holds none we could * prove. */ grants?: PermissionPolicyBinding[]; }; //#endregion //#region src/policy/built-in/identity/data/validator.d.ts declare class PolicyIdentityDataValidator extends Container { initialize(): void; } //#endregion //#region src/policy/built-in/identity/validator.d.ts export declare class IdentityPolicyValidator extends Container { initialize(): void; } //#endregion //#region src/policy/built-in/identity/evaluator.d.ts export declare class IdentityPolicyEvaluator implements IPolicyEvaluator { protected validator: IdentityPolicyValidator; protected dataValidator: PolicyIdentityDataValidator; constructor(); requires(): string[]; accessData(ctx: PolicyEvaluationContext): Promise; evaluate(value: Record, ctx: PolicyEvaluationContext): Promise; } //#endregion //#region src/policy/built-in/realm-match/types.d.ts export interface RealmMatchPolicy extends BasePolicy { /** * Determines how realm-id/name matches are handled. */ decisionStrategy?: `${DecisionStrategy}`; /** * Specifies the name(s) of the realm-id/name attribute(s) used for matching. * Can be a single attribute name or an array of attribute names. */ attributeName?: string | string[]; /** * Only match if the attribute is strict equal to the name. */ attributeNameStrict?: boolean; /** * Determines if resources with null realm-id/name value should match all identity realms. * If true, any identity realm can access resources with null realm-id/name values. */ attributeNullMatchAll?: boolean; /** * Coarse, actor-relative realm reach (none/own/ownOrNull/any). When set, the evaluator * runs in SCOPE MODE: it matches the resource realm read from the REALM_MATCH data key * against the identity realm via `realmScopeMatches`, and ignores `attributeName` / * `attributeNullMatchAll`. With no REALM_MATCH key present it neutral-passes. */ scope?: `${RealmScope}`; } //#endregion //#region src/policy/built-in/realm-match/validator.d.ts export declare class RealmMatchPolicyValidator extends Container { initialize(): void; } //#endregion //#region src/policy/built-in/realm-match/evaluator.d.ts export declare class RealmMatchPolicyEvaluator implements IPolicyEvaluator { protected validator: RealmMatchPolicyValidator; protected identityEvaluator: IdentityPolicyEvaluator; protected attributesEvaluator: AttributesPolicyEvaluator; constructor(); requires(value: Record): string[]; /** * Condition form over the row's realm column, with the actor realm baked in * (mirrors `realmScopeMatches` / the attribute-mode match). Exactness holds for * row-shaped data where the referenced field exists (DB rows) — the object-bag * "key absent → neutral-pass" case has no SQL counterpart. Lowerable configs: * scope mode (field = single-string `attributeName`, default `realmId` — scope-mode * EVALUATION ignores `attributeName`, lowering reuses it as the column override), * and strict attribute mode with a single explicit `attributeName`. Everything * else (multi-key / default-key CONSENSUS, non-strict key expansion) is * row-shape-dependent and stays a post-check. */ toCondition(value: Record, ctx: PolicyEvaluationContext): Promise; evaluate(value: Record, ctx: PolicyEvaluationContext): Promise; } //#endregion //#region src/policy/built-in/permission-binding/types.d.ts export interface PermissionBindingPolicy extends BasePolicy {} //#endregion //#region src/policy/built-in/permission-binding/validator.d.ts export declare class PermissionBindingPolicyValidator extends Container { initialize(): void; } //#endregion //#region src/policy/built-in/permission-binding/identity-evaluator.d.ts export declare class IdentityPermissionBindingPolicyEvaluator implements IPolicyEvaluator { protected validator: PermissionBindingPolicyValidator; protected identityEvaluator: IdentityPolicyEvaluator; protected realmMatchEvaluator: RealmMatchPolicyEvaluator; constructor(); requires(): string[]; accessData(ctx: PolicyEvaluationContext): Promise; /** * The grants the identity holds. An identity carrying none is missing * data, which throws a PolicyError carrying the refusing issue. */ accessGrants(ctx: PolicyEvaluationContext, identity: IdentityPolicyData): PermissionPolicyBinding[]; evaluate(value: Record, ctx: PolicyEvaluationContext): Promise; } //#endregion //#region src/policy/built-in/permission-binding/module.d.ts export declare class PermissionBindingPolicyEvaluator implements IPolicyEvaluator { protected validator: PermissionBindingPolicyValidator; constructor(); requires(): string[]; evaluate(value: Record): Promise; } //#endregion //#region src/policy/built-in/time/constants.d.ts export declare enum TimePolicyInterval { DAILY = "daily", WEEKLY = "weekly", MONTHLY = "monthly", YEARLY = "yearly" } //#endregion //#region src/policy/built-in/time/types.d.ts export interface TimePolicy extends BasePolicy { /** * Format: HH:MM */ start?: string | number | Date; /** * Format HH:MM */ end?: string | number | Date; /** * Interval: daily, weekly, monthly, yearly */ interval?: `${TimePolicyInterval}`; /** * 0 (Sunday) - 6 (Saturday) */ dayOfWeek?: number; /** * 1 - 31 */ dayOfMonth?: number; /** * 1 - 365 */ dayOfYear?: number; } //#endregion //#region src/policy/built-in/time/validator.d.ts export declare class TimePolicyValidator extends Container { initialize(): void; } //#endregion //#region src/policy/built-in/time/evaluator.d.ts export declare class TimePolicyEvaluator implements IPolicyEvaluator { protected validator: TimePolicyValidator; constructor(); evaluate(value: Record, ctx: PolicyEvaluationContext): Promise; } //#endregion //#region src/policy/built-in/time/helpers.d.ts export declare function isIntervalForDayOfWeek(interval: string): interval is TimePolicyInterval.WEEKLY | TimePolicyInterval.MONTHLY | TimePolicyInterval.YEARLY; export declare function isIntervalForDayOfMonth(interval: string): interval is TimePolicyInterval.MONTHLY | TimePolicyInterval.YEARLY; export declare function isIntervalForDayOfYear(interval: string): interval is TimePolicyInterval.YEARLY; //#endregion //#region src/policy/built-in/constants.d.ts export declare enum BuiltInPolicyType { /** * Bundles different policies. */ COMPOSITE = "composite", /** * Date Based Access Control (DBAC) */ DATE = "date", /** * Time Based Access Control (TBAC) */ TIME = "time", /** * Attribute Name Based Access Control (ANBAC) */ ATTRIBUTE_NAMES = "attributeNames", /** * Attribute Based Access Control (ABAC) */ ATTRIBUTES = "attributes", /** * Realm of Identity is for attribute realm. */ REALM_MATCH = "realmMatch", /** * Restriction based on identity (type, id, ...) */ IDENTITY = "identity", /** * Restriction based on a binding between identity <-> permission */ PERMISSION_BINDING = "permissionBinding" } export declare const SystemPolicyName: { readonly DEFAULT: "system.default"; readonly IDENTITY: "system.identity"; readonly PERMISSION_BINDING: "system.permission-binding"; readonly REALM_MATCH: "system.realm-match"; readonly CLIENT_NAMES_SELF_MANAGE: "system.client-names-self-manage"; readonly USER_NAMES_SELF_MANAGE: "system.user-names-self-manage"; }; //#endregion //#region src/policy/built-in/types.d.ts type BuiltInPolicyTypeMapRaw = Record> = { [BuiltInPolicyType.ATTRIBUTES]: AttributesPolicy; [BuiltInPolicyType.ATTRIBUTE_NAMES]: AttributeNamesPolicy; [BuiltInPolicyType.DATE]: DatePolicy; [BuiltInPolicyType.COMPOSITE]: CompositePolicy; [BuiltInPolicyType.TIME]: TimePolicy; [BuiltInPolicyType.IDENTITY]: IdentityPolicy; [BuiltInPolicyType.PERMISSION_BINDING]: PermissionBindingPolicy; [BuiltInPolicyType.REALM_MATCH]: RealmMatchPolicy; }; export type BuiltInPolicyTypeMap = Record> = { [K in keyof BuiltInPolicyTypeMapRaw as `${K}`]: BuiltInPolicyTypeMapRaw[K]; }; export type BuiltInPolicies = Record> = { [K in keyof BuiltInPolicyTypeMap]: BuiltInPolicyTypeMap[K] & { type: K; }; }[keyof BuiltInPolicyTypeMap]; //#endregion //#region src/policy/built-in/define.d.ts export declare function definePolicyWithType[K]>(type: K, data: D): PolicyWithType; //#endregion //#region src/policy/constants.d.ts export declare const PolicyDefaultEvaluators: { readonly composite: CompositePolicyEvaluator; readonly attributes: AttributesPolicyEvaluator>; readonly attributeNames: AttributeNamesPolicyEvaluator; readonly date: DatePolicyEvaluator; readonly identity: IdentityPolicyEvaluator; readonly permissionBinding: PermissionBindingPolicyEvaluator; readonly realmMatch: RealmMatchPolicyEvaluator; readonly time: TimePolicyEvaluator; }; /** * The configuration validator of every built-in policy type, keyed like * `PolicyDefaultEvaluators`. It is what `projectAuthorizationPolicy` runs a * node through, so a type absent here cannot travel in the authorization * catalog. The registry is open like the evaluator one (#3635): spread it and * add a custom type's validator to let that type travel. It is frozen, since * a write into it would make the type projectable for every caller in the * process. */ export declare const PolicyDefaultValidators: Readonly; //#endregion //#region src/policy/input.d.ts /** * Typed seed for a permission evaluation's {@link PolicyData} bag. * * The well-known context keys are value-typed, so construction is discoverable and a * wrong-typed value is a compile error. The trailing index signature keeps the bag **open** — * a third-party evaluator may supply its own key without any change to this published type * (the `access` evaluator set is deliberately extensible). */ export interface PolicyInput { [BuiltInPolicyType.IDENTITY]?: IdentityPolicyData; [BuiltInPolicyType.ATTRIBUTES]?: Record; [BuiltInPolicyType.REALM_MATCH]?: string | string[] | null; [key: string]: any; } /** * Build a {@link PolicyData} bag from a typed {@link PolicyInput} seed. Well-known keys * (identity / attributes / realmMatch) are type-checked; unknown keys are accepted as-is. * * Prefer this over `new PolicyData({ ... })` at construction sites so the key vocabulary and * per-key value types live in one place. */ export declare function definePolicyData(input?: PolicyInput): PolicyData; //#endregion //#region src/permission/error/module.d.ts export declare const PERMISSION_ERROR_INSTANCE: unique symbol; export declare class PermissionError extends AuthupError { constructor(options?: AuthupErrorOptions); static notFound(name: string): PermissionError; static denied(name: string): PermissionError; static deniedAll(names: string[]): PermissionError; static evaluationFailed(name: string | string[], issues?: PolicyIssue[]): PermissionError; } //#endregion //#region src/permission/error/check.d.ts export declare function isPermissionError(input: unknown): input is PermissionError; //#endregion //#region src/permission/helpers/aggregate.d.ts /** * Group raw permission-policy bindings by permission key into the actor's disjunction of * `(realmScope, policy)` grants per permission — with NO lossy collapse. Every consumer * (the binding evaluator, isSuperset, junction propagation, the memory provider) evaluates the * grant disjunction directly, so each grant's realm reach stays paired with the policy that * gates it. */ export declare function aggregatePermissionPolicyBindings(input: PermissionPolicyBinding[]): PermissionPolicyBindingAggregated[]; //#endregion //#region src/permission/helpers/equal.d.ts export declare function isPermissionPolicyBindingEqual(a: { permission: BasePermission; }, b: { permission: BasePermission; }): boolean; //#endregion //#region src/permission/helpers/grant.d.ts /** * Whether the actor's `parent` grant covers the target's `child` grant: it reaches at least as * far (ordered none < own < ownOrNull < any) AND its policy provably covers the child's * (see `policyDominates`). Used per grant by `isSuperset` over the aggregated disjunction — * every child grant must be dominated by SOME parent grant. */ export declare function grantDominates(parent: PermissionGrant, child: PermissionGrant): boolean; //#endregion //#region src/permission/helpers/key.d.ts export declare function buildPermissionKey(input: BasePermission): string; //#endregion //#region src/permission/provider/types.d.ts export type PermissionGetOptions = { name: string; clientId?: string | null; realmId?: string | null; }; export interface IPermissionProvider { findOne(criteria: PermissionGetOptions): Promise; } //#endregion //#region src/permission/provider/memory.d.ts export declare class PermissionMemoryProvider implements IPermissionProvider { protected items: Record; constructor(items?: PermissionPolicyBinding[]); findOne(options: PermissionGetOptions): Promise; setMany(input: PermissionPolicyBinding[]): void; } //#endregion //#region src/permission/evaluator/types.d.ts export interface IPermissionEvaluator { evaluate(ctx: PermissionEvaluationContext): Promise; evaluateOneOf(ctx: PermissionEvaluationContext): Promise; preEvaluate(ctx: PermissionEvaluationContext): Promise; preEvaluateOneOf(ctx: PermissionEvaluationContext): Promise; compile(ctx: PermissionCompileContext): Promise; } export type PermissionEvaluatorOptions = { provider: IPermissionProvider; policyEngine?: IPolicyEngine; realmId?: string | null; clientId?: string | null; }; export type PermissionEvaluationOptions = { decisionStrategy?: `${DecisionStrategy}`; policiesIncluded?: string[]; policiesExcluded?: string[]; /** * How a grant whose policy evaluation is PENDING (a required data key is absent — * see `PolicyEvaluationResult.pending`) is treated: * * - `deny` (default): pending counts as failure — full `evaluate()` semantics, * matching the historical missing-data deny. * - `permit`: pending counts as pass — the data-availability-derived pre-gate * (`preEvaluate()`): only a tree that settles false with the current bag denies. */ pendingPolicies?: 'deny' | 'permit'; /** * Receives the instants at which a clock-dependent policy (`date`, `time`) * in an evaluated tree could change its verdict, so a caller caching the * outcome knows when it expires. Handed to every policy evaluation this call * runs; a policy-free grant evaluates nothing and reports nothing. */ transitions?: PolicyTransitionSink; }; export type PermissionEvaluationContext = { name: string | string[]; realmId?: string | null; clientId?: string | null; data?: PolicyData; options?: PermissionEvaluationOptions; }; export type PermissionCompileContext = { /** * Permission name(s). Several names compile as a disjunction — the row is * readable when ANY of them passes (`evaluateOneOf` semantics). */ name: string | string[]; realmId?: string | null; clientId?: string | null; /** * The knowns bag (typically the actor identity). Row-dependent keys * (`attributes`, `realmMatch`) are deliberately absent — they are what the * compiled condition ranges over. */ data?: PolicyData; /** * Row column the realm reach is lowered onto, when the rows this compilation * ranges over carry their realm under another name — a junction's owner-realm * key (`roleRealmId`, `clientRealmId`, …). Default `realmId`. Affects the * `conditional` condition only; the per-row `post` fallback still reads the * realm from the `realmMatch` data key its caller supplies. */ realmAttributeName?: string; }; /** * Outcome of compiling a permission's policy trees against the knowns bag * (issue #3286 phase 3) — the query-build counterpart of `evaluate()`: * * - `allow` — settled true for every row; no restriction needed. * - `deny` — settled false for every row; no row can pass. * - `conditional` — the EXACT residual as a rapiq condition over row attributes: * push it into the row query (WHERE) and skip per-row post-evaluation. * - `post` — some pending policy is not expressible as a condition; fall back to * loading rows and evaluating per row (always sound). */ export type PermissionCompileResult = { verdict: 'allow'; } | { verdict: 'deny'; } | { verdict: 'conditional'; condition: ICondition; } | { verdict: 'post'; }; //#endregion //#region src/permission/evaluator/module.d.ts export declare class PermissionEvaluator implements IPermissionEvaluator { protected provider: IPermissionProvider; protected policyEngine: IPolicyEngine; protected clientId?: string | null; protected realmId?: string | null; constructor(options: PermissionEvaluatorOptions); protected findOne(input: string, overrides?: { realmId?: string | null; clientId?: string | null; }): Promise; evaluate(ctx: PermissionEvaluationContext): Promise; evaluateOneOf(ctx: PermissionEvaluationContext): Promise; preEvaluate(ctx: PermissionEvaluationContext): Promise; preEvaluateOneOf(ctx: PermissionEvaluationContext): Promise; /** * Compile the permission's policy trees against the knowns bag into a * {@link PermissionCompileResult} — the query-build counterpart of * {@link evaluate} (issue #3286 phase 3). Runs the SAME evaluation walk with * `withConditions` enabled: policies that settle with the knowns settle here, * pending subtrees contribute their exact condition form. Multiple names are * a disjunction (any-of), so a single non-expressible name degrades the whole * compilation to `post` — pushing only some disjuncts would wrongly exclude * rows another name would admit. */ compile(ctx: PermissionCompileContext): Promise; } //#endregion //#region src/permission/record/types.d.ts /** * The realm of the record a check is evaluated against: a realm id, `null` * for a global row, or a list of either when every listed realm must be * reached. */ export type RecordRealm = string | null | (string | null)[]; /** One record a single-record check is evaluated against. */ export type RecordTarget = { /** * The RECORD's realm (`null` = global row), or the target realm on * create. This is what each grant's `realm_scope` is matched against. * It is distinct from `PermissionEvaluationContext.realmId`, which is the * realm the PERMISSION is bound to. Required: `undefined` throws, so a * caller cannot drop the realm by omission and neutral-pass every grant's * `realm_scope`. */ realm: RecordRealm; /** * The policy data the record is evaluated with: the row under * `attributes` (for attribute policies on the grant; never synthesized, * so without it an attribute policy stays pending), an identity, a custom * key. Never mutated; must not carry `realmMatch`, which is set from * `realm`. */ data?: PolicyData | PolicyInput; }; export type RecordEvaluationContext = RecordTarget & { name: string | string[]; options?: PermissionEvaluationOptions; }; export type RecordUpdateEvaluationContext = { name: string | string[]; options?: PermissionEvaluationOptions; /** The stored row: the actor must reach it to change it at all. */ current: RecordTarget; /** The updated row: it must stay in reach afterwards. */ next: RecordTarget; }; //#endregion //#region src/permission/record/module.d.ts /** * Throws a permission error unless `name` passes for the record: each grant's * `realm_scope` is matched against the record's realm and its policies are * evaluated against the record. An array of names must ALL pass, like * `evaluate()`. */ export declare function evaluateRecord(evaluator: IPermissionEvaluator, ctx: RecordEvaluationContext): Promise; /** {@link evaluateRecord} where ANY of the names suffices, like `evaluateOneOf()`. */ export declare function evaluateRecordOneOf(evaluator: IPermissionEvaluator, ctx: RecordEvaluationContext): Promise; /** * {@link evaluateRecord} as a predicate. Only a permission error reads as * `false`; anything else propagates, so a failure on the authorization path * never turns into a quiet "not authorized". */ export declare function reachesRecord(evaluator: IPermissionEvaluator, ctx: RecordEvaluationContext): Promise; /** {@link evaluateRecordOneOf} as a predicate, like {@link reachesRecord}. */ export declare function reachesRecordOneOf(evaluator: IPermissionEvaluator, ctx: RecordEvaluationContext): Promise; /** * An update passes only when `name` passes for BOTH the stored row (the actor * may only change a row it can already reach) and the updated row (the row * must stay in reach afterwards). Evaluating the updated row alone lets an * update move a row INTO reach. */ export declare function evaluateRecordUpdate(evaluator: IPermissionEvaluator, ctx: RecordUpdateEvaluationContext): Promise; /** * Whether a grant of `name` (any of, for an array) reaches every realm with * no narrowing policy, i.e. `realm_scope: any`. Reads the `compile()` * verdict, so it relies on the binding policy (`system.default`) being bound * to the permission: without it a grant's reach is never evaluated and any * grant compiles to `allow`. Fail-closed: a policy-bearing `any` grant * compiles to `conditional` and reads as `false`. */ export declare function hasUnboundedReach(evaluator: IPermissionEvaluator, name: string | string[]): Promise; //#endregion //#region src/permission/authorization/error.d.ts export declare const AUTHORIZATION_CATALOG_STALE_ERROR_INSTANCE: unique symbol; /** * A grant references a definition or a policy the supplied catalog does not * carry: the caller's cached catalog predates the definition or the junction * row and must be refetched. A definition the catalog carries with * `policies: null`, and one whose tree this copy cannot project, are not * stale but unevaluable, and a grant of either is dropped. * * Recognize it with `isAuthorizationCatalogStaleError`, never `instanceof`: * this package is a plain caret dependency of several workspaces, so a * consumer tree may resolve two copies of it and turn the one recoverable * state into an unrecoverable one. */ export declare class AuthorizationCatalogStaleError extends AuthupError { constructor(message: string); } //#endregion //#region src/permission/authorization/check.d.ts /** * Marker-only: the error carries no code of its own, and it never crosses a * wire boundary, so there is no shape to fall back to. */ export declare function isAuthorizationCatalogStaleError(input: unknown): input is AuthorizationCatalogStaleError; //#endregion //#region src/permission/authorization/types.d.ts /** * One policy tree node as it travels: the type's configuration keys (the output * of that type's validator), `invert`, and for a composite its children inline. */ export type AuthorizationPolicy = { type: string; invert?: boolean | null; children?: AuthorizationPolicy[]; [key: string]: unknown; }; export type AuthorizationDefinition = { name: string; realm_id: string | null; client_id: string | null; decision_strategy: `${DecisionStrategy}` | null; /** * The definition layer: the ids of the policy trees bound to the permission * definition (`auth_permission_policies`). Empty means unrestricted at this * layer. `null` means the server could not project one of those trees onto * the wire (a policy type the catalog does not carry, or a configuration * its validator refuses): the definition exists, a consumer cannot evaluate * it and denies it, dropping every grant of it, until the policy is fixed. */ policies: string[] | null; }; /** * Identity-free and cacheable: every permission definition with its policy trees. */ export type AuthorizationCatalog = { /** * Every policy tree a definition or a grant can name, keyed by the tree's * own id and present exactly once however many of them reference it. */ policies: Record; permissions: AuthorizationDefinition[]; }; /** * One raw grant of an identity as the introspection endpoints report it: the * permission namespace it names, its realm reach and the junction policy ids. * Structurally the extended `OAuth2TokenPermission` of `@authup/specs` (this * package does not depend on specs). */ export type AuthorizationGrant = { name: string; realm_id?: string | null; client_id?: string | null; /** * Absent or null coerces to `own`, fail-closed. */ realm_scope?: `${RealmScope}` | null; /** * Absent or null means no junction policy. */ policies?: string[] | null; }; export type AuthorizationEvaluatorInput = { /** * An `AuthorizationCatalog`, validated by the schema. */ catalog: unknown; /** * `AuthorizationGrant[]`, validated by the schema. Defaults to none, and * may only be supplied together with the identity holding them. */ grants?: unknown; /** * The identity the grants belong to. Omitted for an anonymous caller: * no identity data is injected and no grant is bound, so only a * definition whose policies need no identity can pass. */ identity?: IdentityPolicyData; }; export type AuthorizationEvaluatorOptions = { /** * The policy types a catalog tree may carry. Defaults to * `PolicyDefaultValidators`; spread it to add a custom type. */ validators?: PolicyValidators; /** * How the projected trees evaluate. Defaults to * `PolicyDefaultEvaluators`; spread it to add a custom type. The * permission-binding evaluator is always replaced by the one binding the * introspected grants. */ evaluators?: PolicyEvaluators; }; /** * Which resource realms a batch check evaluates against. * * A string is SYMBOLIC and resolved server-side against the caller's own * identity: `own` is the realm the identity belongs to, `ownOrNull` is that * realm plus `null`, the global rows every realm shares. An array is taken * VERBATIM: the server resolves no realm key, so it discloses no realm's * existence and the caller matches the answer against its own input with no * resolution step of its own. * * String versus array is what discriminates the two forms, so `own` stays * unambiguous even though it is a legal realm name. */ export type AuthorizationCheckRealms = `${RealmScope.OWN}` | `${RealmScope.OWN_OR_NULL}` | Array; /** * One permission the identity may attempt, and the requested realms it may * attempt it in. Never empty: a permission reaching no requested realm is * absent from the answer entirely, so absent means denied. */ export type AuthorizationCheckPermission = { name: string; realms: Array; }; /** * The answer `POST /authorization/check` serves: the caller's own verdicts, * paired with the realms they hold in. * * It is an upper bound on what may be ATTEMPTED rather than an entitlement, * the same posture the catalog and `GET /schemas` take: it is a pre-gate, so a * grant whose junction policy needs a resource row passes here and is still * decided per row on the server, which stays the enforcement point. */ export type AuthorizationCheckPermissions = AuthorizationCheckPermission[]; export type AuthorizationCheckEvaluatorInput = { /** * An `AuthorizationCheckPermissions`, validated by the schema. */ permissions: unknown; /** * The identity the verdicts belong to, used to resolve a `realmMatch` of * `own` shape: a resource realm equal to this identity's realm id or name * is the identity's own realm. Omitted for an anonymous caller, which * holds no verdict at all. */ identity?: IdentityPolicyData; }; //#endregion //#region src/permission/authorization/check-schema.d.ts /** * The whole input `createAuthorizationCheckEvaluator` takes: the answer * `POST /authorization/check` served and the identity it belongs to. Same * validup-over-zod shape as the catalog's input, so a consumer can override * one member's rules instead of restating the answer. */ export declare class AuthorizationCheckEvaluatorInputValidator extends Container { initialize(): void; } export type AuthorizationCheckEvaluatorInputParsed = { permissions: AuthorizationCheckPermissions; identity: AuthorizationCheckEvaluatorInput['identity']; }; /** * Validate the check evaluator's input, plus the one rule a per-key validator * cannot express: a permission namespace appears at most once. Two entries for * one name would make the answer depend on which the consumer looked up first, * and the server emits one entry per name by construction. */ export declare function parseAuthorizationCheckEvaluatorInput(input: AuthorizationCheckEvaluatorInput): Promise; //#endregion //#region src/permission/authorization/constants.d.ts /** * The node a policy tree travels as when the server withholds it, because the * caller's realm reach does not cover the row it was read from. * * It is deliberately a type no consumer can project: `projectAuthorizationPolicy` * refuses it, which is already the state a definition referencing it denies * through and a grant naming it is dropped through, so withholding a body needs * no rule of its own on the consumer side. That is a contract between the two * halves rather than a server detail, which is why it is declared HERE, next to * the projection that has to keep refusing it, and pinned by this package's own * test. */ export declare const AUTHORIZATION_POLICY_WITHHELD_TYPE = "withheld"; //#endregion //#region src/permission/authorization/module.d.ts /** * Build a resource-server (or console) evaluator from the catalog * `GET /authorization` serves, the identity's grants as the introspection * endpoints report them, and the identity itself. Rejects legacy, incomplete * and unsupported input. A grant referencing a definition or a policy the * catalog lacks throws `AuthorizationCatalogStaleError`, the signal to * refetch the catalog: the grants come from a fresh introspection while the * catalog may predate the definition or the junction row. A definition the * server could not project travels with `policies: null` instead of being * left out, so a grant of it is dropped rather than reported stale: the * definition layer cannot be evaluated here, a refetch changes nothing, and * the permission denies until the policy is fixed. * * A tree THIS copy cannot project is the same condition read from the other * side, and it is per tree: a policy type the validator registry lacks (a * type newer than this package, or a custom one the caller did not register) * or a configuration its validator refuses denies the definitions that reference * it, exactly as `policies: null` does, and drops a grant that names it, * exactly as a binding check does. One such tree never takes the evaluator * down for the permissions that do not use it. A malformed catalog still * throws: a duplicate permission namespace is not a data condition. * * Both the identity and the grants are optional. Without an identity no grant * is bound and any IDENTITY key the caller supplied is REMOVED, so the * binding evaluator answers with missing data exactly as the server does for * an anonymous request, only a definition whose policies need no identity can * pass, and a caller can never inject an identity the document did not prove. * Grants without the identity they belong to are refused. * * The REALM_MATCH data key follows the server's own three-way rule: a * resource that carries a realm passes it (null for a global row, which * `own` denies), a resource with no realm dimension passes nothing and reach * neutral-passes. `preEvaluate` / `preEvaluateOneOf` are the pre-gate and * enforce reach only when that key is present. `compile` returns the * allow/deny/conditional/post contract; a `post` collection query must be * rejected or evaluated over every candidate before paging. The supplied * identity is authoritative; `options.decisionStrategy` is forwarded and the * policy include, exclude and pending options are refused. * * The policy type set is open (#3635): `options.validators` decides which * trees project and `options.evaluators` how they evaluate, the built-in * registries by default. A custom type needs both, the validator the server * projected it with and the evaluator the server decides it with; given only * the first it projects and then denies. The binding evaluator is always this * function's own, since it is what binds the introspected grants. */ export declare function createAuthorizationEvaluator(input: AuthorizationEvaluatorInput, options?: AuthorizationEvaluatorOptions): Promise; /** * An `IPermissionEvaluator` over the answer `POST /authorization/check` * served: the caller's own verdicts, paired with the realms they hold in. * * It is what a PUBLIC client gets where the catalog is out of reach. A public * client holds no secret, so it can obtain no `client_credentials` token and * has no credential of its own for the catalog's gate to be satisfied by; * publishing every policy predicate to it instead would be the wrong trade. * The verdicts are computed by the server from the same grants and the same * evaluators a request runs, so this is authoritative where the name-only * fallback it replaces is merely coarse. * * Two properties follow from the answer being a pre-gate: * * It is an UPPER BOUND, so `evaluate` and `evaluateOneOf` answer exactly what * the pre-gate pair answers. A check that depends on a resource row belongs to * whoever holds the row, and the server decides it there; answering such a * check here would mean inventing a verdict. That is the same bound the * name-only fallback already had, so nothing that gates on it loosens. * * And a resource realm is matched against what the REQUEST asked about: a * `realmMatch` naming a realm the request never carried is in no entry's list * and therefore denies. That is fail-closed by construction rather than by a * rule, and it is why a caller must ask about the realms its UI will ask * about. */ export declare function createAuthorizationCheckEvaluator(input: AuthorizationCheckEvaluatorInput): Promise; //#endregion //#region src/permission/authorization/policy.d.ts /** * The one definition of what a policy looks like on the wire, used by the server * to build a document and by the consumer to validate one. A node is the OUTPUT * of its type's validator (validup strips every unmounted key, so entity columns * such as `id`, `name`, `builtIn` or `createdAt` never travel), plus its type * and, for a composite, its projected children. * * The type set is the `validators` registry, `PolicyDefaultValidators` unless * the caller hands another (#3635): a type the registry lacks is refused, so * the server and a consumer that register the same custom type let it travel, * and one that does not denies it. The withheld node is refused whatever the * registry says, since projecting it would evaluate a tree the caller was not * allowed to see. * * Every refusal is a `ValidupError`, the node's head and the type's own * validator alike, and a child's issues are rebased onto the position it sits * at, so one message names the node in the tree that is wrong. */ export declare function projectAuthorizationPolicy(input: unknown, validators?: PolicyValidators): Promise; /** * Whether a projected tree evaluates the permission binding at any depth. A * grant policy carrying one would re-enter its own permission's grants, so * `createAuthorizationEvaluator` drops the grant that names it and evaluates * the permission from the rest. Its one caller is that consumer: the tree is * legal in a definition, where the binding check is what reach is enforced * by, so the producer carries it and only the grant side is refused. */ export declare function containsBindingCheck(policy: AuthorizationPolicy): boolean; //#endregion //#region src/permission/authorization/schema.d.ts /** * A policy node as it travels. Deliberately LOOSE: every key beyond `type` is * that type's own configuration, and `projectAuthorizationPolicy` is what * validates it, by running the type's own validator. Mounting a node in a * validup container would strip every key the container does not mount, and * the whole configuration would go with it. */ export declare const authorizationPolicySchema: z.ZodObject<{ type: z.ZodString; }, z.core.$loose>; /** * One permission definition. `policies` carries the ids of its * definition-layer trees, or `null` when the server could not project one. */ export declare const authorizationDefinitionSchema: z.ZodObject<{ name: z.ZodString; realm_id: z.ZodNullable; client_id: z.ZodNullable; decision_strategy: z.ZodNullable>; policies: z.ZodNullable>; }, z.core.$strip>; export declare const authorizationCatalogSchema: z.ZodObject<{ policies: z.ZodRecord>; permissions: z.ZodArray; client_id: z.ZodNullable; decision_strategy: z.ZodNullable>; policies: z.ZodNullable>; }, z.core.$strip>>; }, z.core.$strip>; /** * One grant of the identity, as the introspection endpoints report it. * Whether a grant's policy ids are declared is checked against the catalog * the consumer holds, since the two travel separately. */ export declare const authorizationGrantSchema: z.ZodObject<{ name: z.ZodString; realm_id: z.ZodOptional>; client_id: z.ZodOptional>; realm_scope: z.ZodOptional>>; policies: z.ZodOptional>>; }, z.core.$strip>; export declare const authorizationIdentitySchema: z.ZodObject<{ id: z.ZodString; type: z.ZodEnum<{ user: "user"; client: "client"; }>; realmId: z.ZodOptional>; realmName: z.ZodOptional>; clientId: z.ZodOptional>; }, z.core.$strip>; /** * The whole input `createAuthorizationEvaluator` takes: the catalog * `GET /authorization` serves, the grants an introspection reports and the * identity it names. A validup container over zod mounts, the shape every * validator in this package uses, so a consumer can reuse or override one * member's rules instead of restating the document. */ export declare class AuthorizationEvaluatorInputValidator extends Container { initialize(): void; } export type AuthorizationEvaluatorInputParsed = { catalog: AuthorizationCatalog; grants: AuthorizationGrant[]; identity: AuthorizationEvaluatorInput['identity']; }; /** * Validate the evaluator's input, plus the two rules per-key validators * cannot express. * * Every id a definition names must be a key of `policies`: a dangling id * resolves to `undefined`, which reads as "this layer carries no policy", so * a catalog that merely omitted a tree would grant unrestricted access rather * than fail. The lookup is own-property only, so an id such as `constructor` * cannot be answered by a member of `Object.prototype`. * * And the identity and its grants travel together: grants without an identity * belong to nobody, while an identity without a grant list is the shape an * INACTIVE introspection produces (`permissions` is absent unless the * credential is active), which read as "holds nothing" would authorize every * definition that carries no binding check. An identity holding no grant says * so with an empty array. */ export declare function parseAuthorizationEvaluatorInput(input: AuthorizationEvaluatorInput): Promise; /** * One verdict: the permission namespace and the requested realms it holds in. * A realm value is a realm key the caller itself supplied, or `null` for the * global rows, so nothing here is resolved or looked up. */ export declare const authorizationCheckPermissionSchema: z.ZodObject<{ name: z.ZodString; realms: z.ZodArray>; }, z.core.$strip>; export declare const authorizationCheckPermissionsSchema: z.ZodArray>; }, z.core.$strip>>; //#endregion export {}; //# sourceMappingURL=index.d.mts.map