/** * Single-query catalog introspection for the safegres audit. * * Pulls every relation + every policy + (parsed) role ACL per role in one shot, * so Script A can process the whole database from one in-memory snapshot. */ import type { Client, Pool } from 'pg'; /** Minimal query interface — accepts pg.Client, pg.Pool, or any `{ query }`. */ export interface QueryExecutor { query(text: string, params?: unknown[]): Promise<{ rows: T[]; }>; } /** PostgreSQL privilege codes as they appear in `pg_policy.polcmd` / ACL items. */ export type PgPrivilege = 'SELECT' | 'INSERT' | 'UPDATE' | 'DELETE' | 'TRUNCATE' | 'REFERENCES' | 'TRIGGER'; /** * Mapping of ACL single-letter codes (from `aclexplode`) to our privilege names. * `r` = SELECT, `a` = INSERT, `w` = UPDATE, `d` = DELETE, etc. */ export declare const ACL_PRIVILEGE_MAP: Record; export interface GrantInfo { role: string; privilege: PgPrivilege; /** Was the grant delegated (i.e. `WITH GRANT OPTION`). */ grantable: boolean; /** * `true` if the grantee role is a superuser or has `BYPASSRLS`. RLS policies * do not apply to this role, so coverage findings are suppressed for it. * `false` for `PUBLIC` and all other grantees. */ bypassRls: boolean; } /** `pg_policy.polcmd` uses: `r` SELECT, `a` INSERT, `w` UPDATE, `d` DELETE, `*` ALL. */ export type PolicyCmd = 'SELECT' | 'INSERT' | 'UPDATE' | 'DELETE' | 'ALL'; export declare const POLICY_CMD_MAP: Record; export interface PolicyInfo { name: string; cmd: PolicyCmd; permissive: boolean; /** Role names the policy applies to. `['PUBLIC']` if `polroles = {0}`. */ roles: string[]; using: string | null; withCheck: string | null; } export interface TableSnapshot { schema: string; name: string; oid: number; rlsEnabled: boolean; rlsForced: boolean; /** `true` if the table is partitioned or is a view — used to skip irrelevant findings. */ isPartitioned: boolean; owner: string; grants: GrantInfo[]; policies: PolicyInfo[]; } export interface IntrospectOptions { /** Schemas to include. If omitted, all non-system schemas. */ schemas?: string[]; /** * Schemas to exclude. Applied on top of `schemas`. * Defaults to `['pg_catalog', 'information_schema', 'pg_toast']`. */ excludeSchemas?: string[]; /** * Roles to include when reporting grants. If omitted, all roles returned * by {@link listAuditableRoles}. */ roles?: string[]; } /** * One-query snapshot of every table + its policies + its grants expanded per role. * * We deliberately avoid views that hide permissive vs restrictive distinctions * (like `pg_policies`) — `pg_policy` gives us `polpermissive` directly. */ export declare function introspectTables(exec: QueryExecutor, options?: IntrospectOptions): Promise; /** * Convenience: accept any of `pg.Client` / `pg.Pool` / a custom executor. */ export declare function asExecutor(client: Client | Pool | QueryExecutor): QueryExecutor;