/** * Automation-client secret resolution — the single place every API * auth path resolves a `clientId` + `clientSecret` pair from. * * Per `docs/credentials.md` the config file holds every credential's * **non-secret metadata** (`clientId`, `name`, `mintedAt`); the OS * keychain holds **only secrets**. So a `clientId` always comes from the * config and the matching `clientSecret` from the keychain. Resolution * walks three tiers: * * 1. `SITECOREAI_ENV__CLIENT_SECRET` (or the global * `SITECOREAI_CLIENT_SECRET`) environment variable — the * bring-your-own-client escape hatch. Paired with a `clientId` from * the env profile (or `SITECOREAI_ENV__CLIENT_ID`). * 2. The scai-minted env-scoped automation client: `clientId` from the * env profile's `automationClient` block, secret from the OS * keychain (`cm-client:`). * 3. The scai-minted org-scoped automation client: `clientId` from the * root config's `orgClients[orgId]` block, secret from the OS * keychain (`org-client:`). The fallback for org-level * profiles with no project/environment of their own. * * Lives in `shared/` (a leaf module): it depends only on the keychain * wrapper and `process.env`, never on `config/`. Callers pass the * non-secret `clientId`s — already read from the resolved config — in. */ /** * Tier 1 of secret resolution: the `SITECOREAI_ENV__CLIENT_SECRET` * environment variable, falling back to the global * `SITECOREAI_CLIENT_SECRET`. This is the bring-your-own-client escape * hatch — the operator supplies their own automation client and feeds * its secret in via the environment, never the config file. * * Returns `undefined` when neither variable is set. */ export declare const resolveEnvClientSecret: (envName: string) => string | undefined; /** A resolved automation-client credential pair. */ export interface ResolvedClientCredential { clientId: string; clientSecret: string; /** Which tier supplied the credential — useful for diagnostics. */ source: "env-var" | "cm-client" | "org-client"; } export interface ResolveClientCredentialOptions { /** * Env-profile name — keys tier 1's `SITECOREAI_ENV__*` env vars * and tier 2's `cm-client:` keychain slot. Optional: an org-scoped * caller (brief, campaign) may have no env profile, in which case * tiers 1 and 2 are skipped and only tier 3 (the org-scoped client) * can resolve. */ envName?: string; /** * `clientId` from the env profile (the bring-your-own-client escape * hatch). Pairs with the tier-1 env-var secret when set. */ clientId?: string; /** * `clientId` of the scai-minted env-scoped automation client — read * from the env profile's `automationClient` block. Pairs with the * tier-2 `cm-client:` keychain secret. */ automationClientId?: string; /** Organization id — keys the tier-3 `org-client:` slot. */ organizationId?: string; /** * `clientId` of the scai-minted org-scoped automation client — read * from the root config's `orgClients[orgId]` block. Pairs with the * tier-3 `org-client:` keychain secret. */ orgClientId?: string; } /** * Resolve a full `{ clientId, clientSecret }` automation-client pair via * the three-tier chain (env var → env-scoped keychain client → org-scoped * keychain client). `clientId` and `clientSecret` are always taken as a * matched pair from whichever tier supplies the secret. * * Returns `undefined` when no tier yields a usable pair — the caller * decides how to surface the missing credential. */ export declare const resolveClientCredential: (options: ResolveClientCredentialOptions) => Promise;