import { type Kysely } from 'kysely';
import type { Database, AgentTokenRow } from '../db/types.js';
/**
 * Safe token row shape returned from list/validate (excludes token_hash).
 */
export type SafeAgentTokenRow = Omit<AgentTokenRow, 'token_hash'>;
/**
 * Manages agent authentication tokens.
 *
 * Tokens are kat_ + 64 hex chars (32 random bytes = 256 bits).
 * Only the SHA-256 hash is stored; the plaintext is returned once at generation time.
 */
export declare class AgentTokenStore {
    private readonly db;
    constructor(db: Kysely<Database>);
    /**
     * Create a static (long-lived) agent token.
     *
     * Static tokens have no expiry and are intended for manually-registered agents.
     *
     * @param opts.labels - Optional agent labels this token is authorized for.
     * @param opts.createdBy - Optional creator identifier (e.g. "cli:admin").
     * @returns The plaintext token (shown once) and the DB row ID.
     */
    createStatic(opts: {
        labels?: string[];
        createdBy?: string;
    }): Promise<{
        token: string;
        id: string;
    }>;
    /**
     * Create an ephemeral (short-lived) agent token.
     *
     * Ephemeral tokens are issued by the scaler for auto-provisioned agents
     * and expire after the specified TTL.
     *
     * @param agentId - The agent ID this token is for (used as created_by).
     * @param labels - Agent labels this token is authorized for.
     * @param ttlMs - Time-to-live in milliseconds.
     * @returns The plaintext token (shown once).
     */
    createEphemeral(agentId: string, labels: string[], ttlMs: number): Promise<string>;
    /**
     * Validate a plaintext token against stored hashes.
     *
     * Checks that the token exists, is not revoked, and has not expired.
     * On success, fires a non-blocking update to last_seen_at.
     *
     * @param token - The plaintext token to validate.
     * @returns The token row (without hash) if valid, null otherwise.
     */
    validate(token: string): Promise<SafeAgentTokenRow | null>;
    /**
     * Revoke a token by ID.
     *
     * Sets revoked_at to now. Returns true if the token was revoked,
     * false if it was already revoked or not found.
     *
     * @param id - The token row ID to revoke.
     * @returns True if the token was newly revoked.
     */
    revoke(id: string): Promise<boolean>;
    /**
     * List all non-revoked tokens (excludes token_hash for security).
     *
     * @param opts.agentType - Optional filter by agent type ('static' | 'ephemeral').
     * @returns Array of token rows without the hash field.
     */
    list(opts?: {
        agentType?: string;
    }): Promise<SafeAgentTokenRow[]>;
    /**
     * Clean up expired ephemeral tokens.
     *
     * Deletes rows where `expires_at < now()` and `agent_type = 'ephemeral'`.
     * Called periodically by the orchestrator (every 60s) to keep the
     * table from growing without bound.
     *
     * Optional `onBeforeDelete` callback is invoked once with the list
     * of expired token IDs **before** the DELETE runs. The orchestrator
     * uses this to call `agentRegistry.disconnectByTokenId(id)` for
     * each expired row, so any in-flight WS that survived the
     * per-token kick timer (e.g. across a process restart that wiped
     * the in-memory `tokenExpiryTimers` map) is still kicked. Closes
     * the sister gap to the revocation finding.
     *
     * @param opts.onBeforeDelete - Optional sync/async callback invoked
     *   with expired token IDs before the DELETE.
     * @returns Number of deleted rows.
     */
    cleanupExpired(opts?: {
        onBeforeDelete?: (tokenIds: string[]) => void | Promise<void>;
    }): Promise<number>;
}
//# sourceMappingURL=token-store.d.ts.map