Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@aegis-sdk/core

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@aegis-sdk/core - npm Package Compare versions

Comparing version
0.2.0
to
0.3.0
+622
-7
dist/index.d.cts

@@ -74,3 +74,15 @@ /**

riskTrend: number[];
/** Enhanced topic drift analysis from TrajectoryAnalyzer */
topicDrift?: TopicDriftResult;
}
interface TopicDriftResult {
/** Jaccard similarity scores between consecutive messages */
similarities: number[];
/** Indices where topic drift was detected (similarity below threshold) */
driftIndices: number[];
/** Whether escalation keywords appeared progressively */
escalationDetected: boolean;
/** Escalation keywords found, in order of appearance */
escalationKeywords: string[];
}
interface InputScannerConfig {

@@ -285,4 +297,20 @@ sensitivity?: Sensitivity;

}
/**
* A custom transport function invoked for each audit entry.
*
* May return `void` or `Promise<void>` -- async transports are
* fire-and-forget (errors are swallowed to avoid blocking the pipeline).
*/
type TransportFn = (entry: AuditEntry) => void | Promise<void>;
interface AuditLogConfig {
/**
* Primary transport (single). Kept for backward compatibility.
* When both `transport` and `transports` are set, they are merged.
*/
transport?: AuditTransport;
/**
* Multiple active transports. For example `['console', 'otel', 'custom']`
* enables all three simultaneously.
*/
transports?: AuditTransport[];
path?: string;

@@ -296,8 +324,81 @@ level?: AuditLevel;

rules: AlertRule[];
webhook?: string;
}
interface AlertRule {
condition: string;
action: "webhook" | "log" | "custom";
/** Optional unique identifier for this rule */
id?: string;
/** The condition that triggers this alert */
condition: AlertCondition;
/** Action to take when the alert fires */
action: "webhook" | "log" | "callback";
/** URL to POST to when action is "webhook" */
webhookUrl?: string;
/** Custom callback function when action is "callback" */
callback?: (alert: Alert) => void | Promise<void>;
/** Cooldown in ms before re-firing this rule. Default: 60000 (1 min) */
cooldownMs?: number;
}
type AlertCondition = {
type: "rate-spike";
event: AuditEventType;
threshold: number;
windowMs: number;
} | {
type: "session-kills";
threshold: number;
windowMs: number;
} | {
type: "cost-anomaly";
threshold: number;
windowMs: number;
} | {
type: "scan-block-rate";
threshold: number;
windowMs: number;
} | {
type: "repeated-attacker";
threshold: number;
windowMs: number;
};
interface Alert {
/** Unique alert identifier */
id: string;
/** The rule that triggered this alert */
ruleId: string;
/** The condition that was met */
condition: AlertCondition;
/** When the alert was triggered */
triggeredAt: Date;
/** When the alert was resolved (if applicable) */
resolvedAt?: Date;
/** Additional context about the alert */
context: Record<string, unknown>;
}
interface SignedMessage {
/** The original message */
message: PromptMessage;
/** HMAC-SHA256 hex signature */
signature: string;
}
interface SignedConversation {
/** Messages with their signatures */
messages: SignedMessage[];
/** Chained hash: each signature includes the previous one for ordering integrity */
chainHash: string;
}
interface IntegrityResult {
/** Whether all signatures are valid */
valid: boolean;
/** Indices of messages with invalid signatures */
tamperedIndices: number[];
/** Whether the chain hash ordering is intact */
chainValid: boolean;
}
interface MessageIntegrityConfig {
/** HMAC secret. Required. */
secret: string;
/** Algorithm. Default: 'SHA-256' */
algorithm?: string;
/** Only sign assistant messages (default: true) */
assistantOnly?: boolean;
}
type PresetPolicy = "strict" | "balanced" | "permissive" | "customer-support" | "code-assistant" | "paranoid";

@@ -313,2 +414,4 @@ interface AegisConfig {

agentLoop?: AgentLoopConfig;
/** HMAC message integrity configuration for detecting history manipulation (T15) */
integrity?: MessageIntegrityConfig;
}

