/** * ServiceAccessTokenCodec * * Long-lived serviceToken is a local/root setup credential. Cloud should not * embed it into provisionCode. Instead Cloud signs a short-lived access token * with serviceToken, and Local verifies it statelessly before accepting * provision callbacks. * * 格式: "sat-" + base64url(JSON payload) + "." + base64url(HMAC-SHA256 signature) */ export interface ServiceAccessTokenPayload { typ: 'xpod-service-access'; sub?: string; scopes: string[]; exp: number; } export interface CreateServiceAccessTokenOptions { /** Long-lived local serviceToken used only as signing secret. */ serviceToken: string; /** Node/app/service subject, normally nodeId. */ subject?: string; scopes: string[]; /** Relative lifetime in seconds. Ignored when expiresAt is set. */ ttlSeconds?: number; /** Absolute expiration as Unix timestamp seconds. */ expiresAt?: number; /** Test hook. Returns milliseconds. */ now?: () => number; } export interface VerifyServiceAccessTokenOptions { /** Long-lived local serviceToken used only as verification secret. */ serviceToken: string; requiredScope?: string; /** Test hook. Returns milliseconds. */ now?: () => number; } export type VerifyServiceAccessTokenResult = { valid: true; payload: ServiceAccessTokenPayload; } | { valid: false; reason: 'malformed' | 'signature' | 'expired' | 'scope'; }; export declare function createServiceAccessToken(options: CreateServiceAccessTokenOptions): string; export declare function verifyServiceAccessToken(token: string | undefined | null, options: VerifyServiceAccessTokenOptions): VerifyServiceAccessTokenResult;