/** * GC-PERM-011, Policy loader with signature validation. * * Wraps the raw policy bundle loading path with a signature validation * step. In managed mode, bundles with invalid or missing signatures are * rejected. In non-managed mode, unsigned bundles are allowed through * with a `SignatureStatus` of `'unsigned'` for UI display. * * This module does NOT perform I/O itself, it accepts a pre-parsed * `SignedPolicyBundle` so callers control the loading strategy. */ import { GoodVibesSdkError } from '@pellux/goodvibes-errors'; import type { PolicyRule } from './types.js'; import type { PolicyBundleId, SignatureStatus, ProvenanceSource, SignedPolicyBundle } from './policy-signer.js'; import type { FeatureFlagReader } from '../feature-flags/index.js'; /** * A policy bundle payload: the rules array and optional metadata. */ export interface PolicyBundlePayload { /** Version tag for schema migration. */ version: number; /** The ordered list of policy rules to register with the evaluator. */ rules: PolicyRule[]; /** Optional human-readable bundle description. */ description?: string | undefined; } /** * Provenance record attached to every loaded policy bundle. * * Carried forward onto each `PermissionDecision` produced by an evaluator * that was configured from this bundle. */ export interface BundleProvenance { /** Stable identifier for the bundle instance. */ policyBundleId: PolicyBundleId; /** Validation outcome for the bundle's signature. */ signatureStatus: SignatureStatus; /** Where the bundle originated from. */ provenanceSource: ProvenanceSource; /** ISO 8601 timestamp from the bundle, if present. */ issuedAt?: string | undefined; /** Human-readable issuer label, if present in the bundle. */ issuer?: string | undefined; } /** * Result returned by `loadPolicyBundle()`. */ export interface PolicyLoadResult { /** Whether the bundle was successfully loaded and validated. */ ok: boolean; /** The extracted policy rules (only populated when `ok` is true). */ rules?: PolicyRule[] | undefined; /** Provenance record for the bundle. */ provenance: BundleProvenance; /** Human-readable explanation of why loading failed (when `ok` is false). */ error?: string | undefined; } /** * PolicySignatureError, Thrown when a managed-mode bundle fails signature * validation and the caller opts into strict error throwing. * * Managed mode MUST reject bundles with invalid or missing signatures. */ export declare class PolicySignatureError extends GoodVibesSdkError { /** The bundle ID that failed validation. */ readonly bundleId: PolicyBundleId; /** The validation outcome. */ readonly signatureStatus: SignatureStatus; readonly code: 'POLICY_SIGNATURE_INVALID'; constructor( /** The bundle ID that failed validation. */ bundleId: PolicyBundleId, /** The validation outcome. */ signatureStatus: SignatureStatus, message: string); } /** * Options controlling how `loadPolicyBundle()` behaves. */ export interface PolicyLoaderOptions { /** * HMAC-SHA256 signing key (Buffer or hex string). * * Required when `managed` is true; optional otherwise. When absent, * signature verification is skipped and status is set to `'skipped'`. */ signingKey?: Buffer | string | undefined; /** * When true, the loader operates in managed mode: * - Bundles with `SignatureStatus` of `'invalid'` or `'missing'` are rejected. * - Bundles with `SignatureStatus` of `'unsigned'` are rejected. * - Only `'valid'` signatures are accepted. * * When false (default), unsigned bundles are permitted with status `'unsigned'`. */ managed?: boolean | undefined; /** * Describes where the bundle was loaded from. * Defaults to `'inline'` when not provided. */ provenanceSource?: ProvenanceSource | undefined; /** * When true, `loadPolicyBundle()` throws a `PolicySignatureError` on * rejection in managed mode instead of returning `{ ok: false }`. * * Defaults to false. */ throwOnRejection?: boolean | undefined; /** * The capability gates control signature validation when supplied by SDK runtime services. * Hosts without runtime gates can provide explicit loader options. */ featureFlags?: FeatureFlagReader | undefined; } /** * loadPolicyBundle, Validates and loads a signed policy bundle. * * Performs signature verification and returns the extracted rules with * a full provenance record. In managed mode, bundles that are unsigned, * missing a signature, or carry an invalid signature are rejected. * * In non-managed mode, unsigned bundles are accepted with status `'unsigned'` * so the UI can display a warning. * * @param bundle , The pre-parsed signed bundle object. * @param options, Loader behaviour options. * * @example * ```ts * const result = loadPolicyBundle(bundle, { * signingKey: process.env['POLICY_SIGNING_KEY'], * managed: true, * provenanceSource: 'local-file', * }); * if (!result.ok) { * throw new Error(`Policy load failed: ${result.error}`); * } * ``` */ export declare function loadPolicyBundle(bundle: SignedPolicyBundle, options?: PolicyLoaderOptions): PolicyLoadResult; /** * createUnsignedBundle, Convenience helper for non-managed/test usage. * * Creates a bare `SignedPolicyBundle` without a signature. The resulting * bundle will be accepted in non-managed mode with status `'unsigned'`. * * @param bundleId, Unique identifier for this bundle. * @param payload , The policy payload. */ export declare function createUnsignedBundle(bundleId: PolicyBundleId, payload: PolicyBundlePayload): SignedPolicyBundle; //# sourceMappingURL=policy-loader.d.ts.map