export interface CredentialContext { userEmail: string; orgId?: string | null; } export type CredentialStorageScope = "user" | "org"; /** * Resolve a credential from one explicit legacy SQL credential scope. * * Prefer `resolveCredential()` for normal app-local credential lookup. This * helper exists for workspace connection refs, where a ref can explicitly say * "use the org-scoped key" and must not accidentally read a user override. */ export declare function resolveCredentialForScope(key: string, ctx: CredentialContext & { scope: CredentialStorageScope; }): Promise; /** * Resolve a credential across the encrypted app_secrets store and the legacy * settings-backed credential store. User overrides win, followed by the * active org/workspace shared value. * * SECURITY: NEVER reads from process.env. Env vars are global to the * deployment and would leak across users in a multi-tenant app. * * Read order: * 1. user-scoped app_secrets * 2. user-scoped legacy settings credential * 3. org-scoped app_secrets * 4. legacy workspace-scoped app_secrets for the org * 5. org-scoped legacy settings credential * 6. solo workspace-scoped app_secrets (`solo:`) * * Steps 3-5 are skipped without an active org. */ export declare function resolveCredential(key: string, ctx: CredentialContext): Promise; /** * Explain an empty credential lookup when a key of that name is saved in a * scope the caller cannot read. * * Two distinct causes produce the same "the key is right there and it still * says it's missing" report: * * - Non-interactive runs — integration/webhook deliveries, scheduled jobs, * automations, and inbound A2A calls — resolve credentials as an owner * identity rather than as the person who triggered them, so a teammate's * Personal key is invisible to them even though the vault visibly holds it. * - The key is saved in a DIFFERENT organization the caller also belongs to. * Credentials are per-organization, so gaining a second organization (or * having `active-org-id` repointed at one) orphans every key synced under * the first. Without this, the only symptom is a missing-env-var error that * names the key rather than the org mismatch that actually caused it. * * SECURITY: both probes are bounded to organizations the caller is a member * of, report only the scope kind (and, for the cross-org case, the name of an * org the caller already belongs to), and never return the owning account, how * many rows matched, or any part of the value. Without an active org there is * no boundary to bound the probe to, so it declines to answer rather than * revealing that some other tenant holds a key of the same name. * * Returns null when nothing safe and useful can be said. */ export declare function describeCredentialScopeGap(keys: readonly string[], ctx: CredentialContext): Promise; /** * Check if a credential is available for the given context. */ export declare function hasCredential(key: string, ctx: CredentialContext): Promise; /** * Save a credential. By default writes to the per-user store; pass * `scope: "org"` to write to the active org's shared credentials. */ export declare function saveCredential(key: string, value: string, ctx: CredentialContext & { scope?: "user" | "org"; }): Promise; /** * Delete a credential from the per-user (default) or per-org store. */ export declare function deleteCredential(key: string, ctx: CredentialContext & { scope?: "user" | "org"; }): Promise; //# sourceMappingURL=index.d.ts.map