@@ -326,6 +429,297 @@ interface RecoveryConfig {

/**
* Minimal interface matching a subset of `@opentelemetry/api` Span.
*/
interface OTelSpan {
setAttribute(key: string, value: string | number | boolean): void;
setStatus(status: {
code: number;
message?: string;
}): void;
end(): void;
}
/**
* Minimal interface matching a subset of `@opentelemetry/api` Counter.
*/
interface OTelCounter {
add(value: number, attributes?: Record<string, string>): void;
}
/**
* Minimal interface matching a subset of `@opentelemetry/api` Histogram.
*/
interface OTelHistogram {
record(value: number, attributes?: Record<string, string>): void;
}
/**
* Configuration for the OpenTelemetry audit transport.
*
* None of the fields are required -- the transport gracefully skips
* any instrumentation channel that is not wired up.
*/
interface OTelTransportConfig {
/** OTel Tracer instance (from `@opentelemetry/api`). */
tracer?: {
startSpan(name: string, options?: unknown): OTelSpan;
};
/** OTel Meter instance (from `@opentelemetry/api`). */
meter?: {
createCounter(name: string, options?: unknown): OTelCounter;
createHistogram(name: string, options?: unknown): OTelHistogram;
};
/** OTel Logger instance (from `@opentelemetry/api-logs`). */
logger?: {
emit(record: unknown): void;
};
/** Prefix for metric / span names. Default: `'aegis'`. */
prefix?: string;
}
/**
* OpenTelemetry-compatible transport for the Aegis audit log.
*
* This class does **not** depend on `@opentelemetry/*` packages at runtime.
* Instead, it accepts OTel API objects through its constructor so the consumer
* controls the OTel SDK version and configuration.
*
* @example
* ```ts
* import { trace, metrics } from '@opentelemetry/api';
* import { OTelTransport } from '@aegis-sdk/core';
*
* const otel = new OTelTransport({
* tracer: trace.getTracer('aegis'),
* meter: metrics.getMeter('aegis'),
* prefix: 'aegis',
* });
*
* auditLog.setOTelTransport(otel);
* ```
*/
declare class OTelTransport {
private readonly prefix;
private readonly tracer;
private readonly meter;
private readonly logger;
private totalCounter?;
private blockedCounter?;
private flaggedCounter?;
private scoreHistogram?;
constructor(config?: OTelTransportConfig);
/**
* Emit an audit entry through all configured OTel channels.
*
* - **Tracing**: creates a span for `blocked` / `flagged` events.
* - **Metrics**: increments counters and records histogram values.
* - **Logging**: forwards the entry to the OTel logger.
*/
emit(entry: AuditEntry): void;
}
/**
* Configuration for the JSON-Lines file transport.
*/
interface FileTransportConfig {
/** Path to the JSONL audit file. */
path: string;
/** Enable log rotation when `maxSizeMB` is exceeded. Default: `false`. */
rotate?: boolean;
/** Maximum file size in megabytes before rotation. Default: `50`. */
maxSizeMB?: number;
}
/**
* JSONL (JSON Lines) file transport for the Aegis audit log.
*
* Each audit entry is appended as a single JSON line. This transport
* requires a Node.js runtime (`fs` module). When running in an Edge
* or browser environment, construction throws a descriptive error.
*
* @example
* ```ts
* import { FileTransport, AuditLog } from '@aegis-sdk/core';
*
* const file = new FileTransport({ path: './audit.jsonl', rotate: true, maxSizeMB: 100 });
* const audit = new AuditLog({ transports: ['json-file'] });
* audit.setFileTransport(file);
* ```
*/
declare class FileTransport {
private readonly filePath;
private readonly rotate;
private readonly maxSizeBytes;
/**
* Cached reference to `node:fs` obtained via synchronous `require` or
* stored after the first successful dynamic import.
*/
private fsModule;
/** Promise that resolves once the async fs import completes (if needed). */
private fsReady;
constructor(config: FileTransportConfig);
/**
* Append an audit entry as a JSON line to the configured file.
*
* If the `fs` module has not finished loading yet this method will
* `await` the pending import before writing.
*/
emit(entry: AuditEntry): Promise<void>;
/**
* Dynamically import Node.js `fs` so this module can be bundled without
* a hard static dependency on `node:fs`.
*/
private loadFs;
/**
* Rotate the log file if it exceeds `maxSizeBytes`.
*
* Rotation renames the current file to `<path>.<timestamp>.jsonl` and
* the next `emit()` call will create a fresh file.
*/
private maybeRotate;
}
/**
* Alerting Engine — real-time alert system for the Aegis audit pipeline.
*
* Evaluates audit entries against configurable rules and fires alerts
* when conditions are met. Supports rate-spike detection, session kill
* monitoring, cost anomaly tracking, scan block rate analysis, and
* repeated attacker detection.
*
* Alert actions include console logging, webhook POSTs, and custom
* callback functions. Rules support cooldown periods to prevent
* alert flooding.
*/
/**
* AlertingEngine — evaluates audit entries against rules and fires alerts.
*
* Maintains a sliding window of recent audit entries for time-based
* condition evaluation. Each rule can specify a cooldown period to
* prevent alert flooding.
*
* @example
* ```ts
* const engine = new AlertingEngine({
* enabled: true,
* rules: [
* {
* condition: { type: 'rate-spike', event: 'scan_block', threshold: 10, windowMs: 60000 },
* action: 'log',
* },
* {
* condition: { type: 'session-kills', threshold: 3, windowMs: 300000 },
* action: 'webhook',
* webhookUrl: 'https://hooks.example.com/alerts',
* },
* ],
* });
*
* // Evaluate each audit entry
* const alerts = engine.evaluate(auditEntry);
* ```
*/
declare class AlertingEngine {
private readonly config;
private readonly rules;
private readonly activeAlerts;
private readonly recentEntries;
private readonly lastFired;
/** Maximum entries to keep in the sliding window */
private static readonly MAX_ENTRIES;
/** Default cooldown: 1 minute */
private static readonly DEFAULT_COOLDOWN_MS;
constructor(config: AlertingConfig);
/**
* Evaluate an audit entry against all configured rules.
*
* Returns any alerts that were triggered by this entry. Also
* executes the configured action for each triggered alert
* (logging, webhook, or callback).
*
* @param entry - The audit entry to evaluate
* @returns Array of triggered Alert objects
*/
evaluate(entry: AuditEntry): Alert[];
/**
* Get all currently active (unresolved) alerts.
*
* @returns Array of active Alert objects
*/
getActiveAlerts(): Alert[];
/**
* Resolve an alert by its ID.
*
* @param id - The alert ID to resolve
*/
resolveAlert(id: string): void;
/**
* Check whether a rule is currently in its cooldown period.
*/
private isInCooldown;
/**
* Evaluate a single alert condition against the current entry and
* recent entry history.
*/
private evaluateCondition;
/**
* Rate spike: more than N events of a specific type within a time window.
*/
private evaluateRateSpike;
/**
* Session kills: more than N kill_switch events within a time window.
*/
private evaluateSessionKills;
/**
* Cost anomaly: denial_of_wallet events exceeding threshold within a window.
*/
private evaluateCostAnomaly;
/**
* Scan block rate: percentage of scan_block vs total scans exceeds threshold.
* Threshold is expressed as a fraction (0-1), e.g., 0.5 = 50%.
*/
private evaluateScanBlockRate;
/**
* Repeated attacker: same session triggers blocks more than N times within a window.
*/
private evaluateRepeatedAttacker;
/**
* Execute the action configured for a triggered alert rule.
*/
private executeAction;
/**
* Log the alert to console.warn.
*/
private executeLog;
/**
* POST the alert to a webhook URL.
*/
private executeWebhook;
/**
* Invoke the custom callback function.
*/
private executeCallback;
/**
* Prune old entries from the sliding window to prevent unbounded memory growth.
*/
private pruneEntries;
}
/**
* Audit Log — records every decision, action, and violation in the pipeline.
*
* Supports multiple transports: console, JSON file, OpenTelemetry, or custom.
* Supports multiple simultaneous transports: console, JSON file,
* OpenTelemetry, or any number of custom transport functions.
* Every security-relevant event in the Aegis pipeline creates an audit entry.
*
* @example
* ```ts
* // Multiple transports active at once
* const audit = new AuditLog({
* transports: ['console', 'otel', 'custom'],
* level: 'all',
* });
*
* // Wire OTel
* audit.setOTelTransport(otel);
*
* // Add custom transports
* audit.addTransport((entry) => sendToDatadog(entry));
* audit.addTransport((entry) => sendToSplunk(entry));
* ```
*/

@@ -335,9 +729,48 @@ declare class AuditLog {

private entries;
private customTransport?;
/** Registered custom transport functions. */
private customTransports;
/** OpenTelemetry transport instance (optional). */
private otelTransport?;
/** JSON-Lines file transport instance (optional). */
private fileTransport?;
/** Alerting engine for evaluating rules against audit entries. */
private alertingEngine?;
constructor(config?: AuditLogConfig);
/**
* Set a custom transport function for audit entries.
*
* @deprecated Use {@link addTransport} instead for adding multiple custom
* transports. This method is kept for backward compatibility and replaces
* all existing custom transports with a single function.
*/
setCustomTransport(fn: (entry: AuditEntry) => void | Promise<void>): void;
setCustomTransport(fn: TransportFn): void;
/**
* Add a custom transport function.
*
* Multiple custom transports can be active simultaneously. Each one
* receives every audit entry that passes level filtering.
*/
addTransport(fn: TransportFn): void;
/**
* Remove a previously-added custom transport function.
*
* Uses reference equality — pass the same function reference that was
* originally added.
*/
removeTransport(fn: TransportFn): void;
/**
* Wire up an {@link OTelTransport} instance.
*
* When the `"otel"` transport is active, every audit entry is forwarded
* to this transport's `emit()` method.
*/
setOTelTransport(otel: OTelTransport): void;
/**
* Wire up a {@link FileTransport} instance for JSON-Lines file logging.
*
* When the `"json-file"` transport is active, every audit entry is
* forwarded to this transport's `emit()` method.
*/
setFileTransport(file: FileTransport): void;
/**
* Log an audit entry.

@@ -369,5 +802,26 @@ */

clear(): void;
/**
* Get the alerting engine instance, if alerting is configured.
*
* @returns The AlertingEngine instance, or null if alerting is not enabled
*/
getAlertingEngine(): AlertingEngine | null;
/**
* Get all active (unresolved) alerts from the alerting engine.
*
* @returns Array of active alerts, or empty array if alerting is not enabled
*/
getActiveAlerts(): Alert[];
private shouldLog;
private redact;
/**
* Dispatch an entry to every active transport.
*
* Multiple transports can fire simultaneously (e.g., console + otel + custom).
*/
private emit;
/**
* Route an entry to a single transport type.
*/
private emitToTransport;
private emitConsole;

@@ -436,2 +890,97 @@ }

/**
* HMAC Message Integrity Module.
*
* Signs and verifies assistant messages to detect conversation history
* manipulation (T15). Uses the Web Crypto API (SubtleCrypto) for HMAC
* operations so it works on Edge runtimes. Falls back to a simple
* hash-based approach when SubtleCrypto is not available.
*/
/**
* MessageSigner — signs and verifies assistant messages using HMAC-SHA256.
*
* Detects history manipulation (T15) by cryptographically binding message
* content to signatures. Supports chained hashing for ordering integrity:
* each signature incorporates the previous signature, so reordering or
* inserting messages is detectable.
*
* @example
* ```ts
* const signer = new MessageSigner({ secret: 'my-hmac-secret' });
*
* // Sign a conversation
* const signed = await signer.signConversation(messages);
*
* // Later, verify integrity
* const result = await signer.verifyConversation(signed);
* if (!result.valid) {
* console.warn('Tampered messages at indices:', result.tamperedIndices);
* }
* ```
*/
declare class MessageSigner {
private readonly secret;
private readonly algorithm;
private readonly assistantOnly;
private cryptoKey;
private readonly useSubtleCrypto;
constructor(config: MessageIntegrityConfig);
/**
* Import the HMAC key for SubtleCrypto operations.
* Caches the key after first import.
*/
private getKey;
/**
* Compute HMAC signature for the given data string.
*/
private hmac;
/**
* Build the signable content string for a message.
* Includes role and content to prevent role-swapping attacks.
*/
private messagePayload;
/**
* Determine whether a message should be signed based on configuration.
*/
private shouldSign;
/**
* Sign a single message and return its HMAC-SHA256 hex signature.
*
* @param message - The message to sign
* @returns The HMAC-SHA256 hex signature string
*/
sign(message: PromptMessage): Promise<string>;
/**
* Verify that a signature matches the given message content.
*
* @param message - The message to verify
* @param signature - The expected HMAC signature
* @returns true if the signature is valid
*/
verify(message: PromptMessage, signature: string): Promise<boolean>;
/**
* Sign all messages in a conversation, producing a SignedConversation.
*
* Each signed message's signature includes the previous signature
* (chain hashing) to ensure ordering integrity. Messages that are
* not signed (e.g., user messages when assistantOnly is true) get
* an empty signature but still participate in chain ordering.
*
* @param messages - The conversation messages to sign
* @returns A SignedConversation with signatures and a chain hash
*/
signConversation(messages: PromptMessage[]): Promise<SignedConversation>;
/**
* Verify the integrity of a signed conversation.
*
* Checks each signed message's signature and verifies the chain hash
* to detect both content tampering and message reordering/insertion.
*
* @param signed - The SignedConversation to verify
* @returns An IntegrityResult with detailed tampering information
*/
verifyConversation(signed: SignedConversation): Promise<IntegrityResult>;
}
/**
* Aegis — the main entry point for streaming-first prompt injection defense.

@@ -466,2 +1015,3 @@ *

private agentLoopConfig;
private messageSigner;
private sessionQuarantined;

@@ -519,2 +1069,12 @@ /** Default privilege decay schedule */

/**
* Get the message signer for HMAC integrity operations.
*
* Returns null if no integrity configuration was provided.
* Use the signer to sign conversations before storing them
* and verify them before processing to detect history manipulation (T15).
*
* @returns The MessageSigner instance, or null if integrity is not configured
*/
getMessageSigner(): MessageSigner | null;
/**
* Guard a single step in an agentic loop.

@@ -633,2 +1193,6 @@ *

* messages look benign but the conversation gradually escalates.
*
* Combines two analysis approaches:
* 1. Pattern-based risk scoring per message (original approach)
* 2. Keyword-based topic drift and escalation detection (TrajectoryAnalyzer)
*/

@@ -765,2 +1329,53 @@ analyzeTrajectory(messages: PromptMessage[]): TrajectoryResult;

/**
* Enhanced Conversation Trajectory Analysis.
*
* Provides keyword-based topic drift detection and escalation pattern
* recognition across conversation messages. Uses Jaccard similarity
* between consecutive message keyword sets to measure topic drift,
* and tracks risk-related keyword progression to detect gradual
* escalation attacks (Crescendo, T7).
*/
/**
* TrajectoryAnalyzer — enhanced conversation trajectory analysis.
*
* Tracks topic keywords across messages and detects:
* 1. **Topic drift**: Sudden topic changes measured by Jaccard similarity
* between consecutive message keyword sets
* 2. **Escalation patterns**: Progressive appearance of risk-related
* keywords across the conversation
*
* @example
* ```ts
* const analyzer = new TrajectoryAnalyzer({ driftThreshold: 0.1 });
* const result = analyzer.analyze(messages);
* if (result.escalationDetected) {
* console.warn('Escalation detected:', result.escalationKeywords);
* }
* ```
*/
declare class TrajectoryAnalyzer {
private readonly driftThreshold;
/**
* @param options - Configuration options
* @param options.driftThreshold - Jaccard similarity threshold below which
* topic drift is flagged. Default: 0.1
*/
constructor(options?: {
driftThreshold?: number;
});
/**
* Analyze a conversation's trajectory for topic drift and escalation.
*
* Examines user messages to extract keywords, compute consecutive
* message similarity, and detect progressive escalation patterns.
*
* @param messages - The conversation messages to analyze
* @returns TopicDriftResult with similarity scores, drift indices,
* and escalation information
*/
analyze(messages: PromptMessage[]): TopicDriftResult;
}
/**
* Resolve a policy from a preset name, policy object, or file path.

@@ -870,2 +1485,2 @@ */

export { type ActionValidationRequest, type ActionValidationResult, ActionValidator, type ActionValidatorConfig, Aegis, type AegisConfig, AegisInputBlocked, type AegisPolicy, AegisSessionQuarantined, AegisSessionTerminated, type AgentLoopConfig, type AlertRule, type AlertingConfig, type AuditEntry, type AuditEventType, type AuditLevel, AuditLog, type AuditLogConfig, type AuditTransport, type BuiltPrompt, type ChainStepOptions, type ChainStepResult, type ChunkStrategy, type ContentSource, type DelimiterStrategy, type DenialOfWalletConfig, type Detection, type DetectionType, type EntropyResult, type ExtractionSchema, type GuardInputOptions, InputScanner, type InputScannerConfig, type LanguageResult, type LanguageSwitch, type PiiHandling, type PresetPolicy, PromptBuilder, type PromptBuilderConfig, type PromptMessage, type QuarantineMetadata, type QuarantineOptions, type Quarantined, type RecoveryConfig, type RecoveryMode, type RiskLevel, Sandbox, type SandboxConfig, type ScanResult, type ScanStrategy, type Sensitivity, StreamMonitor, type StreamMonitorConfig, type StreamViolation, type TrajectoryResult, type UnsafeUnwrapOptions, aegis, analyzeEntropy, detectLanguageSwitches, getPreset, isActionAllowed, isQuarantined, normalizeEncoding, parseWindow, quarantine, resolvePolicy, shannonEntropy, tryDecodeBase64 };
export { type ActionValidationRequest, type ActionValidationResult, ActionValidator, type ActionValidatorConfig, Aegis, type AegisConfig, AegisInputBlocked, type AegisPolicy, AegisSessionQuarantined, AegisSessionTerminated, type AgentLoopConfig, type Alert, type AlertCondition, type AlertRule, type AlertingConfig, AlertingEngine, type AuditEntry, type AuditEventType, type AuditLevel, AuditLog, type AuditLogConfig, type AuditTransport, type BuiltPrompt, type ChainStepOptions, type ChainStepResult, type ChunkStrategy, type ContentSource, type DelimiterStrategy, type DenialOfWalletConfig, type Detection, type DetectionType, type EntropyResult, type ExtractionSchema, FileTransport, type FileTransportConfig, type GuardInputOptions, InputScanner, type InputScannerConfig, type IntegrityResult, type LanguageResult, type LanguageSwitch, type MessageIntegrityConfig, MessageSigner, type OTelCounter, type OTelHistogram, type OTelSpan, OTelTransport, type OTelTransportConfig, type PiiHandling, type PresetPolicy, PromptBuilder, type PromptBuilderConfig, type PromptMessage, type QuarantineMetadata, type QuarantineOptions, type Quarantined, type RecoveryConfig, type RecoveryMode, type RiskLevel, Sandbox, type SandboxConfig, type ScanResult, type ScanStrategy, type Sensitivity, type SignedConversation, type SignedMessage, StreamMonitor, type StreamMonitorConfig, type StreamViolation, type TopicDriftResult, TrajectoryAnalyzer, type TrajectoryResult, type TransportFn, type UnsafeUnwrapOptions, aegis, analyzeEntropy, detectLanguageSwitches, getPreset, isActionAllowed, isQuarantined, normalizeEncoding, parseWindow, quarantine, resolvePolicy, shannonEntropy, tryDecodeBase64 };

@@ -74,3 +74,15 @@ /**

riskTrend: number[];
/** Enhanced topic drift analysis from TrajectoryAnalyzer */
topicDrift?: TopicDriftResult;
}
interface TopicDriftResult {
/** Jaccard similarity scores between consecutive messages */
similarities: number[];
/** Indices where topic drift was detected (similarity below threshold) */
driftIndices: number[];
/** Whether escalation keywords appeared progressively */
escalationDetected: boolean;
/** Escalation keywords found, in order of appearance */
escalationKeywords: string[];
}
interface InputScannerConfig {

@@ -285,4 +297,20 @@ sensitivity?: Sensitivity;

}
/**
* A custom transport function invoked for each audit entry.
*
* May return `void` or `Promise<void>` -- async transports are
* fire-and-forget (errors are swallowed to avoid blocking the pipeline).
*/
type TransportFn = (entry: AuditEntry) => void | Promise<void>;
interface AuditLogConfig {
/**
* Primary transport (single). Kept for backward compatibility.
* When both `transport` and `transports` are set, they are merged.
*/
transport?: AuditTransport;
/**
* Multiple active transports. For example `['console', 'otel', 'custom']`
* enables all three simultaneously.
*/
transports?: AuditTransport[];
path?: string;

@@ -296,8 +324,81 @@ level?: AuditLevel;

rules: AlertRule[];
webhook?: string;
}
interface AlertRule {
condition: string;
action: "webhook" | "log" | "custom";
/** Optional unique identifier for this rule */
id?: string;
/** The condition that triggers this alert */
condition: AlertCondition;
/** Action to take when the alert fires */
action: "webhook" | "log" | "callback";
/** URL to POST to when action is "webhook" */
webhookUrl?: string;
/** Custom callback function when action is "callback" */
callback?: (alert: Alert) => void | Promise<void>;
/** Cooldown in ms before re-firing this rule. Default: 60000 (1 min) */
cooldownMs?: number;
}
type AlertCondition = {
type: "rate-spike";
event: AuditEventType;
threshold: number;
windowMs: number;
} | {
type: "session-kills";
threshold: number;
windowMs: number;
} | {
type: "cost-anomaly";
threshold: number;
windowMs: number;
} | {
type: "scan-block-rate";
threshold: number;
windowMs: number;
} | {
type: "repeated-attacker";
threshold: number;
windowMs: number;
};
interface Alert {
/** Unique alert identifier */
id: string;
/** The rule that triggered this alert */
ruleId: string;
/** The condition that was met */
condition: AlertCondition;
/** When the alert was triggered */
triggeredAt: Date;
/** When the alert was resolved (if applicable) */
resolvedAt?: Date;
/** Additional context about the alert */
context: Record<string, unknown>;
}
interface SignedMessage {
/** The original message */
message: PromptMessage;
/** HMAC-SHA256 hex signature */
signature: string;
}
interface SignedConversation {
/** Messages with their signatures */
messages: SignedMessage[];
/** Chained hash: each signature includes the previous one for ordering integrity */
chainHash: string;
}
interface IntegrityResult {
/** Whether all signatures are valid */
valid: boolean;
/** Indices of messages with invalid signatures */
tamperedIndices: number[];
/** Whether the chain hash ordering is intact */
chainValid: boolean;
}
interface MessageIntegrityConfig {
/** HMAC secret. Required. */
secret: string;
/** Algorithm. Default: 'SHA-256' */
algorithm?: string;
/** Only sign assistant messages (default: true) */
assistantOnly?: boolean;
}
type PresetPolicy = "strict" | "balanced" | "permissive" | "customer-support" | "code-assistant" | "paranoid";

