Skip to main content

Prerequisites

  • A Grantex account (free tier or above)
  • At least one registered agent
  • Your API key (GRANTEX_API_KEY)

Step 1: Verify Built-in Rules Are Active

Anomaly detection is enabled by default for all accounts. Verify the built-in rules are active:
import { Grantex } from '@grantex/sdk';

const grantex = new Grantex({ apiKey: process.env.GRANTEX_API_KEY });

const rules = await grantex.anomalies.listRules();
console.log(`${rules.length} rules loaded`);

for (const rule of rules) {
  console.log(`${rule.ruleId}: ${rule.enabled ? 'enabled' : 'disabled'} (${rule.severity})`);
}
You should see 10 built-in rules. All are enabled by default. To disable a rule you do not need:
curl -X PATCH https://api.grantex.dev/v1/anomalies/rules/off_hours_activity \
  -H "Authorization: Bearer $GRANTEX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"enabled": false}'

Step 2: Configure a Slack Channel

Create a Slack incoming webhook, then register it as a notification channel:
await grantex.anomalies.createChannel({
  type: 'slack',
  name: 'slack-security',
  config: {
    webhookUrl: 'https://hooks.slack.com/services/T00000/B00000/xxxxxxxx',
  },
  severities: ['critical', 'high'],
});
The severities array filters which alerts reach this channel. Only critical and high alerts will post to Slack in the example above.

Other Channel Types

TypeRequired Config
slackwebhookUrl
pagerdutyroutingKey
datadogapiKey, site (e.g., datadoghq.com)
emailto (email address), from (optional)
webhookurl, secret (for HMAC verification)

Step 3: Create a Custom Rule

Built-in rules cover common patterns. Create custom rules for your specific needs:
await grantex.anomalies.createRule({
  ruleId: 'billing_agent_write_surge',
  name: 'Billing Agent Write Surge',
  description: 'Billing agent writing more than 20 invoices in 10 minutes',
  severity: 'high',
  condition: {
    agentIds: ['ag_billing_01'],
    scopes: ['invoices:write'],
    timeWindow: '10m',
    threshold: 20,
  },
  channels: ['slack-security', 'pagerduty-oncall'],
});

Condition Parameters

ParameterTypeDescription
agentIdsstring[]Only monitor these agents. Omit to monitor all.
scopesstring[]Trigger when these scopes are accessed. Omit for any scope.
timeWindowstringSliding window. Options: 5m, 15m, 1h, 6h, 24h.
thresholdnumberEvent count in the window that triggers the alert.

Step 4: Stream Events in Real Time

For automated responses, connect to the SSE event stream:
import { Grantex } from '@grantex/sdk';

const grantex = new Grantex({ apiKey: process.env.GRANTEX_API_KEY });

// Stream anomaly events
for await (const event of grantex.events.stream({
  types: ['anomaly.detected'],
})) {
  const { alertId, ruleName, severity, agentId, context } = event.data;
  console.log(`[${severity}] ${ruleName} — agent: ${agentId}`);

  // Auto-revoke on critical alerts
  if (severity === 'critical' && context.grantId) {
    await grantex.grants.revoke(context.grantId);
    await grantex.anomalies.resolveAlert(alertId, 'Auto-revoked by SSE handler');
  }
}
Or with curl:
curl -N -H "Authorization: Bearer $GRANTEX_API_KEY" \
  "https://api.grantex.dev/v1/events/stream?types=anomaly.detected"

Step 5: Monitor via Dashboard

Open the developer portal at /dashboard/anomalies to see:
  1. Severity overview — Color-coded counts of open alerts by severity
  2. Activity chart — 14-day bar chart showing alert volume trends
  3. Alert list — Filter by status (open / acknowledged / resolved) and severity
  4. Rule builder — View, create, and toggle rules at /dashboard/anomalies/rules
Click any alert to see its full detail view: context data, timeline, and resolution note field.

Troubleshooting

No alerts are firing

  1. Check that rules are enabledGET /v1/anomalies/rules and verify enabled: true
  2. Check that agents are active — Anomaly detection only monitors active agents
  3. Check the time window — Rules only fire when the threshold is exceeded within the configured window
  4. Verify grant activity — At least some authorization events must occur for rules to evaluate

Slack notifications not arriving

  1. Verify the webhook URL — Test it with a manual curl POST
  2. Check channel severities — The alert severity must match the channel’s severities filter
  3. Check channel statusGET /v1/anomalies/channels and verify enabled: true

Too many false positives

  1. Increase thresholds — Raise the threshold value for noisy rules
  2. Narrow scope filters — Add agentIds or scopes to limit which events the rule evaluates
  3. Disable low-value rules — Toggle off rules like off_hours_activity if your agents intentionally run 24/7

Custom rule not creating

  1. Rule ID must be unique — Check it does not conflict with a built-in rule ID
  2. Valid time window — Must be one of 5m, 15m, 1h, 6h, 24h
  3. Threshold must be positive — Must be an integer >= 1