/** * The secret gate: every SDK method whose result carries a one-time secret the * caller would otherwise receive (a grant key, a Handoff or Invite Key, a Room * Invite Key, project credentials, a private key, a Lightning pairing, a * sign-in session or write-approval token), or whose input IS such a bearer * secret, calls {@link gateSecret} as its first statement. On a client whose * `capabilities.returnSecrets` is false — the `sandbox` surface an MCP `run` * snippet executes on — that call throws `SECRET_REQUIRES_CLI` before any * request, naming the exact CLI command for the same operation. On every * other surface it is a no-op. * * The gate is the method itself, keyed on a client capability: there is no * tool-name denylist and no path filter anywhere else, so every future door * that builds a `sandbox` client inherits it for free. * * {@link SECRET_RETURNING_METHODS} is the registry: one entry per gated * method (by its dotted path from the client root), with the command builder * and, for a method that carries a secret only when a particular option is * supplied, the predicate that says so. `sdk/src/node/secret-gate.test.ts` * owns the inventory: it fails when a method's types carry a secret-named * field and no entry names it, and when a registered method reaches the * network on a `sandbox` client. * * A command never embeds a secret value: where the input is the secret, the * command carries its placeholder (``), never the key. */ import type { Client } from "./kernel.js"; type Args = any[]; export interface SecretGateEntry { /** The exact CLI command line for the same operation, built from the call's own arguments. */ command: (...args: Args) => string; /** When present, the call is gated only when this returns true (the secret-bearing option was supplied). */ when?: (...args: Args) => boolean; /** Why the operation belongs to the CLI; defaults to the generic one-time-secret sentence. */ why?: string; } /** * Every gated method, by its dotted path from the client root. The command is * the CLI line for the same operation; the drift test calls each one on a * `sandbox` client and requires the refusal before any request. */ export declare const SECRET_RETURNING_METHODS: { "grants.create": { when: (_projectId: unknown, input: unknown) => boolean; command: (projectId: unknown, input: unknown) => string; why: string; }; "grants.createKey": { command: (projectId: unknown) => string; why: string; }; "grants.rotateKey": { command: (projectId: unknown, keyId: unknown) => string; why: string; }; "repos.handoff": { command: (opts: unknown) => string; }; "repos.invite": { command: (opts: unknown) => string; }; "repos.resume": { command: () => string; why: string; }; "repos.join": { command: () => string; why: string; }; "rooms.invite": { command: (orgId: unknown, roomKey: unknown) => string; }; "rooms.join": { command: () => string; why: string; }; "projects.provision": { command: (opts: unknown) => string; why: string; }; "projects.list": { when: (opts: unknown) => boolean; command: () => string; why: string; }; "projects.info": { command: (id: unknown) => string; why: string; }; "projects.keys": { command: (id: unknown) => string; why: string; }; "credentials.projectKeys.import": { command: (projectId: unknown) => string; why: string; }; "credentials.projectKeys.export": { command: (projectId: unknown) => string; why: string; }; "credentials.issue": { command: (projectId: unknown, input: unknown) => string; why: string; }; "credentials.rotate": { command: (projectId: unknown, credentialId: unknown) => string; why: string; }; "credentials.mintToken": { command: (projectId: unknown, opts: unknown) => string; why: string; }; "apps.fork": { command: (opts: unknown) => string; why: string; }; "branches.create": { command: (projectId: unknown) => string; why: string; }; "admin.transfers.initiate": { when: (input: unknown) => boolean; command: (input: unknown) => string; why: string; }; "admin.transfers.accept": { command: (transferId: unknown) => string; why: string; }; "admin.rotateWebhookSecret": { command: () => string; why: string; }; "wallets.create": { command: (name: unknown) => string; why: string; }; "wallets.import": { command: (name: unknown) => string; why: string; }; "agent.lightningWallet.mint": { command: () => string; why: string; }; "agent.lightningWallet.get": { command: () => string; why: string; }; "agent.lightningWallet.waitForActive": { command: () => string; why: string; }; init: { when: (opts: unknown) => boolean; command: () => string; why: string; }; "actions.run": { when: (input: unknown) => boolean; command: (input: unknown) => "run402 projects provision" | "run402 up"; why: string; }; "actions.up": { command: () => string; why: string; }; "session.exchangeCliToken": { command: () => string; why: string; }; "session.devicePoll": { command: () => string; why: string; }; "session.verifyEmail": { command: () => string; why: string; }; "session.passkeyVerify": { command: () => string; why: string; }; "session.consumeRecoveryCode": { command: () => string; why: string; }; "session.whoami": { when: (opts: unknown) => boolean; command: () => string; why: string; }; "session.refresh": { command: () => string; why: string; }; "session.revoke": { when: (opts: unknown) => boolean; command: () => string; why: string; }; "session.enrollPasskeyOptions": { when: (opts: unknown) => boolean; command: () => string; why: string; }; "session.enrollPasskeyVerify": { when: (opts: unknown) => boolean; command: () => string; why: string; }; "session.stepUpOptions": { when: (opts: unknown) => boolean; command: () => string; why: string; }; "session.stepUpVerify": { when: (opts: unknown) => boolean; command: () => string; why: string; }; "session.issueRecoveryCodes": { command: () => string; why: string; }; "session.listAuthenticators": { when: (opts: unknown) => boolean; command: () => string; why: string; }; "session.revokeAuthenticator": { when: (opts: unknown) => boolean; command: () => string; why: string; }; "session.sourceAccessWrappers": { when: (opts: unknown) => boolean; command: () => string; why: string; }; "session.sourceAccessRecoveryBundle": { when: (opts: unknown) => boolean; command: () => string; why: string; }; "writeApproval.requestChallenge": { command: () => string; why: string; }; "writeApproval.exchangeClaimCode": { command: () => string; why: string; }; "me.overview": { when: (opts: unknown) => boolean; command: () => string; why: string; }; "me.status": { when: (opts: unknown) => boolean; command: () => string; why: string; }; "orgs.adopt.challenge": { when: (opts: unknown) => boolean; command: () => string; why: string; }; "orgs.adopt.submit": { when: (opts: unknown) => boolean; command: () => string; why: string; }; "admin.channels.connectTelegram": { when: (_opts: unknown, proofs: unknown) => boolean; command: () => string; why: string; }; "admin.channels.revokeTelegram": { when: (_id: unknown, proofs: unknown) => boolean; command: (id: unknown) => string; why: string; }; "admin.rules.create": { when: (_i: unknown, proofs: unknown) => boolean; command: () => string; why: string; }; "admin.rules.update": { when: (_id: unknown, _p: unknown, proofs: unknown) => boolean; command: () => string; why: string; }; "admin.rules.delete": { when: (_id: unknown, proofs: unknown) => boolean; command: (id: unknown) => string; why: string; }; "admin.setNotificationPreferences": { when: (_p: unknown, proofs: unknown) => boolean; command: () => string; why: string; }; "auth.verifyMagicLink": { command: (projectId: unknown) => string; why: string; }; "auth.verify": { command: (projectId: unknown) => string; why: string; }; "auth.verifyEmailCode": { command: (projectId: unknown, opts: unknown) => string; why: string; }; "auth.setUserPassword": { command: (projectId: unknown) => string; why: string; }; "auth.setPassword": { command: (projectId: unknown) => string; why: string; }; "auth.createPasskeyRegistrationOptions": { command: (projectId: unknown) => string; why: string; }; "auth.verifyPasskeyRegistration": { command: (projectId: unknown) => string; why: string; }; "auth.verifyPasskeyLogin": { command: (projectId: unknown) => string; why: string; }; "auth.listPasskeys": { command: (projectId: unknown) => string; why: string; }; "auth.deletePasskey": { command: (projectId: unknown) => string; why: string; }; "live.changes": { when: (_projectId: unknown, opts: unknown) => boolean; command: (projectId: unknown, opts: unknown) => string; why: string; }; "live.subscribe": { when: (_projectId: unknown, opts: unknown) => boolean; command: (projectId: unknown, opts: unknown) => string; why: string; }; "escalations.ackWithToken": { command: () => string; why: string; }; "ci.exchangeToken": { command: () => string; why: string; }; }; export type SecretReturningMethod = keyof typeof SECRET_RETURNING_METHODS; /** Dotted path → entry, typed loosely for callers that look methods up by string. */ export declare const SECRET_GATE_REGISTRY: Readonly>; /** * Refuse this call before any request when the client may not return * secrets. The first statement of every registered method. The command is * built only on refusal, so the check costs nothing on the permissive path. */ export declare function gateSecret(client: { readonly capabilities?: Readonly; assertSecretReturn?: Client["assertSecretReturn"]; }, method: SecretReturningMethod, ...args: Args): void; export {}; //# sourceMappingURL=secret-gate.d.ts.map