@@ -313,2 +414,4 @@ interface AegisConfig {

agentLoop?: AgentLoopConfig;
/** HMAC message integrity configuration for detecting history manipulation (T15) */
integrity?: MessageIntegrityConfig;
}

@@ -326,6 +429,297 @@ interface RecoveryConfig {

/**
* Minimal interface matching a subset of `@opentelemetry/api` Span.
*/
interface OTelSpan {
setAttribute(key: string, value: string | number | boolean): void;
setStatus(status: {
code: number;
message?: string;
}): void;
end(): void;
}
/**
* Minimal interface matching a subset of `@opentelemetry/api` Counter.
*/
interface OTelCounter {
add(value: number, attributes?: Record<string, string>): void;
}
/**
* Minimal interface matching a subset of `@opentelemetry/api` Histogram.
*/
interface OTelHistogram {
record(value: number, attributes?: Record<string, string>): void;
}
/**
* Configuration for the OpenTelemetry audit transport.
*
* None of the fields are required -- the transport gracefully skips
* any instrumentation channel that is not wired up.
*/
interface OTelTransportConfig {
/** OTel Tracer instance (from `@opentelemetry/api`). */
tracer?: {
startSpan(name: string, options?: unknown): OTelSpan;
};
/** OTel Meter instance (from `@opentelemetry/api`). */
meter?: {
createCounter(name: string, options?: unknown): OTelCounter;
createHistogram(name: string, options?: unknown): OTelHistogram;
};
/** OTel Logger instance (from `@opentelemetry/api-logs`). */
logger?: {
emit(record: unknown): void;
};
/** Prefix for metric / span names. Default: `'aegis'`. */
prefix?: string;
}
/**
* OpenTelemetry-compatible transport for the Aegis audit log.
*
* This class does **not** depend on `@opentelemetry/*` packages at runtime.
* Instead, it accepts OTel API objects through its constructor so the consumer
* controls the OTel SDK version and configuration.
*
* @example
* ```ts
* import { trace, metrics } from '@opentelemetry/api';
* import { OTelTransport } from '@aegis-sdk/core';
*
* const otel = new OTelTransport({
* tracer: trace.getTracer('aegis'),
* meter: metrics.getMeter('aegis'),
* prefix: 'aegis',
* });
*
* auditLog.setOTelTransport(otel);
* ```
*/
declare class OTelTransport {
private readonly prefix;
private readonly tracer;
private readonly meter;
private readonly logger;
private totalCounter?;
private blockedCounter?;
private flaggedCounter?;
private scoreHistogram?;
constructor(config?: OTelTransportConfig);
/**
* Emit an audit entry through all configured OTel channels.
*
* - **Tracing**: creates a span for `blocked` / `flagged` events.
* - **Metrics**: increments counters and records histogram values.
* - **Logging**: forwards the entry to the OTel logger.
*/
emit(entry: AuditEntry): void;
}
/**
* Configuration for the JSON-Lines file transport.
*/
interface FileTransportConfig {
/** Path to the JSONL audit file. */
path: string;
/** Enable log rotation when `maxSizeMB` is exceeded. Default: `false`. */
rotate?: boolean;
/** Maximum file size in megabytes before rotation. Default: `50`. */
maxSizeMB?: number;
}
/**
* JSONL (JSON Lines) file transport for the Aegis audit log.
*
* Each audit entry is appended as a single JSON line. This transport
* requires a Node.js runtime (`fs` module). When running in an Edge
* or browser environment, construction throws a descriptive error.
*
* @example
* ```ts
* import { FileTransport, AuditLog } from '@aegis-sdk/core';
*
* const file = new FileTransport({ path: './audit.jsonl', rotate: true, maxSizeMB: 100 });
* const audit = new AuditLog({ transports: ['json-file'] });
* audit.setFileTransport(file);
* ```
*/
declare class FileTransport {
private readonly filePath;
private readonly rotate;
private readonly maxSizeBytes;
/**
* Cached reference to `node:fs` obtained via synchronous `require` or
* stored after the first successful dynamic import.
*/
private fsModule;
/** Promise that resolves once the async fs import completes (if needed). */
private fsReady;
constructor(config: FileTransportConfig);
/**
* Append an audit entry as a JSON line to the configured file.
*
* If the `fs` module has not finished loading yet this method will
* `await` the pending import before writing.
*/
emit(entry: AuditEntry): Promise<void>;
/**
* Dynamically import Node.js `fs` so this module can be bundled without
* a hard static dependency on `node:fs`.
*/
private loadFs;
/**
* Rotate the log file if it exceeds `maxSizeBytes`.
*
* Rotation renames the current file to `<path>.<timestamp>.jsonl` and
* the next `emit()` call will create a fresh file.
*/
private maybeRotate;
}
/**
* Alerting Engine — real-time alert system for the Aegis audit pipeline.
*
* Evaluates audit entries against configurable rules and fires alerts
* when conditions are met. Supports rate-spike detection, session kill
* monitoring, cost anomaly tracking, scan block rate analysis, and
* repeated attacker detection.
*
* Alert actions include console logging, webhook POSTs, and custom
* callback functions. Rules support cooldown periods to prevent
* alert flooding.
*/
/**
* AlertingEngine — evaluates audit entries against rules and fires alerts.
*
* Maintains a sliding window of recent audit entries for time-based
* condition evaluation. Each rule can specify a cooldown period to
* prevent alert flooding.
*
* @example
* ```ts
* const engine = new AlertingEngine({
* enabled: true,
* rules: [
* {
* condition: { type: 'rate-spike', event: 'scan_block', threshold: 10, windowMs: 60000 },
* action: 'log',
* },
* {
* condition: { type: 'session-kills', threshold: 3, windowMs: 300000 },
* action: 'webhook',
* webhookUrl: 'https://hooks.example.com/alerts',
* },
* ],
* });
*
* // Evaluate each audit entry
* const alerts = engine.evaluate(auditEntry);
* ```
*/
declare class AlertingEngine {
private readonly config;
private readonly rules;
private readonly activeAlerts;
private readonly recentEntries;
private readonly lastFired;
/** Maximum entries to keep in the sliding window */
private static readonly MAX_ENTRIES;
/** Default cooldown: 1 minute */
private static readonly DEFAULT_COOLDOWN_MS;
constructor(config: AlertingConfig);
/**
* Evaluate an audit entry against all configured rules.
*
* Returns any alerts that were triggered by this entry. Also
* executes the configured action for each triggered alert
* (logging, webhook, or callback).
*
* @param entry - The audit entry to evaluate
* @returns Array of triggered Alert objects
*/
evaluate(entry: AuditEntry): Alert[];
/**
* Get all currently active (unresolved) alerts.
*
* @returns Array of active Alert objects
*/
getActiveAlerts(): Alert[];
/**
* Resolve an alert by its ID.
*
* @param id - The alert ID to resolve
*/
resolveAlert(id: string): void;
/**
* Check whether a rule is currently in its cooldown period.
*/
private isInCooldown;
/**
* Evaluate a single alert condition against the current entry and
* recent entry history.
*/
private evaluateCondition;
/**
* Rate spike: more than N events of a specific type within a time window.
*/
private evaluateRateSpike;
/**
* Session kills: more than N kill_switch events within a time window.
*/
private evaluateSessionKills;
/**
* Cost anomaly: denial_of_wallet events exceeding threshold within a window.
*/
private evaluateCostAnomaly;
/**
* Scan block rate: percentage of scan_block vs total scans exceeds threshold.
* Threshold is expressed as a fraction (0-1), e.g., 0.5 = 50%.
*/
private evaluateScanBlockRate;
/**
* Repeated attacker: same session triggers blocks more than N times within a window.
*/
private evaluateRepeatedAttacker;
/**
* Execute the action configured for a triggered alert rule.
*/
private executeAction;
/**
* Log the alert to console.warn.
*/
private executeLog;
/**
* POST the alert to a webhook URL.
*/
private executeWebhook;
/**
* Invoke the custom callback function.
*/
private executeCallback;
/**
* Prune old entries from the sliding window to prevent unbounded memory growth.
*/
private pruneEntries;
}
/**
* Audit Log — records every decision, action, and violation in the pipeline.
*
* Supports multiple transports: console, JSON file, OpenTelemetry, or custom.
* Supports multiple simultaneous transports: console, JSON file,
* OpenTelemetry, or any number of custom transport functions.
* Every security-relevant event in the Aegis pipeline creates an audit entry.
*
* @example
* ```ts
* // Multiple transports active at once
* const audit = new AuditLog({
* transports: ['console', 'otel', 'custom'],
* level: 'all',
* });
*
* // Wire OTel
* audit.setOTelTransport(otel);
*
* // Add custom transports
* audit.addTransport((entry) => sendToDatadog(entry));
* audit.addTransport((entry) => sendToSplunk(entry));
* ```
*/

@@ -335,9 +729,48 @@ declare class AuditLog {

private entries;
private customTransport?;
/** Registered custom transport functions. */
private customTransports;
/** OpenTelemetry transport instance (optional). */
private otelTransport?;
/** JSON-Lines file transport instance (optional). */
private fileTransport?;
/** Alerting engine for evaluating rules against audit entries. */
private alertingEngine?;
constructor(config?: AuditLogConfig);
/**
* Set a custom transport function for audit entries.
*
* @deprecated Use {@link addTransport} instead for adding multiple custom
* transports. This method is kept for backward compatibility and replaces
* all existing custom transports with a single function.
*/
setCustomTransport(fn: (entry: AuditEntry) => void | Promise<void>): void;
setCustomTransport(fn: TransportFn): void;
/**
* Add a custom transport function.
*
* Multiple custom transports can be active simultaneously. Each one
* receives every audit entry that passes level filtering.
*/
addTransport(fn: TransportFn): void;
/**
* Remove a previously-added custom transport function.
*
* Uses reference equality — pass the same function reference that was
* originally added.
*/
removeTransport(fn: TransportFn): void;
/**
* Wire up an {@link OTelTransport} instance.
*
* When the `"otel"` transport is active, every audit entry is forwarded
* to this transport's `emit()` method.
*/
setOTelTransport(otel: OTelTransport): void;
/**
* Wire up a {@link FileTransport} instance for JSON-Lines file logging.
*
* When the `"json-file"` transport is active, every audit entry is
* forwarded to this transport's `emit()` method.
*/
setFileTransport(file: FileTransport): void;
/**
* Log an audit entry.

@@ -369,5 +802,26 @@ */

clear(): void;
/**
* Get the alerting engine instance, if alerting is configured.
*
* @returns The AlertingEngine instance, or null if alerting is not enabled
*/
getAlertingEngine(): AlertingEngine | null;
/**
* Get all active (unresolved) alerts from the alerting engine.
*
* @returns Array of active alerts, or empty array if alerting is not enabled
*/
getActiveAlerts(): Alert[];
private shouldLog;
private redact;
/**
* Dispatch an entry to every active transport.
*
* Multiple transports can fire simultaneously (e.g., console + otel + custom).
*/
private emit;
/**
* Route an entry to a single transport type.
*/
private emitToTransport;
private emitConsole;

@@ -436,2 +890,97 @@ }

/**
* HMAC Message Integrity Module.
*
* Signs and verifies assistant messages to detect conversation history
* manipulation (T15). Uses the Web Crypto API (SubtleCrypto) for HMAC
* operations so it works on Edge runtimes. Falls back to a simple
* hash-based approach when SubtleCrypto is not available.
*/
/**
* MessageSigner — signs and verifies assistant messages using HMAC-SHA256.
*
* Detects history manipulation (T15) by cryptographically binding message
* content to signatures. Supports chained hashing for ordering integrity:
* each signature incorporates the previous signature, so reordering or
* inserting messages is detectable.
*
* @example
* ```ts
* const signer = new MessageSigner({ secret: 'my-hmac-secret' });
*
* // Sign a conversation
* const signed = await signer.signConversation(messages);
*
* // Later, verify integrity
* const result = await signer.verifyConversation(signed);
* if (!result.valid) {
* console.warn('Tampered messages at indices:', result.tamperedIndices);
* }
* ```
*/
declare class MessageSigner {
private readonly secret;
private readonly algorithm;
private readonly assistantOnly;
private cryptoKey;
private readonly useSubtleCrypto;
constructor(config: MessageIntegrityConfig);
/**
* Import the HMAC key for SubtleCrypto operations.
* Caches the key after first import.
*/
private getKey;
/**
* Compute HMAC signature for the given data string.
*/
private hmac;
/**
* Build the signable content string for a message.
* Includes role and content to prevent role-swapping attacks.
*/
private messagePayload;
/**
* Determine whether a message should be signed based on configuration.
*/
private shouldSign;
/**
* Sign a single message and return its HMAC-SHA256 hex signature.
*
* @param message - The message to sign
* @returns The HMAC-SHA256 hex signature string
*/
sign(message: PromptMessage): Promise<string>;
/**
* Verify that a signature matches the given message content.
*
* @param message - The message to verify
* @param signature - The expected HMAC signature
* @returns true if the signature is valid
*/
verify(message: PromptMessage, signature: string): Promise<boolean>;
/**
* Sign all messages in a conversation, producing a SignedConversation.
*
* Each signed message's signature includes the previous signature
* (chain hashing) to ensure ordering integrity. Messages that are
* not signed (e.g., user messages when assistantOnly is true) get
* an empty signature but still participate in chain ordering.
*
* @param messages - The conversation messages to sign
* @returns A SignedConversation with signatures and a chain hash
*/
signConversation(messages: PromptMessage[]): Promise<SignedConversation>;
/**
* Verify the integrity of a signed conversation.
*
* Checks each signed message's signature and verifies the chain hash
* to detect both content tampering and message reordering/insertion.
*
* @param signed - The SignedConversation to verify
* @returns An IntegrityResult with detailed tampering information
*/
verifyConversation(signed: SignedConversation): Promise<IntegrityResult>;
}
/**
* Aegis — the main entry point for streaming-first prompt injection defense.

@@ -466,2 +1015,3 @@ *

private agentLoopConfig;
private messageSigner;
private sessionQuarantined;

@@ -519,2 +1069,12 @@ /** Default privilege decay schedule */

/**
* Get the message signer for HMAC integrity operations.
*
* Returns null if no integrity configuration was provided.
* Use the signer to sign conversations before storing them
* and verify them before processing to detect history manipulation (T15).
*
* @returns The MessageSigner instance, or null if integrity is not configured
*/
getMessageSigner(): MessageSigner | null;
/**
* Guard a single step in an agentic loop.

@@ -633,2 +1193,6 @@ *

* messages look benign but the conversation gradually escalates.
*
* Combines two analysis approaches:
* 1. Pattern-based risk scoring per message (original approach)
* 2. Keyword-based topic drift and escalation detection (TrajectoryAnalyzer)
*/

@@ -765,2 +1329,53 @@ analyzeTrajectory(messages: PromptMessage[]): TrajectoryResult;

/**
* Enhanced Conversation Trajectory Analysis.
*
* Provides keyword-based topic drift detection and escalation pattern
* recognition across conversation messages. Uses Jaccard similarity
* between consecutive message keyword sets to measure topic drift,
* and tracks risk-related keyword progression to detect gradual
* escalation attacks (Crescendo, T7).
*/
/**
* TrajectoryAnalyzer — enhanced conversation trajectory analysis.
*
* Tracks topic keywords across messages and detects:
* 1. **Topic drift**: Sudden topic changes measured by Jaccard similarity
* between consecutive message keyword sets
* 2. **Escalation patterns**: Progressive appearance of risk-related
* keywords across the conversation
*
* @example
* ```ts
* const analyzer = new TrajectoryAnalyzer({ driftThreshold: 0.1 });
* const result = analyzer.analyze(messages);
* if (result.escalationDetected) {
* console.warn('Escalation detected:', result.escalationKeywords);
* }
* ```
*/
declare class TrajectoryAnalyzer {
private readonly driftThreshold;
/**
* @param options - Configuration options
* @param options.driftThreshold - Jaccard similarity threshold below which
* topic drift is flagged. Default: 0.1
*/
constructor(options?: {
driftThreshold?: number;
});
/**
* Analyze a conversation's trajectory for topic drift and escalation.
*
* Examines user messages to extract keywords, compute consecutive
* message similarity, and detect progressive escalation patterns.
*
* @param messages - The conversation messages to analyze
* @returns TopicDriftResult with similarity scores, drift indices,
* and escalation information
*/
analyze(messages: PromptMessage[]): TopicDriftResult;
}
/**
* Resolve a policy from a preset name, policy object, or file path.

@@ -870,2 +1485,2 @@ */

export { type ActionValidationRequest, type ActionValidationResult, ActionValidator, type ActionValidatorConfig, Aegis, type AegisConfig, AegisInputBlocked, type AegisPolicy, AegisSessionQuarantined, AegisSessionTerminated, type AgentLoopConfig, type AlertRule, type AlertingConfig, type AuditEntry, type AuditEventType, type AuditLevel, AuditLog, type AuditLogConfig, type AuditTransport, type BuiltPrompt, type ChainStepOptions, type ChainStepResult, type ChunkStrategy, type ContentSource, type DelimiterStrategy, type DenialOfWalletConfig, type Detection, type DetectionType, type EntropyResult, type ExtractionSchema, type GuardInputOptions, InputScanner, type InputScannerConfig, type LanguageResult, type LanguageSwitch, type PiiHandling, type PresetPolicy, PromptBuilder, type PromptBuilderConfig, type PromptMessage, type QuarantineMetadata, type QuarantineOptions, type Quarantined, type RecoveryConfig, type RecoveryMode, type RiskLevel, Sandbox, type SandboxConfig, type ScanResult, type ScanStrategy, type Sensitivity, StreamMonitor, type StreamMonitorConfig, type StreamViolation, type TrajectoryResult, type UnsafeUnwrapOptions, aegis, analyzeEntropy, detectLanguageSwitches, getPreset, isActionAllowed, isQuarantined, normalizeEncoding, parseWindow, quarantine, resolvePolicy, shannonEntropy, tryDecodeBase64 };
export { type ActionValidationRequest, type ActionValidationResult, ActionValidator, type ActionValidatorConfig, Aegis, type AegisConfig, AegisInputBlocked, type AegisPolicy, AegisSessionQuarantined, AegisSessionTerminated, type AgentLoopConfig, type Alert, type AlertCondition, type AlertRule, type AlertingConfig, AlertingEngine, type AuditEntry, type AuditEventType, type AuditLevel, AuditLog, type AuditLogConfig, type AuditTransport, type BuiltPrompt, type ChainStepOptions, type ChainStepResult, type ChunkStrategy, type ContentSource, type DelimiterStrategy, type DenialOfWalletConfig, type Detection, type DetectionType, type EntropyResult, type ExtractionSchema, FileTransport, type FileTransportConfig, type GuardInputOptions, InputScanner, type InputScannerConfig, type IntegrityResult, type LanguageResult, type LanguageSwitch, type MessageIntegrityConfig, MessageSigner, type OTelCounter, type OTelHistogram, type OTelSpan, OTelTransport, type OTelTransportConfig, type PiiHandling, type PresetPolicy, PromptBuilder, type PromptBuilderConfig, type PromptMessage, type QuarantineMetadata, type QuarantineOptions, type Quarantined, type RecoveryConfig, type RecoveryMode, type RiskLevel, Sandbox, type SandboxConfig, type ScanResult, type ScanStrategy, type Sensitivity, type SignedConversation, type SignedMessage, StreamMonitor, type StreamMonitorConfig, type StreamViolation, type TopicDriftResult, TrajectoryAnalyzer, type TrajectoryResult, type TransportFn, type UnsafeUnwrapOptions, aegis, analyzeEntropy, detectLanguageSwitches, getPreset, isActionAllowed, isQuarantined, normalizeEncoding, parseWindow, quarantine, resolvePolicy, shannonEntropy, tryDecodeBase64 };
+1
-1
{
"name": "@aegis-sdk/core",
"version": "0.2.0",
"version": "0.3.0",
"description": "Streaming-first prompt injection defense for AI applications",

@@ -5,0 +5,0 @@ "license": "MIT",

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display