/** * Push (FCM/APNs) credential storage + resolution for cadre-host. * * The platform-push secrets a self-hosted deployment provisions live in the host * secret store (keytar with file-store fallback — the same store DDNS tokens use); * the non-secret app-config bits (APNs bundle id / sandbox toggle, cooldown / * debounce) live in `host.config.json` (`PushSettings`). At node-spawn time the * orchestrator's `pushResolver` calls {@link resolvePushCredentials}, which reads * BOTH and merges them into the `PushCredentials` block written into the spawned * node's `cadre.json`. * * Secret hygiene: the FCM service-account fields and the APNs `.p8` key are stored * ONLY in the secret store, never in `host.config.json` and never in `state.json`. * They are re-read on every spawn so a restart picks up rotated keys, and the * resolver redacts on any log line. A partial credential set (a present platform * missing required fields) is rejected — fail fast, not at first push. */ import type { PushCredentials } from '@serfab/cadre-core'; import type { SecretsStore } from '../nat/secrets/index.js'; import type { PushSettings } from '../installer/config.js'; /** Push platform whose secret bundle lives in the secret store. */ export type PushSecretPlatform = 'fcm' | 'apns'; /** Build the secret-store account key for a platform's credential bundle. */ export declare function pushAccount(platform: PushSecretPlatform): string; /** FCM secret bundle persisted in the secret store (the whole set is sensitive). */ export interface FcmSecret { projectId: string; clientEmail: string; /** Service-account RSA private key, PEM. */ privateKey: string; } /** * APNs secret bundle persisted in the secret store. `bundleId` / `production` are * NOT here — they are non-secret app-config in {@link PushSettings}. */ export interface ApnsSecret { keyId: string; teamId: string; /** `.p8` ES256 private key, PEM. */ privateKey: string; } /** Store (or replace) the FCM service-account secret bundle. */ export declare function setFcmSecret(secrets: SecretsStore, secret: FcmSecret): Promise; /** Store (or replace) the APNs auth-key secret bundle. */ export declare function setApnsSecret(secrets: SecretsStore, secret: ApnsSecret): Promise; /** Remove a platform's secret bundle. Returns true if one was present. */ export declare function clearPushSecret(secrets: SecretsStore, platform: PushSecretPlatform): Promise; /** * Resolve the full {@link PushCredentials} block to inject into a spawned node, * merging the secret-store bundles with the non-secret {@link PushSettings}. * * Returns `undefined` when NO platform is configured (push is opt-in — the node * then constructs no fan-out). Throws when a configured platform is incomplete * (e.g. APNs secret present but `bundleId` unset), so a misconfig surfaces at the * spawn boundary rather than silently at first push. */ export declare function resolvePushCredentials(secrets: SecretsStore, settings: PushSettings | undefined): Promise; /** * A description of which push platforms are configured, for the `push status` CLI * and any UI — derived without exposing any secret material. */ export interface PushStatus { fcm: boolean; apns: boolean; } /** Report which platforms have a stored secret bundle (no secret material). */ export declare function pushStatus(secrets: SecretsStore): Promise;